package com.jeesharp.business.modules.setting.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.setting.convert.AppSplashAdConvert;
import com.jeesharp.business.modules.setting.dto.AppSplashAdSaveDTO;
import com.jeesharp.business.modules.setting.entity.AppSplashAd;
import com.jeesharp.business.modules.setting.enums.SplashMediaTypeEnum;
import com.jeesharp.business.modules.setting.service.AppSplashAdService;
import com.jeesharp.business.modules.setting.vo.AppSplashAdListVO;
import com.jeesharp.business.modules.setting.vo.AppSplashAdQueryVO;
import com.jeesharp.business.modules.setting.vo.AppSplashAdVO;
import com.jeesharp.business.modules.setting.vo.SplashAdClientBundleVO;
import com.jeesharp.business.modules.setting.vo.SplashAdSlideClientVO;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Comparator;

/**
 * 开屏广告应用服务：后台 CRUD 与 C 端整包。
 *
 * @author jeesharp
 * @since 2026-04-21
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class AppSplashAdApplicationService {

    private final AppSplashAdService appSplashAdService;

    public AppSplashAdVO get(String id) {
        return AppSplashAdConvert.INSTANCE.toInfoVO(appSplashAdService.get(id));
    }

    public PageRespVO<AppSplashAdListVO> findPage(Page<AppSplashAd> page, AppSplashAdQueryVO query) {
        Page<AppSplashAd> result = appSplashAdService.findPage(page, query);
        return AppSplashAdConvert.INSTANCE.toPageRespVO(result);
    }

    @Transactional(readOnly = false)
    public void save(AppSplashAdSaveDTO dto) {
        if (SplashMediaTypeEnum.fromValue(dto.getMediaType()) == null) {
            throw new IllegalArgumentException("媒体类型不合法");
        }
        AppSplashAd entity = AppSplashAdConvert.INSTANCE.toEntity(dto);
        if (StrUtil.isBlank(dto.getId())) {
            appSplashAdService.createSplashAd(entity);
            return;
        }
        appSplashAdService.updateSplashAd(entity);
    }

    @Transactional(readOnly = false)
    public void delete(String ids) {
        appSplashAdService.batchDelete(StrUtil.splitTrim(ids, ','));
    }

    /**
     * C 端免登录拉取开屏整包。
     */
    public SplashAdClientBundleVO getClientBundle(String platform) {
        SplashAdClientBundleVO out = new SplashAdClientBundleVO();
        out.setSlides(new ArrayList<>());
        List<AppSplashAd> rows = appSplashAdService.listActiveForClient(platform);
        if (rows.isEmpty()) {
            out.setEnabled(false);
            out.setConfigVersion("0");
            out.setDurationSec(5);
            out.setSkippable(true);
            return out;
        }
        AppSplashAd first = rows.get(0);
        out.setEnabled(true);
        out.setDurationSec(Objects.requireNonNullElse(first.getDurationSec(), 5));
        out.setSkippable(Objects.equals(first.getSkippable(), 1));
        out.setConfigVersion(computeConfigVersion(rows));
        List<SplashAdSlideClientVO> slides = new ArrayList<>();
        for (AppSplashAd r : rows) {
            slides.add(toSlideClient(r));
        }
        out.setSlides(slides);
        return out;
    }

    private static String computeConfigVersion(List<AppSplashAd> rows) {
        return String.valueOf(
                rows.stream()
                        .map(AppSplashAd::getUpdateDate)
                        .filter(Objects::nonNull)
                        .max(Comparator.naturalOrder())
                        .orElseGet(() -> rows.get(0).getCreateDate() != null
                                ? rows.get(0).getCreateDate()
                                : java.time.LocalDateTime.now())
                        .atZone(ZoneId.systemDefault())
                        .toInstant()
                        .toEpochMilli());
    }

    private static SplashAdSlideClientVO toSlideClient(AppSplashAd r) {
        SplashAdSlideClientVO s = new SplashAdSlideClientVO();
        s.setId(r.getId());
        SplashMediaTypeEnum t = SplashMediaTypeEnum.fromValue(r.getMediaType());
        s.setMediaType(t == SplashMediaTypeEnum.VIDEO ? "video" : "image");
        s.setMediaUrl(r.getMediaUrl());
        s.setPosterUrl(r.getPosterUrl());
        s.setTitle(r.getTitle());
        s.setSubtitle(r.getSubtitle());
        s.setLinkUrl(r.getLinkUrl());
        return s;
    }
}
