package com.fs.feishu.service;

import cn.hutool.json.JSONUtil;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.course.config.CourseConfig;
import com.fs.course.domain.FsCourseLink;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.mapper.FsCourseLinkMapper;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.feishu.model.FeishuLinkParam;
import com.fs.system.service.ISysConfigService;
import com.lark.oapi.Client;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 飞书业务编排层：
 * 负责课程链接和注册链接的完整业务流程，包括缓存、URL 构建、调用底层 API 服务等。
 */
@Component
@Slf4j
public class FeiShuService {

    @Autowired
    private ISysConfigService configService;
    @Autowired
    private FsUserCourseVideoMapper videoMapper;
    @Autowired
    private FsCourseLinkMapper courseLinkMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private FeishuClientPool clientPool;
    @Autowired
    private FeishuDocApiService docApiService;

    /**
     * 001 生成飞书初始链接（注册授权链接）
     * 每次 shortCode 唯一
     */
    public String getFeishuRegisterLink(Long videoId, Long companyId, Long courseId,
                                        Long companyUserId, String shortLink) {
        // 检查功能开关
        CourseConfig config = getCourseConfig();
        if (!Boolean.TRUE.equals(config.getEnableFeishuNewLink())) {
            throw new CustomException("未开启飞书看课");
        }

        FsUserCourseVideo userCourseVideo = videoMapper.selectFsUserCourseVideoByVideoId(videoId);
        if (userCourseVideo == null) {
            throw new CustomException("视频不存在: " + videoId);
        }

        int maxRetries = clientPool.getAvailableCount();
        for (int i = 0; i < maxRetries; i++) {
            Client client = clientPool.getClient();
            try {
                String documentId = docApiService.createDocument(client, userCourseVideo.getTitle() + "-注册");
                String authUrl = buildAuthLink(companyId, companyUserId, courseId, videoId, shortLink);
                docApiService.createTextLinkBlock(client, documentId, authUrl);
                docApiService.changeDocumentPermissions(client, documentId);
                return "https://www.feishu.cn/docx/" + documentId;
            } catch (CustomException e) {
                // 如果是账号禁用异常，继续尝试下一个账号
                if (e.getMessage().contains("不可用") || e.getMessage().contains("已被自动禁用")) {
                    log.warn("账号不可用，尝试下一个");
                    continue;
                }
                throw e;
            } catch (Exception e) {
                throw new CustomException("创建飞书注册链接失败: " + e.getMessage(), e);
            }
        }
        throw new CustomException("所有飞书账号均不可用，请联系管理员");
    }

    /**
     * 002 生成飞书课程链接
     * 相同参数可能重复，使用 Redis 缓存避免重复创建文档
     */
    public String getFeishuCourseNewLink(FeishuLinkParam param) {
        if (param == null || param.getCompanyUserId() == null || param.getCompanyId() == null) {
            throw new CustomException("参数不能为空");
        }

        String cacheKey = String.format("feishu:course_link:%d:%d:%d:%d:%d:%s",
                param.getCompanyId(), param.getCompanyUserId(),
                param.getCourseId(), param.getVideoId(),
                param.getUserId(), param.getLink());

        // 缓存命中直接返回
        String cached = redisCache.getCacheObject(cacheKey);
        if (StringUtils.isNotBlank(cached)) {
            return cached;
        }

        FsUserCourseVideo userCourseVideo = videoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
        if (userCourseVideo == null) {
            throw new CustomException("视频不存在: " + param.getVideoId());
        }

        int maxRetries = clientPool.getAvailableCount();
        for (int i = 0; i < maxRetries; i++) {
            Client client = clientPool.getClient();
            try {
                String documentId = docApiService.createDocument(client, userCourseVideo.getTitle());
                String url = buildCourseNewLink(param.getCompanyId(), param.getCompanyUserId(),
                        param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink());
                docApiService.createIframeBlock(client, documentId, url);
                docApiService.changeDocumentPermissions(client, documentId);

                String resultUrl = "https://www.feishu.cn/docx/" + documentId;
                redisCache.setCacheObject(cacheKey, resultUrl, 24, TimeUnit.HOURS);
                return resultUrl;
            } catch (CustomException e) {
                if (e.getMessage().contains("不可用") || e.getMessage().contains("已被自动禁用")) {
                    log.warn("账号不可用，尝试下一个");
                    continue;
                }
                throw e;
            } catch (Exception e) {
                throw new CustomException("创建飞书课程链接失败: " + e.getMessage(), e);
            }
        }
        throw new CustomException("所有飞书账号均不可用，请联系管理员");
    }

    // ==================== URL 构建（纯业务逻辑，无外部调用） ====================

    private String buildCourseNewLink(Long companyId, Long companyUserId, Long courseId,
                                      Long videoId, Long userId, String link) {
        CourseConfig config = getCourseConfig();

        Map<String, Object> courseParam = new LinkedHashMap<>();
        courseParam.put("companyUserId", companyUserId);
        courseParam.put("videoId", videoId);
        courseParam.put("companyId", companyId);
        courseParam.put("courseId", courseId);
        courseParam.put("link", link);

        FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(link);
        if (fsCourseLink == null) {
            throw new CustomException("课程链接已过期");
        }
        courseParam.put("corpId", fsCourseLink.getCorpId());
        courseParam.put("linkType", fsCourseLink.getLinkType());
        courseParam.put("qwExternalId", fsCourseLink.getQwExternalId());
        courseParam.put("qwUserId", fsCourseLink.getQwUserId());

        try {
            String encodedJson = URLEncoder.encode(JSONUtil.toJsonStr(courseParam), "UTF-8");
            String fullUrl = config.getFeishuCourseDomain() +
                    "/feishuCourse/pages_course/video?course=" + encodedJson + "&userId=" + userId;
            return URLEncoder.encode(fullUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new CustomException("看课URL拼接失败", e);
        }
    }

    private String buildAuthLink(Long companyId, Long companyUserId, Long courseId,
                                 Long videoId, String shortLink) {
        CourseConfig config = getCourseConfig();

        Map<String, Object> authParam = new LinkedHashMap<>();
        authParam.put("companyUserId", companyUserId);
        authParam.put("videoId", videoId);
        authParam.put("companyId", companyId);
        authParam.put("courseId", courseId);
        authParam.put("link", shortLink);

        try {
            String encodedJson = URLEncoder.encode(JSONUtil.toJsonStr(authParam), "UTF-8");
            String fullUrl = config.getFeishuAuthDomain() +
                    "/feishuCourse/pages/wxauth?course=" + encodedJson;
            return URLEncoder.encode(fullUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new CustomException("授权URL拼接失败", e);
        }
    }

    /**
     * 读取课程配置并检查非空
     */
    private CourseConfig getCourseConfig() {
        String json = configService.selectConfigByKey("course.config");
        if (StringUtils.isBlank(json)) {
            throw new CustomException("飞书看课配置为空");
        }
        return JSONUtil.toBean(json, CourseConfig.class);
    }
}