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

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.common.api.BizSceneApi;
import com.jeesharp.business.modules.common.bizscene.support.BizSceneMobileJumpSupport;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneOptionVO;
import com.jeesharp.business.modules.setting.entity.CmsHomeBanner;
import com.jeesharp.business.modules.setting.enums.HomeBannerBizTypeEnum;
import com.jeesharp.business.modules.setting.enums.HomeBannerJumpTypeEnum;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.net.URI;

/**
 * 轮播跳转路径解析：优先 {@code cfg_biz_scene.ext_json.mobile}，回退 {@link HomeBannerBizTypeEnum}。
 *
 * @author jeesharp
 * @since 2026-07-03
 */
@Component
@AllArgsConstructor
public class HomeBannerJumpPathResolver {

    private final BizSceneApi bizSceneApi;

    public String resolveLinkUrl(CmsHomeBanner banner) {
        if (banner == null) {
            return null;
        }
        HomeBannerJumpTypeEnum jump = HomeBannerJumpTypeEnum.fromValue(banner.getJumpType());
        return switch (jump) {
            case BIZ_DETAIL -> resolveDetailPath(banner.getBizType(), banner.getBizId());
            case BIZ_LIST -> resolveListPath(banner.getBizType());
            case CUSTOM_PATH, H5 -> normalizeRawLink(banner.getLinkUrl());
            case NONE -> null;
        };
    }

    public String resolveDetailPath(String bizTypeCode, String bizId) {
        if (StrUtil.isBlank(bizTypeCode) || StrUtil.isBlank(bizId)) {
            return null;
        }
        BizSceneMobileJumpSupport.MobileJump jump = resolveMobileJump(bizTypeCode);
        if (jump != null) {
            return BizSceneMobileJumpSupport.resolveDetailPath(jump, bizId);
        }
        HomeBannerBizTypeEnum biz = HomeBannerBizTypeEnum.fromCode(bizTypeCode);
        if (biz == null || StrUtil.isBlank(biz.getDetailPath())) {
            return null;
        }
        return biz.getDetailPath() + "?" + biz.getDetailIdParam() + "=" + encodeQueryValue(bizId.trim());
    }

    public String resolveListPath(String bizTypeCode) {
        if (StrUtil.isBlank(bizTypeCode)) {
            return null;
        }
        BizSceneMobileJumpSupport.MobileJump jump = resolveMobileJump(bizTypeCode);
        if (jump != null) {
            return BizSceneMobileJumpSupport.resolveListPath(jump);
        }
        HomeBannerBizTypeEnum biz = HomeBannerBizTypeEnum.fromCode(bizTypeCode);
        if (biz == null || StrUtil.isBlank(biz.getListPath())) {
            return null;
        }
        return biz.getListPath();
    }

    /**
     * 业务场景展示名：注册表 sceneName 优先，回退枚举描述。
     */
    public String resolveBizTypeName(String bizTypeCode) {
        if (StrUtil.isBlank(bizTypeCode)) {
            return "";
        }
        BizSceneOptionVO scene = bizSceneApi.getOptionByCode(bizTypeCode.trim(), null);
        if (scene != null && StrUtil.isNotBlank(scene.getSceneName())) {
            return scene.getSceneName();
        }
        String enumName = HomeBannerBizTypeEnum.getDescByCode(bizTypeCode);
        return StrUtil.isNotBlank(enumName) ? enumName : bizTypeCode;
    }

    public boolean isKnownBizType(String bizTypeCode) {
        if (StrUtil.isBlank(bizTypeCode)) {
            return false;
        }
        if (bizSceneApi.getOptionByCode(bizTypeCode.trim(), null) != null) {
            return true;
        }
        return HomeBannerBizTypeEnum.fromCode(bizTypeCode) != null;
    }

    /**
     * 保存前校验并规范化跳转字段。
     */
    public String validateAndNormalize(CmsHomeBanner entity) {
        if (entity == null) {
            throw new IllegalArgumentException("轮播数据不能为空");
        }
        HomeBannerJumpTypeEnum jump = HomeBannerJumpTypeEnum.fromValue(
                entity.getJumpType() == null ? HomeBannerJumpTypeEnum.NONE.getValue() : entity.getJumpType());
        entity.setJumpType(jump.getValue());

        switch (jump) {
            case NONE -> {
                entity.setBizType(null);
                entity.setBizId(null);
                entity.setLinkParamsJson(null);
                entity.setLinkUrl(null);
                return null;
            }
            case BIZ_DETAIL -> {
                if (!isKnownBizType(entity.getBizType())) {
                    throw new IllegalArgumentException("请选择业务场景");
                }
                if (StrUtil.isBlank(entity.getBizId())) {
                    throw new IllegalArgumentException("请选择跳转目标");
                }
                entity.setBizId(entity.getBizId().trim());
                entity.setLinkUrl(null);
                String path = resolveDetailPath(entity.getBizType(), entity.getBizId());
                if (StrUtil.isBlank(path)) {
                    throw new IllegalArgumentException("无法生成业务详情跳转路径");
                }
                entity.setLinkUrl(path);
                return path;
            }
            case BIZ_LIST -> {
                if (!isKnownBizType(entity.getBizType())) {
                    throw new IllegalArgumentException("请选择业务场景");
                }
                entity.setBizId(null);
                entity.setLinkParamsJson(null);
                entity.setLinkUrl(null);
                String path = resolveListPath(entity.getBizType());
                if (StrUtil.isBlank(path)) {
                    throw new IllegalArgumentException("该业务场景不支持列表跳转");
                }
                entity.setLinkUrl(path);
                return path;
            }
            case CUSTOM_PATH -> {
                entity.setBizType(null);
                entity.setBizId(null);
                entity.setLinkParamsJson(null);
                String path = requireMiniPath(entity.getLinkUrl());
                entity.setLinkUrl(path);
                return path;
            }
            case H5 -> {
                entity.setBizType(null);
                entity.setBizId(null);
                entity.setLinkParamsJson(null);
                String url = requireHttpUrl(entity.getLinkUrl());
                entity.setLinkUrl(url);
                return url;
            }
            default -> throw new IllegalArgumentException("跳转类型不合法");
        }
    }

    private BizSceneMobileJumpSupport.MobileJump resolveMobileJump(String bizTypeCode) {
        BizSceneOptionVO scene = bizSceneApi.getOptionByCode(bizTypeCode.trim(), null);
        if (scene == null) {
            return null;
        }
        return BizSceneMobileJumpSupport.parse(scene.getExtJson());
    }

    private static String normalizeRawLink(String raw) {
        if (StrUtil.isBlank(raw)) {
            return null;
        }
        String link = raw.trim();
        if (link.startsWith("http://") || link.startsWith("https://")) {
            return link;
        }
        return link.startsWith("/") ? link : "/" + link;
    }

    private static String requireMiniPath(String raw) {
        String path = normalizeRawLink(raw);
        if (StrUtil.isBlank(path)) {
            throw new IllegalArgumentException("请填写小程序页面路径");
        }
        if (path.startsWith("http://") || path.startsWith("https://")) {
            throw new IllegalArgumentException("自定义路径应为小程序内路径，外链请选择 H5");
        }
        return path;
    }

    private static String requireHttpUrl(String raw) {
        if (StrUtil.isBlank(raw)) {
            throw new IllegalArgumentException("请填写 H5 链接");
        }
        String url = raw.trim();
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            throw new IllegalArgumentException("H5 链接须以 http:// 或 https:// 开头");
        }
        try {
            URI.create(url);
        } catch (IllegalArgumentException ex) {
            throw new IllegalArgumentException("H5 链接格式不正确");
        }
        return url;
    }

    private static String encodeQueryValue(String value) {
        try {
            return java.net.URLEncoder.encode(value, java.nio.charset.StandardCharsets.UTF_8);
        } catch (Exception ex) {
            return value;
        }
    }
}
