package com.czg.service.order.print;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.entity.HandoverRecord;
import com.czg.account.entity.PrintMachine;
import com.czg.account.entity.ShopInfo;
import com.czg.account.service.ShopInfoService;
import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo;
import com.czg.service.order.enums.OrderStatusEnums;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author Administrator
 */
@Component
@Slf4j
public class FeiPrinter extends PrinterHandler implements PrinterImpl {
    @Resource
    private RestTemplate restTemplate;

    @Resource
    private ShopInfoService shopInfoService;

    // API 地址
    private static final String URL = "http://api.feieyun.cn/Api/Open/";

    // 飞鹅云 API 账号
    private static final String USER = "chaozhanggui2022@163.com";
    private static final String UKEY = "UfWkhXxSkeSSscsU";

    public FeiPrinter() {
        super("飞鹅");
    }

    private final PrintSignLabel printSignLabel = new PrintSignLabel()
            .setBr("<BR>")
            .setCut("")
            .setCenterBold(new String[]{"<CB>", "</CB>"})
            .setF(new String[]{"<F>", "</F>"})
            .setL(new String[]{"<L>", "</L>"})
            .setS(new String[]{"", ""})
            .setF(new String[]{"<B>", "</B>"})
            .setQr(new String[]{"<QR>", "</QR>"})
            .setCenter(new String[]{"<C>", "</C>"})
            .setBold(new String[]{"<BOLD>", "</BOLD>"});

    @Override
    public PrintSignLabel getSignLabelInfo() {
        return printSignLabel;
    }

    @Override
    protected void normalDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
        String remark = orderDetail.getRemark();
        String content = buildDishPrintData(false, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), remark, orderDetail.getProGroupInfo());
        Object o = sendPrintRequest(machine.getAddress(), content, null, "1");
        printMachineLogService.save(machine, "新订单", content, o);

//        printMachineLogService.save(machine, "新订单", , );
    }


    @Override
    protected void returnDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
        String remark = orderDetail.getRemark();
        String content = buildDishPrintData(true, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getReturnNum(), remark, orderDetail.getProGroupInfo());
        Object o = sendPrintRequest(machine.getAddress(), content, null, "1");
        printMachineLogService.save(machine, "退款单", content, o);

    }

    @Override
    protected void returnOrderPrint(OrderInfo orderInfo, PrintMachine machine, String balance, List<OrderDetail> detailList) {
        ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
        String printerNum = "1";
        if (StrUtil.isNotBlank(machine.getPrintQty())) {
            printerNum = machine.getPrintQty().split("\\^")[1];
        }

        PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName())
                .setPrintType("普通打印").setPickupNum(getPickupNum(orderInfo))
                .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString())
                .setOriginalAmount(orderInfo.getOriginAmount().toPlainString()).setReturn(isReturn(orderInfo))
                .setBalance(balance).setPayType((ObjectUtil.isEmpty(orderInfo.getPayType()) || ObjectUtil.isNull(orderInfo.getPayType()) ? "" : orderInfo.getPayType())).setIntegral("0")
                .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("结算单")
                .setRemark(orderInfo.getRemark()).setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString());
        String string = buildOrderPrintData(printInfoDTO, detailList);
        Object o = sendPrintRequest(machine.getAddress(), string, null, printerNum);
        printMachineLogService.save(machine, "退款单", string, o);

    }

    @Override
    protected void normalOrderPrint(OrderInfo orderInfo, boolean isPre, PrintMachine machine, String balance, List<OrderDetail> detailList) {
        ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
        long count = orderInfoService.queryChain()
                .eq(OrderInfo::getTradeDay, orderInfo.getTradeDay())
                .eq(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())
                .eq(OrderInfo::getShopId, orderInfo.getShopId())
                .le(OrderInfo::getCreateTime,orderInfo.getCreateTime()).count();
        String printerNum = "1";
        if (StrUtil.isNotBlank(machine.getPrintQty())) {
            printerNum = machine.getPrintQty().split("\\^")[1];
        }

        PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName())
                .setCount(count)
                .setPrintType("普通打印").setPickupNum(getPickupNum(orderInfo))
                .setOrderNo(orderInfo.getOrderNo()).setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setOperator("【POS-1】001").setPayAmount(orderInfo.getPayAmount().toPlainString())
                .setOriginalAmount(orderInfo.getOriginAmount().toPlainString()).setReturn(isReturn(orderInfo))
                .setBalance(balance).setPayType((ObjectUtil.isEmpty(orderInfo.getPayType()) || ObjectUtil.isNull(orderInfo.getPayType()) ? "" : orderInfo.getPayType())).setIntegral("0")
                .setOutNumber(orderInfo.getTakeCode()).setPrintTitle(isPre ? "预结算单" : "结算单")
                .setRemark(orderInfo.getRemark()).setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString());
        printInfoDTO.setPrintTitle(printInfoDTO.getPrintTitle());

        String string = buildOrderPrintData(printInfoDTO, detailList);
        Object resp = sendPrintRequest(machine.getAddress(), string, null, printerNum);
        printMachineLogService.save(machine, "结算单", string, resp);
    }

    @Override
    protected void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote) {
        String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}";
        String data = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime);
        Object resp = sendPrintRequest(machine.getAddress(), data, voiceJson, "1");
        printMachineLogService.save(machine, "叫号单", data, resp);
    }

    @Override
    protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) {
        String string = buildHandoverData(record);
        String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
        sendPrintRequest(machine.getAddress(), string, voiceJson, "1");
    }

    /**
     * 生成签名
     */
    private static String signature(String timeStamp) {
        return DigestUtils.sha1Hex(FeiPrinter.USER + FeiPrinter.UKEY + timeStamp);
    }

    @Override
    public <R> R sendPrintRequest(String address, String metaPrintData, String voiceData, String printerNum) {
        log.info("飞蛾打印机开始发送打印请求, 设备地址: {}, 元数据: {}", address, metaPrintData);
        String time = String.valueOf(System.currentTimeMillis() / 1000);
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        formData.add("user", USER);
        formData.add("stime", time);
        formData.add("sig", signature(time));
        formData.add("apiname", "Open_printMsg");
        formData.add("sn", address);
        formData.add("content", metaPrintData);
        formData.add("times", printerNum == null ? "1" : printerNum);

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);

            String result = restTemplate.postForObject(URL, requestEntity, String.class);
            log.info("打印结果: {}", result);
            return (R) result;
        } catch (Exception e) {
            log.error("打印请求失败: {}", e.getMessage());
            throw new RuntimeException("飞蛾打印请求失败", e);
        }
    }

}
