package com.malk.jiuan.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.malk.jiuan.entity.ConvertSales;
import com.malk.jiuan.entity.Sales;
import com.malk.jiuan.entity.SalesReturn;
import com.malk.jiuan.service.JiuanService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okio.BufferedSink;
import okio.Okio;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Service
public class JiuanServiceImpl implements JiuanService {
    private final static String SHOP_NUMBER = "TJMP1F140";//商铺号
    private final static String CASH_REGISTER_Number = "1400";//收银机号
    private final static String GOODS_NUMBER = "00101701";//货品编码
    private final static String DATE_PATTERN1 = "yyyy-MM-dd HH:mm:ss";

    @Value(value = "${uploadFile.path}")
    private String uploadFilePath;

    @Value(value = "${saveFile.path}")
    private String saveFilePath;

    @Override
    public void convertFile() {
        //搜索钉盘文件
        /*Map query = new HashMap();
        query.put("parentId",0);
        query.put("unionId", UNION_ID);
        query.put("maxResults",10);
        query.put("orderBy","CREATE_TIME");
        query.put("order","DESC");
        DDR_New ddrNew = (DDR_New) UtilHttp.doGet("https://api.dingtalk.com/v1.0/storage/spaces/" + SPACE_ID + "/dentries", ddClient.initTokenHeader(), query, DDR_New.class);

        List<Map> dentries = ddrNew.getDentries();

        String fileId = "";
        String fileName = "";

        for (Map dentry : dentries) {
            String name = UtilMap.getString(dentry, "name");
            if (name.contains(formattedTime3)) {
                fileId = UtilMap.getString(dentry, "id");
                fileName = name;
                break;
            }
        }

        //获取文件下载信息
        query.keySet().removeIf(key -> !key.equals("unionId"));
        DDR_New ddrNew2 = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + SPACE_ID + "/dentries/" + fileId + "/downloadInfos/query", ddClient.initTokenHeader(), query, null,DDR_New.class);

        Map headerSignatureInfo = ddrNew2.getHeaderSignatureInfo();

        Map<String,String> headers = UtilMap.getMap(headerSignatureInfo, "headers");

        List<String> resourceUrls = UtilMap.getList(headerSignatureInfo, "resourceUrls");

        downloadDdFile(resourceUrls.get(0) ,headers, saveFilePath + fileName);*/
        log.info("------------------开始转换文件---------------------");

        //读取文件夹下所有门店流水数据
        File folder = new File(uploadFilePath);

        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();

            if (files != null) {
                for (File file : files) {
                    List<Sales> salesList = new ArrayList<>();

                    //销售单
                    EasyExcel.read(file.getPath(), Sales.class, new PageReadListener<Sales>(dataList -> {
                        for (Sales Sales : dataList) {
                            log.info("读取到一条数据{}", JSON.toJSONString(Sales));
                            salesList.add(Sales);
                        }
                    })).sheet(0).doRead();

                    //退货单
                    EasyExcel.read(file.getPath(), SalesReturn.class, new PageReadListener<SalesReturn>(dataList -> {
                        for (SalesReturn salesReturn : dataList) {
                            log.info("读取到一条数据{}", JSON.toJSONString(salesReturn));
                            Sales sales = new Sales();
                            sales.setZfze(salesReturn.getYtze());//应退金额
                            sales.setZfsj(salesReturn.getTksj());//退款时间
                            sales.setZffs(salesReturn.getZffs());//支付方式
                            salesList.add(sales);
                        }
                    })).sheet(1).doRead();

                    //支付时间升序
                    List<Sales> sortedSalesList = salesList.stream()
                            .sorted(Comparator.comparing(Sales::getZfsj))
                            .collect(Collectors.toList());

                    AtomicInteger counter = new AtomicInteger(1);
                    String currentDatePrefix = "";

                    List<ConvertSales> convertSalesList = new ArrayList<>();

                    for (Sales sales : sortedSalesList) {
                        // 获取日期的YYMMDD部分
                        LocalDate date = sales.getZfsj().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                        LocalDateTime localDateTime = sales.getZfsj().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

                        String datePrefix = date.format(DateTimeFormatter.ofPattern("yyMMdd"));

                        // 如果日期变化，重置计数器
                        if (!datePrefix.equals(currentDatePrefix)) {
                            currentDatePrefix = datePrefix;
                            counter.set(1);
                        }

                        // 生成流水号：YYMMDD + 4位流水（不足补零）
                        String serialNumber = String.format("%s%04d", datePrefix, counter.getAndIncrement());

                        ConvertSales convertSales = new ConvertSales();

                        convertSales.setRow1(CASH_REGISTER_Number);//收银机号

                        convertSales.setRow2(serialNumber);//交易流水号

                        convertSales.setRow3(localDateTime.format(DateTimeFormatter.ofPattern(DATE_PATTERN1)));//支付时间

                        convertSales.setRow4(new DecimalFormat("0.00").format(sales.getZfze()));//整单实收金额

                        convertSales.setRow5(GOODS_NUMBER);//货品编号

                        //交易方式
                        if (Strings.isNotBlank(sales.getZffs())){
                            switch (sales.getZffs()){
                                case "现金支付" : convertSales.setRow6("01");break;
                                case "其他" : convertSales.setRow6("06");break;
                    /*case "刷卡支付" : convertSales.setRow6("02");break;
                    case "外挂POS机" : convertSales.setRow6("03");break;
                    case "储值卡" : convertSales.setRow6("04");break;
                    case "代金卷" : convertSales.setRow6("05");break;*/
                                default: convertSales.setRow6("03");break;//外挂pos机
                            }
                        }

                        convertSalesList.add(convertSales);
                    }

                    if (!convertSalesList.isEmpty()){
                        // 将对象列表写入文件
                        String newFileName = SHOP_NUMBER + "_" + file.getName().substring(0,12) + "00" + "_LIST.txt";
                        writeObjectsToFile(convertSalesList, saveFilePath + newFileName);
                    }

                    //删除门店流水数据
                    boolean isDelete = file.delete();

                    if (isDelete) {
                        log.info("文件已删除");
                    }else {
                        log.info("文件删除失败");
                    }
                }
            }
        } else {
            System.out.println("指定的路径不存在或不是目录");
        }

        log.info("------------------转换文件结束---------------------");
    }

    /**
     *
     * @param url 调用获取下载信息接口获取的internalResourceUrls
     * @param path 文件要下载的目标路径
     * @param headers 调用下载信息接口获取的headers
     */
    public static void downloadDdFile(String url,Map<String,String> headers,String path){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .headers(Headers.of(headers))
                .build();
        try (Response response = client.newCall(request).execute()) { // 同步请求
            if (!response.isSuccessful()) {
                throw new IOException("服务器返回错误: " + response.code());
            }
            File dest = new File(path);
            try (BufferedSink sink = Okio.buffer(Okio.sink(dest))) {
                sink.writeAll(response.body().source());
                System.out.println("文件下载成功: " + dest.getAbsolutePath());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> void writeObjectsToFile(List<T> objects, String filePath) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            if (objects == null || objects.size() == 0) {
                return;
            }

            // 获取对象的所有字段（包括私有字段）
            Field[] fields = objects.get(0).getClass().getDeclaredFields();

            // 遍历对象数组
            for (T obj : objects) {
                StringBuilder line = new StringBuilder();

                // 遍历每个字段
                for (Field field : fields) {
                    field.setAccessible(true); // 允许访问私有字段
                    Object value = field.get(obj);
                    line.append(value != null ? value.toString() : "").append(",");
                }

                // 写入行（以逗号结尾后换行）
                writer.write(line.toString());
                writer.newLine();
            }

            System.out.println("数据已成功写入文件: " + filePath);
        } catch (IOException | IllegalAccessException e) {
            System.err.println("写入文件时出错: " + e.getMessage());
        }
    }
}
