package com.competition.modules.leai.controller;

import com.competition.common.exception.BusinessException;
import com.competition.common.result.Result;
import com.competition.common.util.SecurityUtil;
import com.competition.modules.leai.config.LeaiConfig;
import com.competition.modules.leai.dto.LeaiAuthRedirectDTO;
import com.competition.modules.leai.service.LeaiApiClient;
import com.competition.modules.leai.vo.LeaiTokenVO;
import com.competition.modules.sys.entity.SysUser;
import com.competition.modules.sys.service.ISysUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 乐读派认证入口控制器
 * 前端 iframe 模式的主入口
 */
@Slf4j
@Tag(name = "乐读派认证")
@RestController
@RequestMapping("/leai-auth")
@RequiredArgsConstructor
public class LeaiAuthController {

    private final LeaiApiClient leaiApiClient;
    private final LeaiConfig leaiConfig;
    private final ISysUserService sysUserService;

    /**
     * 前端 iframe 主入口：返回 token 信息 JSON
     * 需要登录认证
     */
    @GetMapping("/token")
    @Operation(summary = "获取乐读派创作 Token")
    public Result<LeaiTokenVO> getToken() {
        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, "用户未绑定手机号，无法使用创作功能");
        }

        try {
            String token = leaiApiClient.exchangeToken(phone);

            // Entity → VO 转换（Controller 层负责）
            // 注意: orgId 对应本项目的租户 code（tenant_code）
            LeaiTokenVO vo = new LeaiTokenVO();
            vo.setToken(token);
            vo.setOrgId(leaiConfig.getOrgId()); // 即租户 tenant_code
            vo.setH5Url(leaiConfig.getH5Url());
            vo.setPhone(phone);

            log.info("[乐读派] 获取创作Token成功, userId={}, phone={}", userId, phone);
            return Result.success(vo);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("[乐读派] 获取创作Token失败, userId={}", userId, e);
            throw new BusinessException(500, "获取创作Token失败: " + e.getMessage());
        }
    }

    /**
     * 跳转模式备选：换 token + 302 重定向到 H5
     * 需要登录认证
     */
    @GetMapping
    @Operation(summary = "重定向到乐读派 H5 创作页")
    public void authRedirect(LeaiAuthRedirectDTO dto, HttpServletResponse response) throws IOException {
        Long userId = SecurityUtil.getCurrentUserId();
        SysUser user = sysUserService.getById(userId);
        if (user == null || user.getPhone() == null || user.getPhone().isEmpty()) {
            response.sendError(401, "请先登录并绑定手机号");
            return;
        }

        String phone = user.getPhone();
        try {
            String token = leaiApiClient.exchangeToken(phone);

            StringBuilder url = new StringBuilder(leaiConfig.getH5Url())
                    .append("/?token=").append(URLEncoder.encode(token, StandardCharsets.UTF_8))
                    .append("&orgId=").append(URLEncoder.encode(leaiConfig.getOrgId(), StandardCharsets.UTF_8))
                    .append("&phone=").append(URLEncoder.encode(phone, StandardCharsets.UTF_8));

            if (dto.getReturnPath() != null && !dto.getReturnPath().isEmpty()) {
                url.append("&returnPath=").append(URLEncoder.encode(dto.getReturnPath(), StandardCharsets.UTF_8));
            }

            log.info("[乐读派] 重定向到H5, userId={}, phone={}", userId, phone);
            response.sendRedirect(url.toString());

        } catch (Exception e) {
            log.error("[乐读派] 重定向失败, userId={}", userId, e);
            response.sendError(500, "跳转乐读派失败: " + e.getMessage());
        }
    }

    /**
     * iframe 内 Token 刷新接口
     * 前端 JS 在收到 TOKEN_EXPIRED postMessage 时调用此接口
     */
    @GetMapping("/refresh-token")
    @Operation(summary = "刷新乐读派 Token")
    public Result<LeaiTokenVO> refreshToken() {
        Long userId = SecurityUtil.getCurrentUserId();
        SysUser user = sysUserService.getById(userId);
        if (user == null || user.getPhone() == null || user.getPhone().isEmpty()) {
            throw new BusinessException(401, "请先登录并绑定手机号");
        }

        String phone = user.getPhone();
        try {
            String token = leaiApiClient.exchangeToken(phone);

            // Entity → VO 转换（Controller 层负责）
            LeaiTokenVO vo = new LeaiTokenVO();
            vo.setToken(token);
            vo.setOrgId(leaiConfig.getOrgId());
            vo.setPhone(phone);

            log.info("[乐读派] Token刷新成功, userId={}", userId);
            return Result.success(vo);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("[乐读派] Token刷新失败, userId={}", userId, e);
            throw new BusinessException(500, "Token刷新失败: " + e.getMessage());
        }
    }
}
