package com.lesingle.modules.leai.controller;

import com.lesingle.common.exception.BusinessException;
import com.lesingle.common.util.SecurityUtil;
import com.lesingle.modules.leai.config.LeaiConfig;
import com.lesingle.modules.leai.service.ILeaiSyncService;
import com.lesingle.modules.leai.service.LeaiApiClient;
import com.lesingle.modules.leai.util.LeaiUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.lesingle.modules.sys.entity.SysUser;
import com.lesingle.modules.sys.service.ISysUserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * 乐读派代理控制器
 * 前端所有乐读派请求经由本控制器代理转发，前端不持有 phone/orgId/appSecret
 * 后端自动注入 orgId + phone，使用 HMAC 签名与乐读派通信
 */
@Slf4j
@Tag(name = "乐读派代理")
@RestController
@RequestMapping("/leai-proxy")
@RequiredArgsConstructor
public class LeaiProxyController {

    private final LeaiApiClient leaiApiClient;
    private final LeaiConfig leaiConfig;
    private final ISysUserService sysUserService;
    private final ObjectMapper objectMapper;
    private final ILeaiSyncService leaiSyncService;

    /**
     * 获取当前用户手机号，校验非空
     */
    private String getPhoneOrThrow() {
        Long userId = SecurityUtil.getCurrentUserId();
        SysUser user = sysUserService.getById(userId);
        if (user == null) {
            throw new BusinessException(404, "用户不存在");
        }
        String phone = user.getPhone();
        if (phone == null || phone.isEmpty()) {
            throw new BusinessException(400, "用户未绑定手机号，无法使用创作功能");
        }
        return phone;
    }

    /**
     * 构建带 orgId + phone 的基础 body
     */
    private Map<String, Object> buildBaseBody() {
        Map<String, Object> body = new HashMap<>();
        body.put("orgId", leaiConfig.getOrgId());
        body.put("phone", getPhoneOrThrow());
        return body;
    }

    /**
     * 将乐读派原始 JSON 响应以 application/json 返回给前端
     * （String 返回类型默认 Content-Type 为 text/plain，需手动设为 JSON）
     */
    private ResponseEntity<String> jsonOk(String body) {
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(body);
    }

    // ═══════════════════════════════════════════════════════════
    // 代理接口
    // ═══════════════════════════════════════════════════════════

    /**
     * 图片上传
     * POST /leai-proxy/upload → 乐读派 /api/v1/creation/upload
     */
    @PostMapping("/upload")
    @Operation(summary = "图片上传代理")
    public ResponseEntity<String> proxyUpload(@RequestParam("file") MultipartFile file) {
        log.info("[乐读派代理] 图片上传, fileName={}, size={}", file.getOriginalFilename(), file.getSize());
        return jsonOk(leaiApiClient.proxyUpload("/creation/upload", file));
    }

    /**
     * 角色提取
     * POST /leai-proxy/extract → 乐读派 /api/v1/creation/extract-original
     */
    @PostMapping("/extract")
    @Operation(summary = "角色提取代理")
    public ResponseEntity<String> proxyExtract(@RequestBody Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        body.putAll(requestBody);
        log.info("[乐读派代理] 角色提取, imageUrl={}", requestBody.get("imageUrl"));
        return jsonOk(leaiApiClient.proxyPost("/creation/extract-original", body));
    }

    /**
     * 故事创作
     * POST /leai-proxy/create-story → 乐读派 /api/v1/creation/image-story
     */
    @PostMapping("/create-story")
    @Operation(summary = "故事创作代理")
    public ResponseEntity<String> proxyCreateStory(@RequestBody Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        body.putAll(requestBody);
        // 默认关闭自动配音
        body.putIfAbsent("enableVoice", false);
        log.info("[乐读派代理] 故事创作, imageUrl={}", requestBody.get("imageUrl"));
        return jsonOk(leaiApiClient.proxyPost("/creation/image-story", body));
    }

    /**
     * 查询作品详情
     * GET /leai-proxy/work/{id} → 乐读派 /api/v1/query/work/{id}
     */
    @GetMapping("/work/{id}")
    @Operation(summary = "查询作品详情代理")
    public ResponseEntity<String> proxyGetWork(@PathVariable String id) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgId", leaiConfig.getOrgId());
        params.put("phone", getPhoneOrThrow());
        log.info("[乐读派代理] 查询作品详情, workId={}", id);
        return jsonOk(leaiApiClient.proxyGet("/query/work/" + id, params));
    }

    /**
     * 额度校验
     * POST /leai-proxy/validate → 乐读派 /api/v1/query/validate
     */
    @PostMapping("/validate")
    @Operation(summary = "额度校验代理")
    public ResponseEntity<String> proxyValidate(@RequestBody(required = false) Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        if (requestBody != null) {
            body.putAll(requestBody);
        }
        body.putIfAbsent("apiType", "A3");
        log.info("[乐读派代理] 额度校验");
        return jsonOk(leaiApiClient.proxyPost("/query/validate", body));
    }

    /**
     * 编辑作品
     * PUT /leai-proxy/work/{id} → 乐读派 /api/v1/update/work/{id}
     */
    @PutMapping("/work/{id}")
    @Operation(summary = "编辑作品代理")
    public ResponseEntity<String> proxyUpdateWork(@PathVariable String id, @RequestBody Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        body.putAll(requestBody);
        log.info("[乐读派代理] 编辑作品, workId={}", id);
        String responseBody = leaiApiClient.proxyPut("/update/work/" + id, body);
        syncLocalAfterLeaiUpdate(id, responseBody);
        return jsonOk(responseBody);
    }

    /**
     * 解析乐读派 update 响应并同步本地 t_ugc_work，避免仅依赖 Webhook 导致发布前状态滞后
     */
    private void syncLocalAfterLeaiUpdate(String remoteWorkId, String responseJson) {
        if (responseJson == null || responseJson.isEmpty()) {
            return;
        }
        try {
            Map<String, Object> root = objectMapper.readValue(responseJson, new TypeReference<Map<String, Object>>() {});
            if (root.containsKey("code")) {
                int code = LeaiUtil.toInt(root.get("code"), 200);
                if (code != 200) {
                    log.debug("[乐读派代理] update 响应非成功，跳过本地同步: code={}", code);
                    return;
                }
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> data = (Map<String, Object>) root.get("data");
            if (data == null) {
                data = root;
            }
            if (data.get("status") == null) {
                data = leaiApiClient.fetchWorkDetail(remoteWorkId);
                if (data == null) {
                    return;
                }
            }
            leaiSyncService.syncWork(remoteWorkId, data, "Proxy[update.work]");
        } catch (Exception e) {
            log.warn("[乐读派代理] 编辑作品后同步本地失败: remoteWorkId={}", remoteWorkId, e);
        }
    }

    /**
     * 批量更新配音
     * POST /leai-proxy/batch-audio → 乐读派 /api/v1/update/batch-audio
     */
    @PostMapping("/batch-audio")
    @Operation(summary = "批量更新配音代理")
    public ResponseEntity<String> proxyBatchAudio(@RequestBody Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        body.putAll(requestBody);
        log.info("[乐读派代理] 批量更新配音, workId={}", requestBody.get("workId"));
        return jsonOk(leaiApiClient.proxyPost("/update/batch-audio", body));
    }

    /**
     * AI 配音
     * POST /leai-proxy/voice → 乐读派 /api/v1/creation/voice
     */
    @PostMapping("/voice")
    @Operation(summary = "AI配音代理")
    public ResponseEntity<String> proxyVoice(@RequestBody Map<String, Object> requestBody) {
        Map<String, Object> body = buildBaseBody();
        body.putAll(requestBody);
        log.info("[乐读派代理] AI配音");
        return jsonOk(leaiApiClient.proxyPost("/creation/voice", body));
    }

    /**
     * STS 临时凭证
     * POST /leai-proxy/sts-token → 乐读派 /api/v1/oss/sts-token
     */
    @PostMapping("/sts-token")
    @Operation(summary = "STS临时凭证代理")
    public ResponseEntity<String> proxyStsToken() {
        Map<String, Object> body = buildBaseBody();
        log.info("[乐读派代理] 获取STS凭证");
        return jsonOk(leaiApiClient.proxyPost("/oss/sts-token", body));
    }
}
