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.vo.BizSceneOptionVO;
import com.jeesharp.business.modules.common.enums.DisabledEnabledEnum;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.business.modules.setting.application.support.HomeBannerJumpBizQuerySupport;
import com.jeesharp.business.modules.setting.application.support.HomeBannerJumpPathResolver;
import com.jeesharp.business.modules.setting.convert.HomeBannerConvert;
import com.jeesharp.business.modules.setting.dto.HomeBannerSaveDTO;
import com.jeesharp.business.modules.setting.entity.CmsHomeBanner;
import com.jeesharp.business.modules.setting.enums.HomeBannerJumpTypeEnum;
import com.jeesharp.business.modules.setting.enums.HomeBannerPlatformEnum;
import com.jeesharp.business.modules.setting.enums.HomeBannerPositionEnum;

import com.jeesharp.business.modules.setting.service.HomeBannerService;
import com.jeesharp.business.modules.setting.vo.HomeBannerJumpBizOptionVO;
import com.jeesharp.business.modules.setting.vo.HomeBannerListVO;
import com.jeesharp.business.modules.setting.vo.HomeBannerQueryVO;
import com.jeesharp.business.modules.setting.vo.HomeBannerVO;
import com.jeesharp.business.modules.setting.vo.MiniHomeBannerItemVO;
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-08
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class HomeBannerApplicationService {

    private final HomeBannerService homeBannerService;
    private final HomeBannerJumpBizQuerySupport homeBannerJumpBizQuerySupport;
    private final BizSceneApi bizSceneApi;
    private final HomeBannerJumpPathResolver homeBannerJumpPathResolver;

    public HomeBannerVO get(String id) {
        CmsHomeBanner entity = homeBannerService.get(id);
        if (entity == null) {
            return null;
        }
        HomeBannerVO vo = HomeBannerConvert.INSTANCE.toInfoVO(entity);
        fillDisplayNames(vo);
        vo.setResolvedLinkUrl(homeBannerJumpPathResolver.resolveLinkUrl(entity));
        return vo;
    }

    public PageRespVO<HomeBannerListVO> findPage(Page<CmsHomeBanner> page, HomeBannerQueryVO query) {
        Page<CmsHomeBanner> result = homeBannerService.findPage(page, query);
        PageRespVO<HomeBannerListVO> pageResp = HomeBannerConvert.INSTANCE.toPageRespVO(result);
        if (pageResp.getRecords() != null) {
            pageResp.getRecords().forEach(this::fillDisplayNames);
        }
        return pageResp;
    }

    public List<HomeBannerJumpBizOptionVO> listJumpBizOptions(String bizType, String keyword) {
        return homeBannerJumpBizQuerySupport.listOptions(bizType, keyword);
    }

    /**
     * 轮播业务场景下拉（来自 {@code cfg_biz_scene}，能力标签 BANNER）。
     */
    public List<BizSceneOptionVO> listBizSceneOptions() {
        return bizSceneApi.listEnabledOptions(BizSceneCapabilityEnum.BANNER, null);
    }

    @Transactional(readOnly = false)
    public void create(HomeBannerSaveDTO dto) {
        if (StrUtil.isNotBlank(dto.getId())) {
            throw new BizErrorException("新增请求不应携带主键 id");
        }
        CmsHomeBanner entity = prepareAndValidateBanner(HomeBannerConvert.INSTANCE.toEntity(dto));
        homeBannerService.createHomeBanner(entity);
    }

    @Transactional(readOnly = false)
    public void update(HomeBannerSaveDTO dto) {
        if (StrUtil.isBlank(dto.getId())) {
            throw new BizErrorException("更新请求必须携带主键 id");
        }
        CmsHomeBanner entity = prepareAndValidateBanner(HomeBannerConvert.INSTANCE.toEntity(dto));
        homeBannerService.updateHomeBanner(entity);
    }

    private CmsHomeBanner prepareAndValidateBanner(CmsHomeBanner entity) {
        if (entity.getStatus() == null) {
            entity.setStatus(DisabledEnabledEnum.ENABLED.getValue());
        }
        if (entity.getSortOrder() == null) {
            entity.setSortOrder(0);
        }
        if (StrUtil.isBlank(entity.getPlatform())) {
            entity.setPlatform(HomeBannerPlatformEnum.WECHAT_MINI.getValue());
        } else if (HomeBannerPlatformEnum.fromValue(entity.getPlatform()) == null) {
            throw new IllegalArgumentException("展示端不合法");
        }
        if (StrUtil.isBlank(entity.getBannerPosition())) {
            entity.setBannerPosition(HomeBannerPositionEnum.HOME.getValue());
        } else if (HomeBannerPositionEnum.fromValue(entity.getBannerPosition()) == null) {
            throw new IllegalArgumentException("展示位置不合法，可选：HOME（首页）、MALL（商城）、FOOD（美食餐饮）");
        }
        homeBannerJumpPathResolver.validateAndNormalize(entity);
        if (StrUtil.isNotBlank(entity.getBizType())
                && (HomeBannerJumpTypeEnum.BIZ_DETAIL.getValue().equals(entity.getJumpType())
                || HomeBannerJumpTypeEnum.BIZ_LIST.getValue().equals(entity.getJumpType()))) {
            bizSceneApi.assertSceneEnabled(entity.getBizType(), entity.getTenantId());
        }
        if (HomeBannerJumpTypeEnum.BIZ_DETAIL.getValue().equals(entity.getJumpType())) {
            homeBannerJumpBizQuerySupport.assertBizTargetExists(entity.getBizType(), entity.getBizId());
        }
        return entity;
    }

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

    /**
     * 小程序轮播统一入口：按 position 返回启用中的轮播项。
     * <p>合法 position：HOME（首页）、MALL（商城）、FOOD（美食餐饮）；缺省 HOME。
     * 原 {@code GET /mall/banners} 已合并至此接口。</p>
     *
     * @param position 展示位置编码，空则按首页；合法值见 {@link HomeBannerPositionEnum}
     */
    public List<MiniHomeBannerItemVO> listMiniBannersByPosition(String position) {
        String code = StrUtil.isBlank(position) ? HomeBannerPositionEnum.HOME.getValue() : position.trim();
        HomeBannerPositionEnum pos = HomeBannerPositionEnum.fromValue(code);
        if (pos == null) {
            throw new IllegalArgumentException("位置不合法，可选：HOME（首页）、MALL（商城）、FOOD（美食餐饮）");
        }
        List<CmsHomeBanner> rows = homeBannerService.listEnabledForPortal(
            HomeBannerPlatformEnum.WECHAT_MINI.getValue(), pos.getValue());
        List<MiniHomeBannerItemVO> out = new ArrayList<>();
        for (CmsHomeBanner b : rows) {
            if (b.getImageUrl() == null || b.getImageUrl().isBlank()) {
                continue;
            }
            out.add(toMiniItem(b));
        }
        return out;
    }

    /**
     * 小程序首页轮播（兼容旧调用）：等同 {@code listMiniBannersByPosition(HOME)}。
     */
    public List<MiniHomeBannerItemVO> listMiniHomeBannersForMini() {
        return listMiniBannersByPosition(HomeBannerPositionEnum.HOME.getValue());
    }

    public MiniHomeBannerItemVO toMiniItem(CmsHomeBanner b) {
        MiniHomeBannerItemVO it = new MiniHomeBannerItemVO();
        it.setId(b.getId());
        it.setTitle(b.getTitle());
        it.setImageUrl(b.getImageUrl());
        it.setJumpType(b.getJumpType());
        it.setBizType(b.getBizType());
        it.setBizId(b.getBizId());
        String resolved = homeBannerJumpPathResolver.resolveLinkUrl(b);
        if (StrUtil.isBlank(resolved)) {
            resolved = StrUtil.nullToEmpty(b.getLinkUrl()).trim();
        }
        it.setLinkUrl(StrUtil.isBlank(resolved) ? null : resolved);
        return it;
    }

    private void fillDisplayNames(HomeBannerVO vo) {
        if (vo == null) {
            return;
        }
        vo.setStatusName(DisabledEnabledEnum.getDescByValue(vo.getStatus()));
        vo.setPlatformName(HomeBannerPlatformEnum.getDescByValue(vo.getPlatform()));
        vo.setBannerPositionName(HomeBannerPositionEnum.getDescByValue(vo.getBannerPosition()));
        vo.setJumpTypeName(HomeBannerJumpTypeEnum.getDescByValue(vo.getJumpType()));
        vo.setBizTypeName(homeBannerJumpPathResolver.resolveBizTypeName(vo.getBizType()));
        if (HomeBannerJumpTypeEnum.BIZ_DETAIL.getValue().equals(vo.getJumpType())
                && StrUtil.isNotBlank(vo.getBizType()) && StrUtil.isNotBlank(vo.getBizId())) {
            vo.setBizTargetName(homeBannerJumpBizQuerySupport.resolveBizTargetLabel(vo.getBizType(), vo.getBizId()));
        }
    }

    private void fillDisplayNames(HomeBannerListVO vo) {
        if (vo == null) {
            return;
        }
        vo.setStatusName(DisabledEnabledEnum.getDescByValue(vo.getStatus()));
        vo.setPlatformName(HomeBannerPlatformEnum.getDescByValue(vo.getPlatform()));
        vo.setBannerPositionName(HomeBannerPositionEnum.getDescByValue(vo.getBannerPosition()));
        vo.setJumpTypeName(HomeBannerJumpTypeEnum.getDescByValue(vo.getJumpType()));
        vo.setBizTypeName(homeBannerJumpPathResolver.resolveBizTypeName(vo.getBizType()));
        if (HomeBannerJumpTypeEnum.BIZ_DETAIL.getValue().equals(vo.getJumpType())
                && StrUtil.isNotBlank(vo.getBizType()) && StrUtil.isNotBlank(vo.getBizId())) {
            vo.setBizTargetName(homeBannerJumpBizQuerySupport.resolveBizTargetLabel(vo.getBizType(), vo.getBizId()));
        }
    }
}
