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

import com.jeesharp.business.modules.common.api.BizSceneApi;
import com.jeesharp.business.modules.common.bizscene.enums.BizSceneCapabilityEnum;
import com.jeesharp.business.modules.common.bizscene.support.BizSceneMobileJumpSupport;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneOptionVO;
import com.jeesharp.business.modules.common.enums.DisabledEnabledEnum;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.setting.application.support.HomeQuickGridIntroLayoutSupport;
import com.jeesharp.business.modules.setting.convert.HomeQuickGridConvert;
import com.jeesharp.business.modules.setting.dto.HomeQuickGridSaveDTO;
import com.jeesharp.business.modules.setting.entity.CmsHomeQuickGrid;
import com.jeesharp.business.modules.setting.enums.HomeQuickGridIntroJumpTypeEnum;
import com.jeesharp.business.modules.setting.enums.HomeQuickGridIntroListLayoutEnum;

import com.jeesharp.business.modules.setting.enums.SettingPublishStatusEnum;
import com.jeesharp.business.modules.setting.entity.CmsHomeGridIntro;
import com.jeesharp.business.modules.setting.service.HomeGridIntroService;
import com.jeesharp.business.modules.setting.service.HomeQuickGridService;
import com.jeesharp.business.modules.setting.vo.HomeQuickGridListVO;
import com.jeesharp.business.modules.setting.vo.HomeQuickGridNavSceneOptionVO;
import com.jeesharp.business.modules.setting.vo.HomeQuickGridQueryVO;
import com.jeesharp.business.modules.setting.vo.HomeQuickGridVO;
import com.jeesharp.business.modules.setting.vo.MiniHomeQuickNavItemVO;
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.util.ArrayList;
import java.util.List;

/**
 * 小程序首页宫格应用服务：后台 CRUD 与编号唯一校验。
 *
 * @author jeesharp
 * @since 2026-05-15
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class HomeQuickGridApplicationService {

    private static final int SHELL_QUICK_NAV_LIMIT = 8;

    private final HomeQuickGridService homeQuickGridService;
    private final HomeGridIntroService homeGridIntroService;
    private final BizSceneApi bizSceneApi;

    public HomeQuickGridVO get(String id) {
        CmsHomeQuickGrid entity = homeQuickGridService.get(id);
        if (entity == null) {
            return null;
        }
        HomeQuickGridVO vo = HomeQuickGridConvert.INSTANCE.toInfoVO(entity);
        fillStatusName(vo);
        fillIntroJumpTypeName(vo);
        fillIntroListLayoutName(vo);
        return vo;
    }

    public PageRespVO<HomeQuickGridListVO> findPage(Page<CmsHomeQuickGrid> page, HomeQuickGridQueryVO query) {
        Page<CmsHomeQuickGrid> result = homeQuickGridService.findPage(page, query);
        PageRespVO<HomeQuickGridListVO> pageResp = HomeQuickGridConvert.INSTANCE.toPageRespVO(result);
        if (pageResp.getRecords() != null) {
            pageResp.getRecords().forEach(vo -> {
                fillStatusName(vo);
                fillIntroJumpTypeName(vo);
                fillIntroListLayoutName(vo);
            });
        }
        return pageResp;
    }

    @Transactional(readOnly = false)
    public void save(HomeQuickGridSaveDTO dto) {
        CmsHomeQuickGrid entity = HomeQuickGridConvert.INSTANCE.toEntity(dto);
        String code = StrUtil.trimToEmpty(entity.getNavCode());
        if (StrUtil.isBlank(code)) {
            throw new IllegalArgumentException("业务编号不能为空");
        }
        entity.setNavCode(code);
        applyRegistryNavLinkPath(entity);
        String title = StrUtil.trimToEmpty(entity.getTitle());
        if (StrUtil.isBlank(title)) {
            throw new IllegalArgumentException("名称不能为空");
        }
        entity.setTitle(title);
        String link = StrUtil.trimToEmpty(entity.getLinkPath());
        if (StrUtil.isBlank(link)) {
            throw new IllegalArgumentException("跳转路径不能为空");
        }
        if (!link.startsWith("/")) {
            throw new IllegalArgumentException("小程序路径须以 / 开头");
        }
        entity.setLinkPath(link);
        if (entity.getStatus() == null) {
            entity.setStatus(DisabledEnabledEnum.ENABLED.getValue());
        } else if (DisabledEnabledEnum.fromValue(entity.getStatus()) == null) {
            throw new IllegalArgumentException("状态取值不合法");
        }
        if (entity.getSortOrder() == null) {
            entity.setSortOrder(0);
        }
        resolveIntroListLayoutFields(entity, dto);
        resolveIntroJumpFields(entity, dto);
        String excludeId = StrUtil.isBlank(dto.getId()) ? null : dto.getId().trim();
        if (homeQuickGridService.countByNavCodeExcludeId(entity.getNavCode(), excludeId) > 0L) {
            throw new IllegalArgumentException("业务编号已存在");
        }
        if (StrUtil.isBlank(dto.getId())) {
            homeQuickGridService.save(entity);
            return;
        }
        homeQuickGridService.update(entity);
    }

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

    /**
     * 壳层拉取：启用宫格至多 8 条（按排序），转为 C 端 VO。
     */
    public List<MiniHomeQuickNavItemVO> listQuickNavVoForShell() {
        List<CmsHomeQuickGrid> rows = homeQuickGridService.listEnabledForShell(SHELL_QUICK_NAV_LIMIT);
        List<MiniHomeQuickNavItemVO> out = new ArrayList<>();
        for (CmsHomeQuickGrid e : rows) {
            MiniHomeQuickNavItemVO vo = new MiniHomeQuickNavItemVO();
            vo.setId(e.getId());
            vo.setNavCode(e.getNavCode());
            vo.setLabel(e.getTitle());
            vo.setIconUrl(StrUtil.nullToEmpty(e.getIconUrl()));
            vo.setLinkUrl(StrUtil.nullToEmpty(e.getLinkPath()));
            Integer jump = e.getIntroJumpType() == null ? HomeQuickGridIntroJumpTypeEnum.LIST.getValue() : e.getIntroJumpType();
            vo.setIntroJumpType(jump);
            vo.setIntroDetailLinkPath(StrUtil.nullToEmpty(e.getIntroDetailLinkPath()));
            vo.setIntroDetailArticleId(StrUtil.nullToEmpty(e.getIntroDetailArticleId()));
            vo.setIntroListLayout(HomeQuickGridIntroLayoutSupport.resolveListLayout(e));
            out.add(vo);
        }
        return out;
    }

    /**
     * 宫格可选业态（注册表能力 NAV，且配置了 mobile.listPath）。
     */
    public List<HomeQuickGridNavSceneOptionVO> listNavBizSceneOptions() {
        List<HomeQuickGridNavSceneOptionVO> out = new ArrayList<>();
        for (BizSceneOptionVO scene : bizSceneApi.listEnabledOptions(BizSceneCapabilityEnum.NAV, null)) {
            HomeQuickGridNavSceneOptionVO vo = toNavSceneOption(scene);
            if (vo != null && StrUtil.isNotBlank(vo.getListPath())) {
                out.add(vo);
            }
        }
        return out;
    }

    /**
     * 当 navCode 与注册表 scene_code 一致时，从 ext_json.mobile.listPath 补全跳转路径。
     */
    private void applyRegistryNavLinkPath(CmsHomeQuickGrid entity) {
        if (entity == null || StrUtil.isBlank(entity.getNavCode())) {
            return;
        }
        BizSceneOptionVO scene = bizSceneApi.getOptionByCode(entity.getNavCode().trim(), null);
        if (scene == null || !hasNavCapability(scene)) {
            return;
        }
        BizSceneMobileJumpSupport.MobileJump jump = BizSceneMobileJumpSupport.parse(scene.getExtJson());
        String listPath = BizSceneMobileJumpSupport.resolveListPath(jump);
        if (StrUtil.isBlank(listPath)) {
            return;
        }
        if (StrUtil.isBlank(entity.getLinkPath())) {
            entity.setLinkPath(listPath);
        }
    }

    private static HomeQuickGridNavSceneOptionVO toNavSceneOption(BizSceneOptionVO scene) {
        if (scene == null || StrUtil.isBlank(scene.getSceneCode())) {
            return null;
        }
        BizSceneMobileJumpSupport.MobileJump jump = BizSceneMobileJumpSupport.parse(scene.getExtJson());
        HomeQuickGridNavSceneOptionVO vo = new HomeQuickGridNavSceneOptionVO();
        vo.setSceneCode(scene.getSceneCode());
        vo.setSceneName(scene.getSceneName());
        vo.setListPath(BizSceneMobileJumpSupport.resolveListPath(jump));
        return vo;
    }

    private static boolean hasNavCapability(BizSceneOptionVO scene) {
        if (scene == null || StrUtil.isBlank(scene.getCapabilities())) {
            return false;
        }
        for (String part : scene.getCapabilities().split(",")) {
            if (BizSceneCapabilityEnum.NAV.equalsIgnoreCase(part.trim())) {
                return true;
            }
        }
        return false;
    }

    private void fillStatusName(HomeQuickGridVO vo) {
        if (vo == null) {
            return;
        }
        vo.setStatusName(DisabledEnabledEnum.getDescByValue(vo.getStatus()));
    }

    private void fillStatusName(HomeQuickGridListVO vo) {
        if (vo == null) {
            return;
        }
        vo.setStatusName(DisabledEnabledEnum.getDescByValue(vo.getStatus()));
        fillIntroJumpTypeName(vo);
    }

    private void fillIntroJumpTypeName(HomeQuickGridVO vo) {
        if (vo == null) {
            return;
        }
        vo.setIntroJumpTypeName(HomeQuickGridIntroJumpTypeEnum.getDescByValue(vo.getIntroJumpType()));
    }

    private void fillIntroJumpTypeName(HomeQuickGridListVO vo) {
        if (vo == null) {
            return;
        }
        vo.setIntroJumpTypeName(HomeQuickGridIntroJumpTypeEnum.getDescByValue(vo.getIntroJumpType()));
    }

    private void fillIntroListLayoutName(HomeQuickGridVO vo) {
        if (vo == null) {
            return;
        }
        if (vo.getIntroListLayout() == null) {
            vo.setIntroListLayout(HomeQuickGridIntroListLayoutEnum.CARD.getValue());
        }
        vo.setIntroListLayoutName(HomeQuickGridIntroListLayoutEnum.getDescByValue(vo.getIntroListLayout()));
    }

    private void fillIntroListLayoutName(HomeQuickGridListVO vo) {
        if (vo == null) {
            return;
        }
        if (vo.getIntroListLayout() == null) {
            vo.setIntroListLayout(HomeQuickGridIntroListLayoutEnum.CARD.getValue());
        }
        vo.setIntroListLayoutName(HomeQuickGridIntroListLayoutEnum.getDescByValue(vo.getIntroListLayout()));
    }

    private void resolveIntroListLayoutFields(CmsHomeQuickGrid entity, HomeQuickGridSaveDTO dto) {
        Integer layoutVal = dto.getIntroListLayout() == null
                ? HomeQuickGridIntroListLayoutEnum.CARD.getValue()
                : dto.getIntroListLayout();
        HomeQuickGridIntroListLayoutEnum layout = HomeQuickGridIntroListLayoutEnum.fromValue(layoutVal);
        if (layout == null) {
            throw new IllegalArgumentException("介绍列表布局取值不合法");
        }
        entity.setIntroListLayout(layout.getValue());
        String bannerRaw = dto.getIntroBannerJson();
        if (StrUtil.isBlank(bannerRaw)) {
            entity.setIntroBannerJson("[]");
        } else {
            entity.setIntroBannerJson(HomeQuickGridIntroLayoutSupport.normalizeBannerJson(bannerRaw));
        }
        String tabRaw = dto.getIntroTabLabels();
        if (StrUtil.isBlank(tabRaw)) {
            entity.setIntroTabLabels("[]");
        } else {
            entity.setIntroTabLabels(HomeQuickGridIntroLayoutSupport.normalizeTabLabelsJson(tabRaw));
        }
    }

    /**
     * 校验并规范化介绍跳转字段；详情模式要求宫格已存在主键以便绑定文章。
     */
    private void resolveIntroJumpFields(CmsHomeQuickGrid entity, HomeQuickGridSaveDTO dto) {
        Integer jumpVal = dto.getIntroJumpType() == null ? HomeQuickGridIntroJumpTypeEnum.LIST.getValue() : dto.getIntroJumpType();
        HomeQuickGridIntroJumpTypeEnum jump = HomeQuickGridIntroJumpTypeEnum.fromValue(jumpVal);
        if (jump == null) {
            throw new IllegalArgumentException("介绍跳转类型不合法");
        }
        entity.setIntroJumpType(jump.getValue());
        if (HomeQuickGridIntroJumpTypeEnum.LIST.equals(jump)) {
            entity.setIntroDetailLinkPath(null);
            entity.setIntroDetailArticleId(null);
            return;
        }
        if (StrUtil.isBlank(dto.getId())) {
            throw new IllegalArgumentException("新增宫格请先用「介绍列表」保存后，再维护介绍文章并改为「介绍详情」");
        }
        String detailPath = StrUtil.trimToEmpty(dto.getIntroDetailLinkPath());
        if (StrUtil.isBlank(detailPath)) {
            throw new IllegalArgumentException("详情模式须填写详情页路径");
        }
        if (!detailPath.startsWith("/")) {
            throw new IllegalArgumentException("详情页路径须以 / 开头");
        }
        entity.setIntroDetailLinkPath(detailPath);
        String articleId = StrUtil.trimToEmpty(dto.getIntroDetailArticleId());
        if (StrUtil.isBlank(articleId)) {
            throw new IllegalArgumentException("详情模式须绑定介绍文章主键");
        }
        CmsHomeGridIntro article = homeGridIntroService.get(articleId);
        if (article == null) {
            throw new IllegalArgumentException("绑定的介绍文章不存在");
        }
        if (!dto.getId().trim().equals(article.getQuickGridId())) {
            throw new IllegalArgumentException("介绍文章不属于当前宫格，请检查 quick_grid_id 或重新选择文章");
        }
        if (!SettingPublishStatusEnum.PUBLISHED.getValue().equals(article.getStatus())) {
            throw new IllegalArgumentException("详情直达仅允许绑定「已发布」的介绍文章");
        }
        entity.setIntroDetailArticleId(articleId);
    }
}
