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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jeesharp.business.modules.setting.entity.CfgClientAppVersion;
import com.jeesharp.business.modules.setting.service.ClientAppVersionService;
import com.jeesharp.business.modules.setting.vo.ClientAppVersionReleaseView;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * C 端客户端版本发布应用服务：从库读取发布记录，解析 JSON 并按端筛选。
 *
 * @author jeesharp
 * @since 2026-05-13
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ClientAppVersionApplicationService {

    private final ClientAppVersionService clientAppVersionService;
    private final ObjectMapper objectMapper;

    /**
     * 已发布记录按端过滤后返回（已按 versionCode 降序）。
     *
     * @param platformRaw 原始端标识，如 MINI、mp-weixin
     * @return 视图列表
     */
    public List<ClientAppVersionReleaseView> listPublishedForPlatform(String platformRaw) {
        String platform = normalizePlatform(platformRaw);
        List<CfgClientAppVersion> rows = clientAppVersionService.findPublishedOrderByVersionCodeDesc();
        return rows.stream()
                .filter(r -> matchesPlatform(r.getPlatformsJson(), platform))
                .map(this::toView)
                .collect(Collectors.toList());
    }

    private ClientAppVersionReleaseView toView(CfgClientAppVersion e) {
        ClientAppVersionReleaseView v = new ClientAppVersionReleaseView();
        v.setId(e.getId());
        v.setVersion(e.getVersion());
        v.setVersionCode(e.getVersionCode());
        v.setReleaseTime(e.getReleaseTime());
        v.setVersionType(e.getVersionType());
        v.setUpdateType(e.getUpdateType());
        v.setDownloadUrl(e.getDownloadUrl());
        v.setMinVersion(e.getMinVersion());
        v.setUpdateContent(parseUpdateContent(e.getUpdateContentJson()));
        return v;
    }

    private ClientAppVersionReleaseView.UpdateContentView parseUpdateContent(String json) {
        ClientAppVersionReleaseView.UpdateContentView uc = new ClientAppVersionReleaseView.UpdateContentView();
        if (!StringUtils.hasText(json)) {
            return uc;
        }
        try {
            JsonNode root = objectMapper.readTree(json);
            uc.setFeatures(readStringArray(root, "features"));
            uc.setFixes(readStringArray(root, "fixes"));
            uc.setImprovements(readStringArray(root, "improvements"));
        } catch (Exception ignored) {
            // 非法 JSON 时返回空分组
        }
        return uc;
    }

    private List<String> readStringArray(JsonNode root, String key) {
        JsonNode n = root.get(key);
        if (n == null || !n.isArray()) {
            return new ArrayList<>();
        }
        List<String> out = new ArrayList<>();
        for (JsonNode item : n) {
            if (item != null && !item.isNull()) {
                out.add(item.asText());
            }
        }
        return out;
    }

    private boolean matchesPlatform(String platformsJson, String normalized) {
        if (!StringUtils.hasText(platformsJson)) {
            return true;
        }
        String trimmed = platformsJson.trim();
        if ("[]".equals(trimmed) || "{}".equals(trimmed)) {
            return true;
        }
        try {
            JsonNode arr = objectMapper.readTree(trimmed);
            if (!arr.isArray() || arr.isEmpty()) {
                return true;
            }
            for (JsonNode item : arr) {
                if (item != null && !item.isNull()) {
                    String p = item.asText();
                    if (StringUtils.hasText(p) && normalized.equalsIgnoreCase(p.trim())) {
                        return true;
                    }
                }
            }
        } catch (Exception ignored) {
            return false;
        }
        return false;
    }

    /**
     * 与移动端网关 {@code AppVersionMobileService#normalizePlatform} 行为保持一致。
     *
     * @param raw 原始端
     * @return 归一化编码
     */
    public static String normalizePlatform(String raw) {
        if (!StringUtils.hasText(raw)) {
            return "UNKNOWN";
        }
        String s = raw.trim().toUpperCase(Locale.ROOT);
        return switch (s) {
            case "ANDROID" -> "ANDROID";
            case "IOS" -> "IOS";
            case "H5", "WEB", "HTML5" -> "H5";
            case "MINI", "MP-WEIXIN", "MP_WEIXIN", "WECHAT_MINI", "WECHATMINI" -> "MINI";
            case "MP-ALIPAY", "MP_ALIPAY", "ALIPAY" -> "ALIPAY";
            default -> s;
        };
    }
}
