package com.competition.modules.leai.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.competition.modules.leai.util.LeaiUtil;
import com.competition.modules.ugc.entity.UgcWork;
import com.competition.modules.ugc.entity.UgcWorkPage;
import com.competition.modules.ugc.mapper.UgcWorkMapper;
import com.competition.modules.ugc.mapper.UgcWorkPageMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * V4.0 状态同步核心服务
 * Webhook 和 B3 对账共用此服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LeaiSyncService implements ILeaiSyncService {

    private final UgcWorkMapper ugcWorkMapper;
    private final UgcWorkPageMapper ugcWorkPageMapper;
    private final LeaiApiClient leaiApiClient;

    /**
     * V4.0 核心同步逻辑
     * <p>
     * 同步规则：
     * - remoteStatus == -1  → 强制更新（FAILED）
     * - remoteStatus == 2   → 强制更新（PROCESSING 进度变化）
     * - remoteStatus > localStatus → 全量更新（状态前进）
     * - else                → 忽略
     *
     * @param remoteWorkId 乐读派作品ID
     * @param remoteData   远程作品数据（来自 Webhook payload 或 B2/B3 查询结果）
     * @param source       来源标识（用于日志，如 "Webhook[work.status_changed]"）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncWork(String remoteWorkId, Map<String, Object> remoteData, String source) {
        int remoteStatus = LeaiUtil.toInt(remoteData.get("status"), 0);
        String phone = LeaiUtil.toString(remoteData.get("phone"), null);

        // 查找本地作品（通过 remoteWorkId）
        UgcWork localWork = findByRemoteWorkId(remoteWorkId);

        if (localWork == null) {
            // ★ 新作品：首次收到此 remoteWorkId，创建本地记录
            insertNewWork(remoteWorkId, remoteData, phone);
            log.info("[{}] 新增作品 remoteWorkId={}, status={}, phone={}", source, remoteWorkId, remoteStatus, phone);
            return;
        }

        int localStatus = localWork.getStatus() != null ? localWork.getStatus() : 0;

        if (remoteStatus == LeaiApiClient.STATUS_FAILED) {
            // ★ FAILED(-1): 创作失败，强制更新
            updateFailed(localWork, remoteData);
            log.info("[{}] 强制更新(FAILED) remoteWorkId={}", source, remoteWorkId);
            return;
        }

        if (remoteStatus == LeaiApiClient.STATUS_PROCESSING) {
            // ★ PROCESSING(2): 创作进行中，强制更新进度
            updateProcessing(localWork, remoteData);
            log.info("[{}] 强制更新(PROCESSING) remoteWorkId={}, progress={}",
                    source, remoteWorkId, remoteData.get("progress"));
            return;
        }

        if (remoteStatus > localStatus) {
            // ★ 状态前进: 全量更新
            // status=3(COMPLETED): pageList 包含图片 URL
            // status=4(CATALOGED): title/author 已更新
            // status=5(DUBBED): pageList 中 audioUrl 已填充
            updateStatusForward(localWork, remoteData, remoteStatus);
            log.info("[{}] 状态更新 remoteWorkId={}: {} -> {}", source, remoteWorkId, localStatus, remoteStatus);
            return;
        }

        // 旧数据或重复推送，忽略
        log.debug("[{}] 跳过 remoteWorkId={}, remote={} <= local={}", source, remoteWorkId, remoteStatus, localStatus);
    }

    /**
     * 新增作品记录
     */
    private void insertNewWork(String remoteWorkId, Map<String, Object> remoteData, String phone) {
        UgcWork work = new UgcWork();
        work.setRemoteWorkId(remoteWorkId);
        work.setTitle(LeaiUtil.toString(remoteData.get("title"), "未命名作品"));
        work.setStatus(LeaiUtil.toInt(remoteData.get("status"), LeaiApiClient.STATUS_PENDING));
        work.setVisibility("private");
        work.setIsDeleted(0);
        work.setIsRecommended(false);
        work.setViewCount(0);
        work.setLikeCount(0);
        work.setFavoriteCount(0);
        work.setCommentCount(0);
        work.setShareCount(0);
        work.setProgress(LeaiUtil.toInt(remoteData.get("progress"), 0));
        work.setProgressMessage(LeaiUtil.toString(remoteData.get("progressMessage"), null));
        work.setStyle(LeaiUtil.toString(remoteData.get("style"), null));
        work.setAuthorName(LeaiUtil.toString(remoteData.get("author"), null));
        work.setFailReason(LeaiUtil.toString(remoteData.get("failReason"), null));
        work.setCreateTime(LocalDateTime.now());
        work.setModifyTime(LocalDateTime.now());

        // 设置封面图
        Object coverUrl = remoteData.get("coverUrl");
        if (coverUrl == null) coverUrl = remoteData.get("cover_url");
        if (coverUrl != null) work.setCoverUrl(coverUrl.toString());

        // 设置原始图片
        Object originalImageUrl = remoteData.get("originalImageUrl");
        if (originalImageUrl == null) originalImageUrl = remoteData.get("original_image_url");
        if (originalImageUrl != null) work.setOriginalImageUrl(originalImageUrl.toString());

        // 通过手机号查找用户ID（多租户场景）
        if (phone != null && work.getUserId() == null) {
            Long userId = findUserIdByPhone(phone);
            if (userId != null) {
                work.setUserId(userId);
            }
        }

        ugcWorkMapper.insert(work);

        // 如果有 pageList 且 status >= 3，保存页面数据
        if (work.getStatus() != null && work.getStatus() >= LeaiApiClient.STATUS_COMPLETED) {
            savePageList(work.getId(), remoteData.get("pageList"));
        }
    }

    /**
     * 更新失败状态
     */
    private void updateFailed(UgcWork work, Map<String, Object> remoteData) {
        LambdaUpdateWrapper<UgcWork> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UgcWork::getId, work.getId())
               .set(UgcWork::getStatus, LeaiApiClient.STATUS_FAILED)
               .set(UgcWork::getFailReason, LeaiUtil.toString(remoteData.get("failReason"), "未知错误"))
               .set(UgcWork::getModifyTime, LocalDateTime.now());
        ugcWorkMapper.update(null, wrapper);
    }

    /**
     * 更新处理中状态（进度变化）
     */
    private void updateProcessing(UgcWork work, Map<String, Object> remoteData) {
        LambdaUpdateWrapper<UgcWork> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UgcWork::getId, work.getId())
               .set(UgcWork::getStatus, LeaiApiClient.STATUS_PROCESSING);

        if (remoteData.containsKey("progress")) {
            wrapper.set(UgcWork::getProgress, LeaiUtil.toInt(remoteData.get("progress"), 0));
        }
        if (remoteData.containsKey("progressMessage")) {
            wrapper.set(UgcWork::getProgressMessage, LeaiUtil.toString(remoteData.get("progressMessage"), null));
        }
        wrapper.set(UgcWork::getModifyTime, LocalDateTime.now());

        ugcWorkMapper.update(null, wrapper);
    }

    /**
     * 状态前进：全量更新
     */
    private void updateStatusForward(UgcWork work, Map<String, Object> remoteData, int remoteStatus) {
        // CAS 乐观锁：确保并发安全，只有当前 status < remoteStatus 时才更新
        LambdaUpdateWrapper<UgcWork> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UgcWork::getId, work.getId())
               .lt(UgcWork::getStatus, remoteStatus)
               .set(UgcWork::getStatus, remoteStatus);

        // 更新可变字段
        if (remoteData.containsKey("title")) {
            wrapper.set(UgcWork::getTitle, LeaiUtil.toString(remoteData.get("title"), null));
        }
        if (remoteData.containsKey("progress")) {
            wrapper.set(UgcWork::getProgress, LeaiUtil.toInt(remoteData.get("progress"), 0));
        }
        if (remoteData.containsKey("progressMessage")) {
            wrapper.set(UgcWork::getProgressMessage, LeaiUtil.toString(remoteData.get("progressMessage"), null));
        }
        if (remoteData.containsKey("style")) {
            wrapper.set(UgcWork::getStyle, LeaiUtil.toString(remoteData.get("style"), null));
        }
        if (remoteData.containsKey("author")) {
            wrapper.set(UgcWork::getAuthorName, LeaiUtil.toString(remoteData.get("author"), null));
        }
        if (remoteData.containsKey("failReason")) {
            wrapper.set(UgcWork::getFailReason, LeaiUtil.toString(remoteData.get("failReason"), null));
        }
        Object coverUrl = remoteData.get("coverUrl");
        if (coverUrl == null) coverUrl = remoteData.get("cover_url");
        if (coverUrl != null) {
            wrapper.set(UgcWork::getCoverUrl, coverUrl.toString());
        }

        wrapper.set(UgcWork::getModifyTime, LocalDateTime.now());

        int updated = ugcWorkMapper.update(null, wrapper);
        if (updated == 0) {
            log.warn("CAS乐观锁冲突，跳过更新: remoteWorkId={}, remoteStatus={}", work.getRemoteWorkId(), remoteStatus);
            return;
        }

        // status >= 3 时保存 pageList
        if (remoteStatus >= LeaiApiClient.STATUS_COMPLETED) {
            savePageList(work.getId(), remoteData.get("pageList"));
        }
    }

    /**
     * 保存作品页面数据
     * status=3(COMPLETED): pageList 包含 imageUrl
     * status=5(DUBBED): pageList 中 audioUrl 已填充
     */
    @SuppressWarnings("unchecked")
    private void savePageList(Long workId, Object pageListObj) {
        if (pageListObj == null) return;

        List<Map<String, Object>> pageList;
        if (pageListObj instanceof List) {
            pageList = (List<Map<String, Object>>) pageListObj;
        } else {
            return;
        }

        if (pageList.isEmpty()) return;

        // 先删除旧页面数据
        LambdaQueryWrapper<UgcWorkPage> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(UgcWorkPage::getWorkId, workId);
        ugcWorkPageMapper.delete(deleteWrapper);

        // 插入新页面数据
        for (int i = 0; i < pageList.size(); i++) {
            Map<String, Object> pageData = pageList.get(i);
            UgcWorkPage page = new UgcWorkPage();
            page.setWorkId(workId);
            page.setPageNo(i + 1);
            page.setImageUrl(LeaiUtil.toString(pageData.get("imageUrl"), null));
            page.setText(LeaiUtil.toString(pageData.get("text"), null));
            page.setAudioUrl(LeaiUtil.toString(pageData.get("audioUrl"), null));
            ugcWorkPageMapper.insert(page);
        }

        log.info("[乐读派] 保存作品页面数据: workId={}, 页数={}", workId, pageList.size());
    }

    /**
     * 通过 remoteWorkId 查找本地作品
     */
    private UgcWork findByRemoteWorkId(String remoteWorkId) {
        LambdaQueryWrapper<UgcWork> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UgcWork::getRemoteWorkId, remoteWorkId)
               .eq(UgcWork::getIsDeleted, 0);
        return ugcWorkMapper.selectOne(wrapper);
    }

    /**
     * 通过手机号查找用户ID
     * 多租户场景：需要确定租户后查找
     */
    private Long findUserIdByPhone(String phone) {
        // TODO: 如果需要按租户隔离，需要传入 orgId 查找租户再查找用户
        // 当前简化处理：直接通过手机号查用户
        return null; // 暂时不自动关联用户，后续通过 phone + orgId 查询
    }
}
