package com.yifu.cloud.plus.v1.ekp.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.ekp.config.WxConfig;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * 企业微信智能表格管理工具类
 * 实现创建智能表格、创建工作表、清空工作表数据和插入数据的功能
 */
@Component
public class WeComSmartSheetManager {

    /**
     * 企业微信API基础URL
     */
    private static final String WE_COM_API_BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin";

    /**
     * 获取access_token的接口路径
     */
    private static final String GET_TOKEN_PATH = "/gettoken";

    /**
     * 创建文档的接口路径
     */
    private static final String CREATE_DOC_PATH = "/wedoc/create_doc";

    /**
     * 查询子表的接口路径
     */
    private static final String GET_SHEET_PATH = "/wedoc/smartsheet/get_sheet";

    /**
     * 添加记录的接口路径
     */
    private static final String ADD_RECORDS_PATH = "/wedoc/smartsheet/add_records";

    /**
     * 查询记录的接口路径
     */
    private static final String QUERY_RECORDS_PATH = "/wedoc/smartsheet/query_records";

    /**
     * 删除记录的接口路径
     */
    private static final String DELETE_RECORDS_PATH = "/wedoc/smartsheet/delete_records";

    /**
     * 获取字段信息的接口路径
     */
    private static final String GET_FIELDS_PATH = "/wedoc/smartsheet/get_fields";

    /**
     * 创建智能表格
     *
     * @param docName     文档名称
     * @param adminUsers  管理员用户列表
     * @return 文档ID
     */
    public String createSmartSheet(WxConfig wxConfig, String docName, List<String> adminUsers) {
        try {
			RestTemplate restTemplate = new RestTemplate();
			// 1. 获取access_token
			String accessToken = wxConfig.getAccessToken(restTemplate);
			//getAccessToken(corpId, corpSecret);
            if (accessToken == null || accessToken.isEmpty()) {
                System.err.println("获取access_token失败");
                return null;
            }

            // 2. 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("doc_type", 10); // 10: 智能表格
            requestBody.put("doc_name", docName);
            requestBody.put("admin_users", adminUsers);

            // 3. 发送请求创建智能表格
            String docId = createDoc(accessToken, requestBody);
            if (docId != null) {
                System.out.println("智能表格创建成功，文档ID: " + docId);
            } else {
                System.err.println("智能表格创建失败");
            }
            return docId;
        } catch (Exception e) {
            System.err.println("创建智能表格时发生异常: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定智能表格下的所有工作表ID列表
     * 注意：根据企业微信API文档，创建智能表格时会自动创建一个默认的子表
     * 该方法用于查询这些已存在的子表。
     *
     * @param docId      文档ID
     * @return 工作表ID列表
     */
    public List<String> createWorkSheets(WxConfig wxConfig, String docId) {
        try {
			RestTemplate restTemplate = new RestTemplate();
			// 1. 获取access_token
			String accessToken = wxConfig.getAccessToken(restTemplate);
            if (accessToken == null || accessToken.isEmpty()) {
                System.err.println("获取access_token失败");
                return new ArrayList<>();
            }

            return getSheetIds(accessToken, docId);
        } catch (Exception e) {
            System.err.println("获取工作表ID时发生异常: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 使用access_token获取智能表格下的工作表ID列表
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @return 工作表ID列表
     */
    private List<String> getSheetIds(String accessToken, String docId) {
        List<String> sheetIds = new ArrayList<>();
        try {
            String url = WE_COM_API_BASE_URL + GET_SHEET_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            // 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    JSONArray sheets = jsonObject.getJSONArray("sheet_list");
                    if (sheets != null && !sheets.isEmpty()) {
                        for (int i = 0; i < sheets.size(); i++) {
                            JSONObject sheet = sheets.getJSONObject(i);
                            sheetIds.add(sheet.getString("sheet_id"));
                        }
                    } else {
                        System.err.println("未找到任何工作表");
                    }
                } else {
                    System.err.println("查询工作表失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            System.err.println("查询工作表时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return sheetIds;
    }

    /**
     * 通过工作表的ID先清空工作表数据，然后插入新的多条数据
     *
     * @param docId      文档ID
     * @param sheetId    工作表ID
     * @param records    要插入的记录列表
     * @return 是否成功
     */
    public boolean clearAndInsertData(WxConfig wxConfig, String docId, String sheetId,
                                      List<Map<String, Object>> records) {
        try {
			RestTemplate restTemplate = new RestTemplate();
			// 1. 获取access_token
			String accessToken = wxConfig.getAccessToken(restTemplate);
            if (accessToken == null || accessToken.isEmpty()) {
                System.err.println("获取access_token失败");
                return false;
            }

            // 2. 验证字段是否存在
            if (!validateFields(accessToken, docId, sheetId, records)) {
                System.err.println("字段验证失败，请检查字段名称是否正确");
                return false;
            }

            // 3. 清空工作表数据
            if (!clearSheetData(accessToken, docId, sheetId)) {
                System.err.println("清空工作表数据失败");
                return false;
            }

            // 4. 插入新数据（分批处理，避免接口限制）
            if (!insertDataInBatches(accessToken, docId, sheetId, records)) {
                System.err.println("插入数据失败");
                return false;
            }

            System.out.println("清空并插入数据成功");
            return true;
        } catch (Exception e) {
            System.err.println("清空并插入数据时发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取企业微信access_token
     *
     * @param corpId     企业ID
     * @param corpSecret 应用密钥
     * @return access_token
     */
    private String getAccessToken(String corpId, String corpSecret) {
        try {
            String url = WE_COM_API_BASE_URL + GET_TOKEN_PATH + "?corpid=" + corpId + "&corpsecret=" + corpSecret;

            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    return jsonObject.getString("access_token");
                } else {
                    System.err.println("获取access_token失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                    return null;
                }
            }
        } catch (Exception e) {
            System.err.println("获取access_token时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建文档
     *
     * @param accessToken 访问令牌
     * @param requestBody 请求体
     * @return 文档ID
     */
    private String createDoc(String accessToken, JSONObject requestBody) {
        try {
            String url = WE_COM_API_BASE_URL + CREATE_DOC_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    return jsonObject.getString("docid");
                } else {
                    System.err.println("创建文档失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                    return null;
                }
            }
        } catch (Exception e) {
            System.err.println("创建文档时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 验证字段是否存在
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @param records     记录列表
     * @return 是否验证通过
     */
    private boolean validateFields(String accessToken, String docId, String sheetId, List<Map<String, Object>> records) {
        try {
            // 1. 获取表格字段信息
            List<FieldInfo> fieldInfos = getSheetFields(accessToken, docId, sheetId);
            Set<String> fieldTitles = new HashSet<>();
            for (FieldInfo fieldInfo : fieldInfos) {
                fieldTitles.add(fieldInfo.getTitle());
            }

            // 2. 检查记录中的字段是否都存在
            for (Map<String, Object> record : records) {
                Map<String, Object> values = (Map<String, Object>) record.get("values");
                if (values != null) {
                    for (String fieldName : values.keySet()) {
                        if (!fieldTitles.contains(fieldName)) {
                            System.err.println("字段 '" + fieldName + "' 在表格中不存在，请检查字段名称是否正确");
                            return false;
                        }
                    }
                }
            }

            return true;
        } catch (Exception e) {
            System.err.println("验证字段时发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取智能表格字段信息
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @return 字段信息列表
     */
    private List<FieldInfo> getSheetFields(String accessToken, String docId, String sheetId) {
        List<FieldInfo> fieldInfos = new ArrayList<>();
        try {
            String url = WE_COM_API_BASE_URL + GET_FIELDS_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            // 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);
            requestBody.put("sheet_id", sheetId);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    JSONArray fields = jsonObject.getJSONArray("fields");
                    if (fields != null && !fields.isEmpty()) {
						FieldInfo fieldInfo;
                        for (int i = 0; i < fields.size(); i++) {
                            JSONObject field = fields.getJSONObject(i);
                            fieldInfo = new FieldInfo();
                            fieldInfo.setFieldId(field.getString("field_id"));
                            fieldInfo.setTitle(field.getString("field_title"));
                            fieldInfo.setType(field.getString("field_type"));
                            fieldInfos.add(fieldInfo);
                        }
                    }
                } else {
                    System.err.println("获取字段信息失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            System.err.println("获取字段信息时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return fieldInfos;
    }

    /**
     * 清空工作表数据
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @return 是否成功
     */
    private boolean clearSheetData(String accessToken, String docId, String sheetId) {
        try {
            // 1. 查询所有记录ID
            List<String> recordIds = queryAllRecordIds(accessToken, docId, sheetId);
            if (recordIds.isEmpty()) {
                // 没有记录需要删除
                return true;
            }

            // 2. 分批删除记录（企业微信API限制每次最多删除100条记录）
            int batchSize = 100;
            for (int i = 0; i < recordIds.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, recordIds.size());
                List<String> batchRecordIds = recordIds.subList(i, endIndex);

                if (!deleteRecords(accessToken, docId, sheetId, batchRecordIds)) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            System.err.println("清空工作表数据时发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 查询所有记录ID
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @return 记录ID列表
     */
    private List<String> queryAllRecordIds(String accessToken, String docId, String sheetId) {
        List<String> recordIds = new ArrayList<>();
        try {
            String url = WE_COM_API_BASE_URL + QUERY_RECORDS_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            // 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);
            requestBody.put("sheet_id", sheetId);
            requestBody.put("key_type", "CELL_VALUE_KEY_TYPE_FIELD_TITLE");

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    JSONArray records = jsonObject.getJSONArray("records");
                    if (records != null && !records.isEmpty()) {
                        for (int i = 0; i < records.size(); i++) {
                            JSONObject record = records.getJSONObject(i);
                            recordIds.add(record.getString("record_id"));
                        }
                    }
                } else {
                    System.err.println("查询记录失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            System.err.println("查询记录时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return recordIds;
    }

    /**
     * 删除记录
     *
     * @param accessToken  访问令牌
     * @param docId        文档ID
     * @param sheetId      工作表ID
     * @param recordIds    记录ID列表
     * @return 是否成功
     */
    private boolean deleteRecords(String accessToken, String docId, String sheetId, List<String> recordIds) {
        try {
            String url = WE_COM_API_BASE_URL + DELETE_RECORDS_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            // 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);
            requestBody.put("sheet_id", sheetId);
            requestBody.put("record_ids", recordIds);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    return true;
                } else {
                    System.err.println("删除记录失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                    return false;
                }
            }
        } catch (Exception e) {
            System.err.println("删除记录时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 分批插入数据
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @param records     记录列表
     * @return 是否成功
     */
    private boolean insertDataInBatches(String accessToken, String docId, String sheetId, List<Map<String, Object>> records) {
        try {
            // 分批插入数据（企业微信API限制每次最多插入500条记录）
            int batchSize = 500;
            for (int i = 0; i < records.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, records.size());
                List<Map<String, Object>> batchRecords = records.subList(i, endIndex);

                if (!addRecords(accessToken, docId, sheetId, batchRecords)) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            System.err.println("分批插入数据时发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 添加记录
     *
     * @param accessToken 访问令牌
     * @param docId       文档ID
     * @param sheetId     工作表ID
     * @param records     记录列表
     * @return 是否成功
     */
    private boolean addRecords(String accessToken, String docId, String sheetId, List<Map<String, Object>> records) {
        try {
            String url = WE_COM_API_BASE_URL + ADD_RECORDS_PATH + "?access_token=" + accessToken;

            RestTemplate restTemplate = new RestTemplate();

            // 构造请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("docid", docId);
            requestBody.put("sheet_id", sheetId);
            requestBody.put("key_type", "CELL_VALUE_KEY_TYPE_FIELD_TITLE");

            // 构造records数组
            JSONArray recordsArray = new JSONArray();
            for (Map<String, Object> record : records) {
                recordsArray.add(record);
            }
            requestBody.put("records", recordsArray);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject jsonObject = JSON.parseObject(response.getBody());
                if (jsonObject.getInteger("errcode") == 0) {
                    return true;
                } else {
                    System.err.println("添加记录失败，错误代码：" + jsonObject.getInteger("errcode")
                            + "，错误信息：" + jsonObject.getString("errmsg"));
                    // 特别处理字段不存在的错误
                    if (jsonObject.getInteger("errcode") == 2022004) {
                        System.err.println("请检查您要插入的字段名称是否与表格中的字段完全匹配");
                    }
                    return false;
                }
            }
        } catch (Exception e) {
            System.err.println("添加记录时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 使用示例
     *
     */
    public  void test(WxConfig wxConfig) {
        WeComSmartSheetManager manager = new WeComSmartSheetManager();

        // 示例数据
        //String corpId = "your_corp_id";
        //String corpSecret = "your_corp_secret";
        String docName = "测试智能表格";
        List<String> adminUsers = new ArrayList<>();
        adminUsers.add("ZhangQianQian");
        adminUsers.add("FeiTaiLang_Fang");

        // 1. 创建智能表格
        String docId = "dcTSMCj4lWV9MEP7lquZacOY8WS4g-iHxP_jVYA02tdYwb2YYc3BpDR8NrFWkEngHUg8abET4eTIpo9Zv-571NEA";//manager.createSmartSheet(wxConfig, docName, adminUsers);
        if (StringUtils.isEmpty(docId)) {
            System.out.println("创建智能表格失败");
            return;
        }

        // 2. 获取工作表ID列表
        List<String> sheetIds = manager.createWorkSheets(wxConfig, docId);
        if (sheetIds.isEmpty()) {
            System.out.println("获取工作表ID失败");
            return;
        }

        String sheetId = sheetIds.get(0);

        // 3. 准备要插入的数据
        List<Map<String, Object>> records = new ArrayList<>();

        Map<String, Object> record1 = new HashMap<>();
        Map<String, Object> values1 = new HashMap<>();
        values1.put("姓名", "张三");
        values1.put("年龄", "25");
        values1.put("部门", "技术部");
        record1.put("values", values1);

        Map<String, Object> record2 = new HashMap<>();
        Map<String, Object> values2 = new HashMap<>();
        values2.put("姓名", "李四");
        values2.put("年龄", "30");
        values2.put("部门", "市场部");
        record2.put("values", values2);

        records.add(record1);
        records.add(record2);

        // 4. 清空并插入数据
        boolean success = manager.clearAndInsertData(wxConfig, docId, sheetId, records);
        if (success) {
            System.out.println("清空并插入数据成功");
        } else {
            System.out.println("清空并插入数据失败");
        }

    }
    


}