package com.ruoyi.jarvis.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.jarvis.config.WPS365Config;
import com.ruoyi.jarvis.service.IWPS365ApiService;
import com.ruoyi.jarvis.util.WPS365ApiUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * WPS365 API服务实现类
 * 
 * @author system
 */
@Service
public class WPS365ApiServiceImpl implements IWPS365ApiService {
    
    private static final Logger log = LoggerFactory.getLogger(WPS365ApiServiceImpl.class);
    
    @Autowired
    private WPS365Config wps365Config;
    
    @Override
    public JSONObject getUserInfo(String accessToken) {
        try {
            // WPS365用户信息API: GET /api/v1/user/info
            // 注意：如果此API不存在或需要不同的路径，请查看WPS365官方文档
            String url = wps365Config.getApiBaseUrl() + "/user/info";
            log.debug("调用用户信息API: {}", url);
            JSONObject result = WPS365ApiUtil.httpRequest("GET", url, accessToken, null);
            log.debug("用户信息API响应: {}", result);
            return result;
        } catch (Exception e) {
            log.error("获取用户信息失败 - url: {}, error: {}", 
                wps365Config.getApiBaseUrl() + "/user/info", e.getMessage(), e);
            // 不抛出异常，让调用方处理（使用降级方案）
            throw new RuntimeException("获取用户信息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getFileList(String accessToken, Map<String, Object> params) {
        try {
            // WPS365文件列表API路径可能是 /yundoc/files 而不是 /files
            // 根据WPS365 API文档，文件相关API通常在 /yundoc 路径下
            StringBuilder url = new StringBuilder(wps365Config.getApiBaseUrl() + "/yundoc/files");
            
            // 添加查询参数
            if (params != null && !params.isEmpty()) {
                url.append("?");
                boolean first = true;
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (!first) {
                        url.append("&");
                    }
                    // URL编码参数值
                    try {
                        String key = entry.getKey();
                        String value = entry.getValue() != null ? entry.getValue().toString() : "";
                        url.append(key).append("=").append(java.net.URLEncoder.encode(value, "UTF-8"));
                    } catch (java.io.UnsupportedEncodingException e) {
                        url.append(entry.getKey()).append("=").append(entry.getValue());
                    }
                    first = false;
                }
            }
            
            log.debug("调用文件列表API: {}", url.toString());
            return WPS365ApiUtil.httpRequest("GET", url.toString(), accessToken, null);
        } catch (Exception e) {
            log.error("获取文件列表失败 - url: {}", wps365Config.getApiBaseUrl() + "/yundoc/files", e);
            throw new RuntimeException("获取文件列表失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getFileInfo(String accessToken, String fileToken) {
        try {
            // WPS365文件信息API路径：/yundoc/files/{fileToken}
            String url = wps365Config.getApiBaseUrl() + "/yundoc/files/" + fileToken;
            log.debug("调用文件信息API: {}", url);
            return WPS365ApiUtil.httpRequest("GET", url, accessToken, null);
        } catch (Exception e) {
            log.error("获取文件信息失败 - fileToken: {}, url: {}", fileToken, 
                wps365Config.getApiBaseUrl() + "/yundoc/files/" + fileToken, e);
            throw new RuntimeException("获取文件信息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject updateCells(String accessToken, String fileToken, int sheetIdx, String range, List<List<Object>> values) {
        try {
            // WPS365 KSheet API: /api/v1/openapi/ksheet/:file_token/sheets/:sheet_idx/cells
            String url = wps365Config.getApiBaseUrl() + "/openapi/ksheet/" + fileToken + "/sheets/" + sheetIdx + "/cells";
            
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("range", range);
            
            // 将values转换为JSONArray
            JSONArray valuesArray = new JSONArray();
            if (values != null) {
                for (List<Object> row : values) {
                    JSONArray rowArray = new JSONArray();
                    if (row != null) {
                        for (Object cell : row) {
                            rowArray.add(cell != null ? cell : "");
                        }
                    }
                    valuesArray.add(rowArray);
                }
            }
            requestBody.put("values", valuesArray);
            
            String bodyStr = requestBody.toJSONString();
            log.debug("更新单元格数据 - url: {}, range: {}, values: {}", url, range, bodyStr);
            
            return WPS365ApiUtil.httpRequest("POST", url, accessToken, bodyStr);
        } catch (Exception e) {
            log.error("更新单元格数据失败 - fileToken: {}, sheetIdx: {}, range: {}", fileToken, sheetIdx, range, e);
            throw new RuntimeException("更新单元格数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject readCells(String accessToken, String fileToken, int sheetIdx, String range) {
        try {
            // WPS365 KSheet API: GET /api/v1/openapi/ksheet/:file_token/sheets/:sheet_idx/cells
            String url = wps365Config.getApiBaseUrl() + "/openapi/ksheet/" + fileToken + "/sheets/" + sheetIdx + "/cells";
            if (range != null && !range.trim().isEmpty()) {
                url += "?range=" + java.net.URLEncoder.encode(range, "UTF-8");
            }
            
            return WPS365ApiUtil.httpRequest("GET", url, accessToken, null);
        } catch (Exception e) {
            log.error("读取单元格数据失败 - fileToken: {}, sheetIdx: {}, range: {}", fileToken, sheetIdx, range, e);
            throw new RuntimeException("读取单元格数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getSheetList(String accessToken, String fileToken) {
        try {
            // WPS365 KSheet API: GET /api/v1/openapi/ksheet/:file_token/sheets
            String url = wps365Config.getApiBaseUrl() + "/openapi/ksheet/" + fileToken + "/sheets";
            return WPS365ApiUtil.httpRequest("GET", url, accessToken, null);
        } catch (Exception e) {
            log.error("获取工作表列表失败 - fileToken: {}", fileToken, e);
            throw new RuntimeException("获取工作表列表失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject createSheet(String accessToken, String fileToken, String sheetName) {
        try {
            // WPS365 KSheet API: POST /api/v1/openapi/ksheet/:file_token/sheets
            String url = wps365Config.getApiBaseUrl() + "/openapi/ksheet/" + fileToken + "/sheets";
            
            JSONObject requestBody = new JSONObject();
            requestBody.put("name", sheetName);
            
            String bodyStr = requestBody.toJSONString();
            return WPS365ApiUtil.httpRequest("POST", url, accessToken, bodyStr);
        } catch (Exception e) {
            log.error("创建数据表失败 - fileToken: {}, sheetName: {}", fileToken, sheetName, e);
            throw new RuntimeException("创建数据表失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject batchUpdateCells(String accessToken, String fileToken, int sheetIdx, List<Map<String, Object>> updates) {
        try {
            // WPS365 KSheet API: POST /api/v1/openapi/ksheet/:file_token/sheets/:sheet_idx/cells/batch
            String url = wps365Config.getApiBaseUrl() + "/openapi/ksheet/" + fileToken + "/sheets/" + sheetIdx + "/cells/batch";
            
            JSONObject requestBody = new JSONObject();
            JSONArray updatesArray = new JSONArray();
            
            if (updates != null) {
                for (Map<String, Object> update : updates) {
                    JSONObject updateObj = new JSONObject();
                    updateObj.put("range", update.get("range"));
                    
                    // 将values转换为JSONArray
                    @SuppressWarnings("unchecked")
                    List<List<Object>> values = (List<List<Object>>) update.get("values");
                    JSONArray valuesArray = new JSONArray();
                    if (values != null) {
                        for (List<Object> row : values) {
                            JSONArray rowArray = new JSONArray();
                            if (row != null) {
                                for (Object cell : row) {
                                    rowArray.add(cell != null ? cell : "");
                                }
                            }
                            valuesArray.add(rowArray);
                        }
                    }
                    updateObj.put("values", valuesArray);
                    updatesArray.add(updateObj);
                }
            }
            
            requestBody.put("updates", updatesArray);
            String bodyStr = requestBody.toJSONString();
            
            return WPS365ApiUtil.httpRequest("POST", url, accessToken, bodyStr);
        } catch (Exception e) {
            log.error("批量更新单元格数据失败 - fileToken: {}, sheetIdx: {}", fileToken, sheetIdx, e);
            throw new RuntimeException("批量更新单元格数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject readAirSheetCells(String accessToken, String worksheetId, String range) {
        try {
            // WPS365 AirSheet API: GET https://openapi.wps.cn/v7/airsheet/{file_id}/worksheets/{worksheet_id}
            // 根据文档：https://open.wps.cn/documents/app-integration-dev/wps365/server/airsheet/worksheets/VbHZwButmh
            // 注意：worksheetId既是file_id也是worksheet_id（AirSheet中文件ID就是工作表ID）
            String baseUrl = "https://openapi.wps.cn/v7";
            String url = baseUrl + "/airsheet/" + worksheetId + "/worksheets/" + worksheetId;
            if (range != null && !range.trim().isEmpty()) {
                url += "?range=" + java.net.URLEncoder.encode(range, "UTF-8");
            }
            
            log.debug("读取AirSheet数据 - url: {}, range: {}", url, range);
            return WPS365ApiUtil.httpRequest("GET", url, accessToken, null);
        } catch (Exception e) {
            log.error("读取AirSheet数据失败 - worksheetId: {}, range: {}", worksheetId, range, e);
            throw new RuntimeException("读取AirSheet数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject updateAirSheetCells(String accessToken, String worksheetId, String range, List<List<Object>> values) {
        try {
            // WPS365 AirSheet API: PUT https://openapi.wps.cn/v7/airsheet/{file_id}/worksheets/{worksheet_id}
            // 注意：worksheetId既是file_id也是worksheet_id（AirSheet中文件ID就是工作表ID）
            String baseUrl = "https://openapi.wps.cn/v7";
            String url = baseUrl + "/airsheet/" + worksheetId + "/worksheets/" + worksheetId;
            
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            if (range != null && !range.trim().isEmpty()) {
                requestBody.put("range", range);
            }
            
            // 构建values数组
            JSONArray valuesArray = new JSONArray();
            if (values != null) {
                for (List<Object> row : values) {
                    JSONArray rowArray = new JSONArray();
                    if (row != null) {
                        for (Object cell : row) {
                            rowArray.add(cell);
                        }
                    }
                    valuesArray.add(rowArray);
                }
            }
            requestBody.put("values", valuesArray);
            
            String bodyStr = requestBody.toJSONString();
            log.debug("更新AirSheet数据 - url: {}, range: {}, values: {}", url, range, bodyStr);
            
            return WPS365ApiUtil.httpRequest("PUT", url, accessToken, bodyStr);
        } catch (Exception e) {
            log.error("更新AirSheet数据失败 - worksheetId: {}, range: {}", worksheetId, range, e);
            throw new RuntimeException("更新AirSheet数据失败: " + e.getMessage(), e);
        }
    }
}

