package com.ruoyi.jarvis.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.jarvis.config.TencentDocConfig;
import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.service.ITencentDocService;
import com.ruoyi.jarvis.util.TencentDocApiUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.List;

/**
 * 腾讯文档服务实现类
 * 
 * @author system
 */
@Service
public class TencentDocServiceImpl implements ITencentDocService {
    
    private static final Logger log = LoggerFactory.getLogger(TencentDocServiceImpl.class);
    
    @Autowired
    private TencentDocConfig tencentDocConfig;
    
    @Override
    public String getAuthUrl() {
        if (tencentDocConfig == null) {
            throw new RuntimeException("腾讯文档配置未加载，请检查TencentDocConfig是否正确注入");
        }
        
        String appId = tencentDocConfig.getAppId();
        String redirectUri = tencentDocConfig.getRedirectUri();
        String oauthUrl = tencentDocConfig.getOauthUrl();
        
        log.debug("获取授权URL - appId: {}, redirectUri: {}, oauthUrl: {}", appId, redirectUri, oauthUrl);
        
        // 验证配置参数
        if (appId == null || appId.trim().isEmpty()) {
            throw new RuntimeException("腾讯文档应用ID未配置，请检查application-dev.yml中的tencent.doc.app-id配置");
        }
        if (redirectUri == null || redirectUri.trim().isEmpty()) {
            throw new RuntimeException("腾讯文档回调地址未配置，请检查application-dev.yml中的tencent.doc.redirect-uri配置");
        }
        if (oauthUrl == null || oauthUrl.trim().isEmpty()) {
            oauthUrl = "https://docs.qq.com/oauth/v2/authorize"; // 使用默认值
            log.warn("OAuth URL未配置，使用默认值: {}", oauthUrl);
        }
        
        // 构建授权URL（根据腾讯文档官方文档：https://docs.qq.com/open/document/app/oauth2/authorize.html）
        StringBuilder authUrl = new StringBuilder();
        authUrl.append(oauthUrl);
        authUrl.append("?client_id=").append(appId);
        try {
            // 确保redirectUri不为null后再编码
            String encodedRedirectUri = java.net.URLEncoder.encode(redirectUri, "UTF-8");
            authUrl.append("&redirect_uri=").append(encodedRedirectUri);
        } catch (java.io.UnsupportedEncodingException e) {
            log.error("URL编码失败", e);
            authUrl.append("&redirect_uri=").append(redirectUri);
        } catch (Exception e) {
            log.error("构建授权URL失败", e);
            throw new RuntimeException("构建授权URL失败: " + e.getMessage(), e);
        }
        authUrl.append("&response_type=code");
        authUrl.append("&scope=all");  // 根据官方文档，scope固定为all
        
        // 添加state参数（用于防CSRF攻击，可选但建议带上）
        String state = java.util.UUID.randomUUID().toString();
        authUrl.append("&state=").append(state);
        
        String result = authUrl.toString();
        log.info("生成授权URL: {}", result);
        return result;
    }
    
    @Override
    public JSONObject getAccessTokenByCode(String code) {
        try {
            return TencentDocApiUtil.getAccessToken(
                tencentDocConfig.getAppId(),
                tencentDocConfig.getAppSecret(),
                code,
                tencentDocConfig.getRedirectUri(),
                tencentDocConfig.getTokenUrl()
            );
        } catch (Exception e) {
            log.error("通过授权码获取访问令牌失败", e);
            throw new RuntimeException("获取访问令牌失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject refreshAccessToken(String refreshToken) {
        try {
            return TencentDocApiUtil.refreshAccessToken(
                tencentDocConfig.getAppId(),
                tencentDocConfig.getAppSecret(),
                refreshToken,
                tencentDocConfig.getRefreshTokenUrl()
            );
        } catch (Exception e) {
            log.error("刷新访问令牌失败", e);
            throw new RuntimeException("刷新访问令牌失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject uploadLogisticsToSheet(String accessToken, String fileId, String sheetId, List<JDOrder> orders) {
        try {
            if (orders == null || orders.isEmpty()) {
                throw new IllegalArgumentException("订单列表不能为空");
            }
            
            // 构建要写入的数据（二维数组格式）
            JSONArray values = new JSONArray();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            
            for (JDOrder order : orders) {
                JSONArray row = new JSONArray();
                // 根据表格列顺序添加数据
                // 假设列顺序为：内部单号、订单号、下单时间、型号、地址、物流链接、下单人、付款金额、后返金额、备注
                row.add(order.getRemark() != null ? order.getRemark() : "");
                row.add(order.getOrderId() != null ? order.getOrderId() : "");
                row.add(order.getOrderTime() != null ? sdf.format(order.getOrderTime()) : "");
                row.add(order.getModelNumber() != null ? order.getModelNumber() : "");
                row.add(order.getAddress() != null ? order.getAddress() : "");
                row.add(order.getLogisticsLink() != null ? order.getLogisticsLink() : "");
                row.add(order.getBuyer() != null ? order.getBuyer() : "");
                row.add(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "");
                row.add(order.getRebateAmount() != null ? order.getRebateAmount().toString() : "");
                row.add(order.getStatus() != null ? order.getStatus() : "");
                
                values.add(row);
            }
            
            // 追加数据到表格
            return TencentDocApiUtil.appendSheetData(accessToken, fileId, sheetId, values, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("上传物流信息到表格失败", e);
            throw new RuntimeException("上传物流信息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject appendLogisticsToSheet(String accessToken, String fileId, String sheetId, JDOrder order) {
        try {
            if (order == null) {
                throw new IllegalArgumentException("订单信息不能为空");
            }
            
            // 构建单行数据
            JSONArray values = new JSONArray();
            JSONArray row = new JSONArray();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            
            // 根据表格列顺序添加数据
            row.add(order.getRemark() != null ? order.getRemark() : "");
            row.add(order.getOrderId() != null ? order.getOrderId() : "");
            row.add(order.getOrderTime() != null ? sdf.format(order.getOrderTime()) : "");
            row.add(order.getModelNumber() != null ? order.getModelNumber() : "");
            row.add(order.getAddress() != null ? order.getAddress() : "");
            row.add(order.getLogisticsLink() != null ? order.getLogisticsLink() : "");
            row.add(order.getBuyer() != null ? order.getBuyer() : "");
            row.add(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "");
            row.add(order.getRebateAmount() != null ? order.getRebateAmount().toString() : "");
            row.add(order.getStatus() != null ? order.getStatus() : "");
            
            values.add(row);
            
            // 追加数据到表格
            return TencentDocApiUtil.appendSheetData(accessToken, fileId, sheetId, values, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("追加物流信息到表格失败", e);
            throw new RuntimeException("追加物流信息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject readSheetData(String accessToken, String fileId, String sheetId, String range) {
        try {
            return TencentDocApiUtil.readSheetData(accessToken, fileId, sheetId, range, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("读取表格数据失败", e);
            throw new RuntimeException("读取表格数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject writeSheetData(String accessToken, String fileId, String sheetId, String range, Object values) {
        try {
            return TencentDocApiUtil.writeSheetData(accessToken, fileId, sheetId, range, values, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("写入表格数据失败", e);
            throw new RuntimeException("写入表格数据失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getFileInfo(String accessToken, String fileId) {
        try {
            return TencentDocApiUtil.getFileInfo(accessToken, fileId, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("获取文件信息失败", e);
            throw new RuntimeException("获取文件信息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getSheetList(String accessToken, String fileId) {
        try {
            return TencentDocApiUtil.getSheetList(accessToken, fileId, tencentDocConfig.getApiBaseUrl());
        } catch (Exception e) {
            log.error("获取工作表列表失败", e);
            throw new RuntimeException("获取工作表列表失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public JSONObject getUserInfo(String accessToken) {
        try {
            return TencentDocApiUtil.getUserInfo(accessToken);
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            throw new RuntimeException("获取用户信息失败: " + e.getMessage(), e);
        }
    }
}

