package com.ruoyi.web.controller.jarvis;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.jarvis.domain.dto.WPS365TokenInfo;
import com.ruoyi.jarvis.service.IWPS365ApiService;
import com.ruoyi.jarvis.service.IWPS365OAuthService;
import com.ruoyi.jarvis.service.impl.WPS365OAuthServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * WPS365控制器
 *
 * @author system
 */
@RestController
@RequestMapping("/jarvis/wps365")
public class WPS365Controller extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(WPS365Controller.class);

    @Autowired
    private IWPS365OAuthService wps365OAuthService;

    @Autowired
    private IWPS365ApiService wps365ApiService;

    @Autowired
    private WPS365OAuthServiceImpl wps365OAuthServiceImpl;

    @Autowired
    private RedisCache redisCache;

    /**
     * 获取授权URL
     */
    @GetMapping("/authUrl")
    public AjaxResult getAuthUrl(@RequestParam(required = false) String state) {
        try {
            String authUrl = wps365OAuthService.getAuthUrl(state);
            return AjaxResult.success("获取授权URL成功", authUrl);
        } catch (Exception e) {
            log.error("获取授权URL失败", e);
            return AjaxResult.error("获取授权URL失败: " + e.getMessage());
        }
    }

    /**
     * OAuth回调处理（已废弃，请使用 /wps365-callback）
     * 保留此接口用于兼容，实际回调请使用 WPS365CallbackController
     */
    @Anonymous
    @GetMapping("/oauth/callback")
    public AjaxResult oauthCallback(@RequestParam String code, 
                                    @RequestParam(required = false) String state) {
        try {
            log.warn("使用已废弃的回调接口 /jarvis/wps365/oauth/callback，建议使用 /wps365-callback");
            log.info("收到OAuth回调 - code: {}, state: {}", code, state);
            
            // 通过授权码获取访问令牌
            WPS365TokenInfo tokenInfo = wps365OAuthService.getAccessTokenByCode(code);
            
            // 保存Token到Redis（使用userId作为key）
            if (tokenInfo.getUserId() != null) {
                wps365OAuthService.saveToken(tokenInfo.getUserId(), tokenInfo);
            }
            
            return AjaxResult.success("授权成功", tokenInfo);
        } catch (Exception e) {
            log.error("OAuth回调处理失败", e);
            return AjaxResult.error("授权失败: " + e.getMessage());
        }
    }

    /**
     * 刷新访问令牌
     */
    @PostMapping("/refreshToken")
    public AjaxResult refreshToken(@RequestBody Map<String, Object> params) {
        try {
            String refreshToken = (String) params.get("refreshToken");
            if (refreshToken == null || refreshToken.trim().isEmpty()) {
                return AjaxResult.error("refreshToken不能为空");
            }

            WPS365TokenInfo tokenInfo = wps365OAuthService.refreshAccessToken(refreshToken);
            
            // 更新Token到Redis
            if (tokenInfo.getUserId() != null) {
                wps365OAuthService.saveToken(tokenInfo.getUserId(), tokenInfo);
            }
            
            return AjaxResult.success("刷新令牌成功", tokenInfo);
        } catch (Exception e) {
            log.error("刷新访问令牌失败", e);
            return AjaxResult.error("刷新令牌失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前用户的Token状态
     */
    @GetMapping("/tokenStatus")
    public AjaxResult getTokenStatus(@RequestParam(required = false) String userId) {
        try {
            WPS365TokenInfo tokenInfo = null;
            
            // 如果提供了userId，查询指定用户的token
            if (userId != null && !userId.trim().isEmpty()) {
                tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            } else {
                // 如果没有提供userId，尝试查找所有token（通常只有一个）
                // 这里使用getCurrentToken方法，它会尝试查找可用的token
                tokenInfo = wps365OAuthService.getCurrentToken();
            }
            
            if (tokenInfo == null) {
                JSONObject result = new JSONObject();
                result.put("hasToken", false);
                result.put("isValid", false);
                return AjaxResult.success("未授权", result);
            }

            boolean isValid = wps365OAuthService.isTokenValid(tokenInfo);
            JSONObject result = new JSONObject();
            result.put("hasToken", true);
            result.put("isValid", isValid);
            result.put("userId", tokenInfo.getUserId());
            result.put("expired", tokenInfo.isExpired());
            if (tokenInfo.getExpiresIn() != null) {
                result.put("expiresIn", tokenInfo.getExpiresIn());
            }

            return AjaxResult.success("获取Token状态成功", result);
        } catch (Exception e) {
            log.error("获取Token状态失败", e);
            return AjaxResult.error("获取Token状态失败: " + e.getMessage());
        }
    }

    /**
     * 手动设置Token（用于测试或手动授权）
     */
    @PostMapping("/setToken")
    public AjaxResult setToken(@RequestBody Map<String, Object> params) {
        try {
            String accessToken = (String) params.get("accessToken");
            String refreshToken = (String) params.get("refreshToken");
            String userId = (String) params.get("userId");
            Integer expiresIn = params.get("expiresIn") != null ? 
                Integer.valueOf(params.get("expiresIn").toString()) : 7200;

            if (accessToken == null || accessToken.trim().isEmpty()) {
                return AjaxResult.error("accessToken不能为空");
            }
            if (userId == null || userId.trim().isEmpty()) {
                return AjaxResult.error("userId不能为空");
            }

            WPS365TokenInfo tokenInfo = new WPS365TokenInfo();
            tokenInfo.setAccessToken(accessToken);
            tokenInfo.setRefreshToken(refreshToken);
            tokenInfo.setExpiresIn(expiresIn);
            tokenInfo.setUserId(userId);

            wps365OAuthService.saveToken(userId, tokenInfo);
            
            return AjaxResult.success("设置Token成功");
        } catch (Exception e) {
            log.error("设置Token失败", e);
            return AjaxResult.error("设置Token失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/userInfo")
    public AjaxResult getUserInfo(@RequestParam String userId) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效，如果过期则尝试刷新
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject userInfo = wps365ApiService.getUserInfo(tokenInfo.getAccessToken());
            return AjaxResult.success("获取用户信息成功", userInfo);
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return AjaxResult.error("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件列表
     */
    @GetMapping("/files")
    public AjaxResult getFileList(@RequestParam String userId,
                                   @RequestParam(required = false, defaultValue = "1") Integer page,
                                   @RequestParam(required = false, defaultValue = "20") Integer pageSize) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效，如果过期则尝试刷新
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            Map<String, Object> params = new java.util.HashMap<>();
            params.put("page", page);
            params.put("page_size", pageSize);

            JSONObject fileList = wps365ApiService.getFileList(tokenInfo.getAccessToken(), params);
            return AjaxResult.success("获取文件列表成功", fileList);
        } catch (Exception e) {
            log.error("获取文件列表失败", e);
            return AjaxResult.error("获取文件列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件信息
     */
    @GetMapping("/fileInfo")
    public AjaxResult getFileInfo(@RequestParam String userId,
                                   @RequestParam String fileToken) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject fileInfo = wps365ApiService.getFileInfo(tokenInfo.getAccessToken(), fileToken);
            return AjaxResult.success("获取文件信息成功", fileInfo);
        } catch (Exception e) {
            log.error("获取文件信息失败 - fileToken: {}", fileToken, e);
            return AjaxResult.error("获取文件信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取工作表列表
     */
    @GetMapping("/sheets")
    public AjaxResult getSheetList(@RequestParam String userId,
                                    @RequestParam String fileToken) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject sheetList = wps365ApiService.getSheetList(tokenInfo.getAccessToken(), fileToken);
            return AjaxResult.success("获取工作表列表成功", sheetList);
        } catch (Exception e) {
            log.error("获取工作表列表失败 - fileToken: {}", fileToken, e);
            return AjaxResult.error("获取工作表列表失败: " + e.getMessage());
        }
    }

    /**
     * 读取单元格数据
     */
    @GetMapping("/readCells")
    public AjaxResult readCells(@RequestParam String userId,
                                @RequestParam String fileToken,
                                @RequestParam(defaultValue = "0") int sheetIdx,
                                @RequestParam(required = false) String range) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.readCells(tokenInfo.getAccessToken(), fileToken, sheetIdx, range);
            return AjaxResult.success("读取单元格数据成功", result);
        } catch (Exception e) {
            log.error("读取单元格数据失败 - fileToken: {}, sheetIdx: {}, range: {}", fileToken, sheetIdx, range, e);
            return AjaxResult.error("读取单元格数据失败: " + e.getMessage());
        }
    }

    /**
     * 更新单元格数据
     */
    @PostMapping("/updateCells")
    public AjaxResult updateCells(@RequestBody Map<String, Object> params) {
        try {
            String userId = (String) params.get("userId");
            String fileToken = (String) params.get("fileToken");
            Integer sheetIdx = params.get("sheetIdx") != null ? 
                Integer.valueOf(params.get("sheetIdx").toString()) : 0;
            String range = (String) params.get("range");
            @SuppressWarnings("unchecked")
            List<List<Object>> values = (List<List<Object>>) params.get("values");

            if (userId == null || userId.trim().isEmpty()) {
                return AjaxResult.error("userId不能为空");
            }
            if (fileToken == null || fileToken.trim().isEmpty()) {
                return AjaxResult.error("fileToken不能为空");
            }
            if (range == null || range.trim().isEmpty()) {
                return AjaxResult.error("range不能为空");
            }
            if (values == null || values.isEmpty()) {
                return AjaxResult.error("values不能为空");
            }

            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.updateCells(
                tokenInfo.getAccessToken(), 
                fileToken, 
                sheetIdx, 
                range, 
                values
            );
            return AjaxResult.success("更新单元格数据成功", result);
        } catch (Exception e) {
            log.error("更新单元格数据失败", e);
            return AjaxResult.error("更新单元格数据失败: " + e.getMessage());
        }
    }

    /**
     * 创建数据表
     */
    @PostMapping("/createSheet")
    public AjaxResult createSheet(@RequestBody Map<String, Object> params) {
        try {
            String userId = (String) params.get("userId");
            String fileToken = (String) params.get("fileToken");
            String sheetName = (String) params.get("sheetName");

            if (userId == null || userId.trim().isEmpty()) {
                return AjaxResult.error("userId不能为空");
            }
            if (fileToken == null || fileToken.trim().isEmpty()) {
                return AjaxResult.error("fileToken不能为空");
            }
            if (sheetName == null || sheetName.trim().isEmpty()) {
                return AjaxResult.error("sheetName不能为空");
            }

            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.createSheet(tokenInfo.getAccessToken(), fileToken, sheetName);
            return AjaxResult.success("创建数据表成功", result);
        } catch (Exception e) {
            log.error("创建数据表失败", e);
            return AjaxResult.error("创建数据表失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新单元格数据
     */
    @PostMapping("/batchUpdateCells")
    public AjaxResult batchUpdateCells(@RequestBody Map<String, Object> params) {
        try {
            String userId = (String) params.get("userId");
            String fileToken = (String) params.get("fileToken");
            Integer sheetIdx = params.get("sheetIdx") != null ? 
                Integer.valueOf(params.get("sheetIdx").toString()) : 0;
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> updates = (List<Map<String, Object>>) params.get("updates");

            if (userId == null || userId.trim().isEmpty()) {
                return AjaxResult.error("userId不能为空");
            }
            if (fileToken == null || fileToken.trim().isEmpty()) {
                return AjaxResult.error("fileToken不能为空");
            }
            if (updates == null || updates.isEmpty()) {
                return AjaxResult.error("updates不能为空");
            }

            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.batchUpdateCells(
                tokenInfo.getAccessToken(), 
                fileToken, 
                sheetIdx, 
                updates
            );
            return AjaxResult.success("批量更新单元格数据成功", result);
        } catch (Exception e) {
            log.error("批量更新单元格数据失败", e);
            return AjaxResult.error("批量更新单元格数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 读取AirSheet工作表数据
     */
    @GetMapping("/readAirSheetCells")
    public AjaxResult readAirSheetCells(@RequestParam String userId,
                                        @RequestParam String worksheetId,
                                        @RequestParam(required = false) String range) {
        try {
            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.readAirSheetCells(tokenInfo.getAccessToken(), worksheetId, range);
            return AjaxResult.success("读取AirSheet数据成功", result);
        } catch (Exception e) {
            log.error("读取AirSheet数据失败 - worksheetId: {}, range: {}", worksheetId, range, e);
            return AjaxResult.error("读取AirSheet数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新AirSheet工作表数据
     */
    @PostMapping("/updateAirSheetCells")
    public AjaxResult updateAirSheetCells(@RequestBody Map<String, Object> params) {
        try {
            String userId = (String) params.get("userId");
            String worksheetId = (String) params.get("worksheetId");
            String range = (String) params.get("range");
            @SuppressWarnings("unchecked")
            List<List<Object>> values = (List<List<Object>>) params.get("values");

            if (userId == null || worksheetId == null) {
                return AjaxResult.error("userId和worksheetId不能为空");
            }

            WPS365TokenInfo tokenInfo = wps365OAuthServiceImpl.getTokenByUserId(userId);
            if (tokenInfo == null) {
                return AjaxResult.error("用户未授权，请先完成授权");
            }

            // 检查Token是否有效
            if (tokenInfo.isExpired() && tokenInfo.getRefreshToken() != null) {
                try {
                    tokenInfo = wps365OAuthService.refreshAccessToken(tokenInfo.getRefreshToken());
                    wps365OAuthService.saveToken(userId, tokenInfo);
                } catch (Exception e) {
                    log.error("刷新Token失败", e);
                    return AjaxResult.error("Token已过期且刷新失败，请重新授权");
                }
            }

            JSONObject result = wps365ApiService.updateAirSheetCells(tokenInfo.getAccessToken(), worksheetId, range, values);
            return AjaxResult.success("更新AirSheet数据成功", result);
        } catch (Exception e) {
            log.error("更新AirSheet数据失败", e);
            return AjaxResult.error("更新AirSheet数据失败: " + e.getMessage());
        }
    }
}

