package com.xjrsoft.module.ledger.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.db.Entity;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.ListUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.module.ledger.dto.LedgerExportDataDto;
import com.xjrsoft.module.ledger.entity.LedgerConfig;
import com.xjrsoft.module.ledger.entity.LedgerConfigRelease;
import com.xjrsoft.module.ledger.service.ILedgerConfigReleaseService;
import com.xjrsoft.module.ledger.service.ILedgerConfigService;
import com.xjrsoft.module.magicapi.service.IMagicApiService;
import com.xjrsoft.module.magicapi.vo.MagicApiInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.ssssssss.magicapi.core.service.MagicAPIService;
import org.ssssssss.magicapi.modules.db.model.PageResult;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @title: 台账导出
 * @Author szs
 * @Date: 2024-03-20
 * @Version 1.0
 */
@RestController
@RequestMapping("/ledger" + "/LedgerExport")
@Api(value = "/ledger" + "/LedgerExport", tags = "台账导出")
@AllArgsConstructor
public class LedgerExportController {

    private ILedgerConfigReleaseService ledgerConfigReleaseService;

    private ILedgerConfigService ledgerConfigService;

    private IMagicApiService magicApiService;

    private MagicAPIService magicAPIService;

    @PostMapping("/export-query")
    @ApiOperation(value = "导出")
    public ResponseEntity<byte[]> exportData(@Valid @RequestBody LedgerExportDataDto dto) {
//    @GetMapping("/export-query")
//    @ApiOperation(value = "导出")
//    public ResponseEntity<byte[]> exportData(@Valid LedgerExportDataDto dto) {
        LedgerConfigRelease release = ledgerConfigReleaseService.getById(dto.getConfigIntoId());
        if (release == null) {
            throw new MyException("导出数据失败");
        }

        LedgerConfig ledgerConfig = ledgerConfigService.getById(release.getLedgerConfigId());

        if (ledgerConfig == null) {
            throw new MyException("导出数据失败");
        }

        JsonParser parser = new JsonParser();
        JsonObject jsonObject = parser.parse(release.getConfigJson()).getAsJsonObject();

        JsonArray columnConfigs = jsonObject.get("columnConfigs").getAsJsonArray();

        JsonObject apiInfo = jsonObject.get("apiInfo").getAsJsonObject();
        //构建excel头
        List<List<String>> headlist = buildExcelHeader(columnConfigs);

        //构建头对应的key
        List<List<String>> keylist = buildEntityKey(columnConfigs);

        List<List<Object>> dataList = buildExcelDataList(apiInfo, keylist, dto.getQueryParam());

        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot).head(headlist).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);

        String encodedFileName = "";
        try{
            encodedFileName = URLEncoder.encode(ledgerConfig.getName() , "UTF-8");
        }catch (Exception e){

        }

        return RT.fileStream(bot.toByteArray(), encodedFileName + ExcelTypeEnum.XLSX.getValue());
    }

    /**
     * 构建excel标题列
     *
     * @param columnConfigs
     * @return
     */
    private List<List<String>> buildExcelHeader(JsonArray columnConfigs) {
        List<List<String>> list = ListUtils.newArrayList();
        for (JsonElement element : columnConfigs) {
            String key = element.getAsJsonObject().get("label").getAsString();
            List<String> head = ListUtils.newArrayList();
            head.add(key);
            list.add(head);
        }
        return list;
    }

    private List<List<String>> buildEntityKey(JsonArray columnConfigs) {
        List<List<String>> list = ListUtils.newArrayList();
        for (JsonElement element : columnConfigs) {
            String key = element.getAsJsonObject().get("field").getAsString();
            List<String> head = ListUtils.newArrayList();
            head.add(key);
            list.add(head);
        }
        return list;
    }

    /**
     * 构建数据集合
     *
     * @param apiInfo
     * @return
     */
    private List<List<Object>> buildExcelDataList(JsonObject apiInfo, List<List<String>> headlist, Map<String, Object> queryParam) {
        //获取magicApi的id
        String apiId = apiInfo.get("apiId").getAsString();

        //获取magicApi的入参
        JsonArray apiParams = apiInfo.get("apiParams").getAsJsonArray();
        JsonArray tableInfo = apiParams.get(0).getAsJsonObject().get("tableInfo").getAsJsonArray();

        MagicApiInfoVo info = magicApiService.info(apiId);
        Map<String, Object> params = new HashMap<>();


        for (JsonElement element : tableInfo) {
            String key = element.getAsJsonObject().get("name").getAsString();
            if (queryParam != null && queryParam.containsKey(key) && queryParam.get(key) != null) {
                params.put(key, queryParam.get(key));
            }
        }
        if (!params.containsKey("limit")) {
            params.put("limit", 1);
        }
        if (!params.containsKey("size")) {
            params.put("size", Integer.MAX_VALUE);
        }
        PageResult res = magicAPIService.execute(info.getMethod(), info.getPath(), params);

        List<List<Object>> list = ListUtils.newArrayList();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        SimpleDateFormat sdfWithTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");


        for (Object obj : res.getList()) {
            List<Object> data = ListUtils.newArrayList();
            //Map<String, Object> map = (LinkedHashMap)obj;
            Entity rowValue = Convert.convert(Entity.class, obj);

            for (List<String> head : headlist){
                Object value = rowValue.get(head.get(0));

                if (value instanceof Date) {
                    String timeStr = sdfTime.format(value);
                    String dateStr = "";

                    if (timeStr.equals("00:00:00")) {
                        dateStr = sdf.format(value);
                    } else {
                        dateStr = sdfWithTime.format(value);
                    }
                    data.add(dateStr);
                }else if(value instanceof LocalDateTime){
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    String formattedDateTime = ((LocalDateTime) value).format(formatter);
                    data.add(formattedDateTime);
                }else if(value instanceof LocalDate){
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    String formattedDate = ((LocalDate) value).format(formatter);
                    data.add(formattedDate);
                }else if(value instanceof LocalTime){
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
                    String formattedTime = ((LocalTime) value).format(formatter);
                    data.add(formattedTime);
                }else{
                    data.add(rowValue.get(head.get(0)));
                }
            }

            list.add(data);
        }
        return list;
    }

}