package lingtao.net.Factory;

import lingtao.net.bean.Product;
import lingtao.net.vo.PricingListVo;
import lingtao.net.vo.ProductVo;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

public class CardPricingStrategy implements PricingStrategy {
    @Override
    public PricingListVo calculatePrice(Product dto, String role) {
        String plantName = dto.getPlantName();
        String kindValue = dto.getProTypeLabel();

        if ("菜单".equals(kindValue)) {
            //return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
//            String size = dto.getUi_menu_size();
//            dto.setLength(Double.valueOf(size.substring(0, size.indexOf("*"))));
//            if (size.contains(",")) {
//                size = size.split(",")[0];
//            }
//            if (size.indexOf(("*"), size.indexOf("*") + 1) == -1) {
//                dto.setWidth(Double.valueOf(size.substring(size.indexOf("*") + 1)));
//            } else {
//                dto.setWidth(Double.valueOf(size.substring(size.indexOf("*") + 1, size.indexOf(("*"), size.indexOf("*") + 1))));
//                dto.setLength(Math.abs(Double.parseDouble(size.substring(size.indexOf(("*"), size.indexOf("*") + 1) + 1))));
//            }
        }
        double width = dto.getWidth();
        double length = dto.getLength();
        int count = dto.getCount();
        int number = dto.getNumber();
        // 定义纸张尺寸（单位：毫米）
        double paperLength = 280; // 纸张长度
        double paperWidth = 420;  // 纸张宽度
        String basePrice = "0"; // 基础价格
        BigDecimal price = new BigDecimal(0); // 最终价格
        BigDecimal weight = BigDecimal.ZERO;

        length = convertToMillimetersWithMargin(length);
        width = convertToMillimetersWithMargin(width);
        String material = "1";
        if ("婚礼报纸".equals(kindValue)) {
            material = "2";//157g铜版纸
        } else if ("特种纸名片".equals(kindValue)) {
            material = dto.getKindValue6();
        } else if ("菜单".equals(kindValue) && "2".equals(dto.getKindValue5())) {
            material = "pvc";
        }
        String ggSize = dto.getSize1();//刮刮膜
        List<ProductVo> resultList = new ArrayList<>();
        List<String> craft_list = dto.getCraft() != null ? Arrays.asList(dto.getCraft()) : new ArrayList<>();
        if ("艾印".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
            if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
                return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
            }


            Map<String, Map<String, String>> kindValuePrice = new HashMap<>();

            // 统一键的类型为字符串
            kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
            kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
            kindValuePrice.put("皙贝", createPriceMap("1", "2.1", "2", "3.1"));//白卡
            kindValuePrice.put("琮纹", createPriceMap("1", "2.5", "2", "3.7"));//刚古
            kindValuePrice.put("玉蕊", createPriceMap("1", "2.7", "2", "3.8"));//蛋壳
            kindValuePrice.put("睿狐", createPriceMap("1", "2.7", "2", "3.8"));//莱尼
            kindValuePrice.put("溪雪", createPriceMap("1", "3.2", "2", "3.2"));//珠光
            if (!kindValuePrice.containsKey(material)) {
                return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
            }
            // 检查是否超出纸张尺寸限制
            if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
                return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
            }

            // 计算一张纸能容纳的最大金属标数量
            double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);

            // 计算所需纸张数量
            int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
            //单双面单价不一致
            Map<String, String> prices = kindValuePrice.get(material);
            if ("双面印刷".equals(dto.getCraftShua())) {
                basePrice = prices.get("2");
            } else {
                basePrice = prices.get("1");
            }
            price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);

            if ("刮刮卡".equals(kindValue)) {
                Map<String, Map<String, String>> ggmPrices = new HashMap<String, Map<String, String>>();
                ggmPrices.put("60*25", createPriceMap("50", "3", "100", "5"));
                ggmPrices.put("48*15", createPriceMap("50", "2", "100", "3"));
                ggmPrices.put("8*30", createPriceMap("50", "1", "100", "2"));
                ggmPrices.put("6*22", createPriceMap("50", "0.8", "100", "1.6"));
                if (!ggmPrices.containsKey(ggSize)) {
                    return new PricingListVo(100, "无该尺寸刮刮膜"); // 返回空列表表示不适用
                }
                Map<String, String> ggmPrice = ggmPrices.get(ggSize);
                if (count <= 50) {
                    price = price.add(new BigDecimal(ggmPrice.get("50"))).setScale(2, RoundingMode.HALF_UP);
                } else {
                    price = price.add(new BigDecimal(ggmPrice.get("100"))).setScale(2, RoundingMode.HALF_UP);
                }
            }
        }
        if ("即客".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
            if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
                return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
            }

            Map<String, Map<String, String>> kindValuePrice = new HashMap<>();

            // 统一键的类型为字符串
            kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
            kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
            kindValuePrice.put("萱姿", createPriceMap("1", "3", "2", "3"));//雅柔
            kindValuePrice.put("芳怡", createPriceMap("1", "3", "2", "3"));//草香
            if (!kindValuePrice.containsKey(material)) {
                return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
            }
            // 检查是否超出纸张尺寸限制
            if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
                return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
            }

            // 计算一张纸能容纳的最大金属标数量
            double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);

            // 计算所需纸张数量
            int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
            //单双面单价不一致
            Map<String, String> prices = kindValuePrice.get(material);
            if ("双面印刷".equals(dto.getCraftShua())) {
                basePrice = prices.get("2");
            } else {
                basePrice = prices.get("1");
            }
            price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);

            if ("刮刮卡".equals(kindValue)) {
                Map<String, Map<String, String>> ggmPrices = new HashMap<String, Map<String, String>>();
                ggmPrices.put("60*25", createPriceMap("50", "3", "100", "6"));
                ggmPrices.put("48*15", createPriceMap("50", "2", "100", "4"));
                ggmPrices.put("8*30", createPriceMap("50", "1", "100", "2"));
                ggmPrices.put("6*22", createPriceMap("50", "0.8", "100", "1.6"));
                if (!ggmPrices.containsKey(ggSize)) {
                    return new PricingListVo(100, "无该尺寸刮刮膜"); // 返回空列表表示不适用
                }
                Map<String, String> ggmPrice = ggmPrices.get(ggSize);
                if (count <= 50) {
                    price = price.add(new BigDecimal(ggmPrice.get("50"))).setScale(2, RoundingMode.HALF_UP);
                } else {
                    price = price.add(new BigDecimal(ggmPrice.get("100"))).setScale(2, RoundingMode.HALF_UP);
                }
            }
        }
        if ("欣海信".equals(plantName) && !"种子纸".equals(kindValue)) {
            paperLength = 272; // 纸张长度
            paperWidth = 390;  // 纸张宽度
            Map<String, Map<String, String>> kindValuePrice = new HashMap<>();

            // 统一键的类型为字符串
            kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
            kindValuePrice.put("pvc", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
            kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
            kindValuePrice.put("溪雪", createPriceMap("1", "4", "2", "6"));//珠光
            kindValuePrice.put("琮纹", createPriceMap("1", "4", "2", "6"));//刚古
            kindValuePrice.put("睿狐", createPriceMap("1", "4", "2", "6"));//莱尼
            kindValuePrice.put("玉蕊", createPriceMap("1", "4", "2", "6"));//蛋壳
            if (!kindValuePrice.containsKey(material)) {
                return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
            }
            // 检查是否超出纸张尺寸限制
            if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
                return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
            }

            // 计算一张纸能容纳的最大金属标数量
            double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);

            // 计算所需纸张数量
            int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
            //单双面单价不一致
            Map<String, String> prices = kindValuePrice.get(material);
            if ("双面印刷".equals(dto.getCraftShua())) {
                basePrice = prices.get("2");
                if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
                    basePrice = new BigDecimal(basePrice).add(new BigDecimal(prices.get("18"))).setScale(2, RoundingMode.HALF_UP).toString();
                }
            } else {
                basePrice = prices.get("1");
                if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
                    basePrice = new BigDecimal(basePrice).add(new BigDecimal(prices.get("9"))).setScale(2, RoundingMode.HALF_UP).toString();
                }
            }
            price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);

            if ("刮刮卡".equals(kindValue)) {
                price = price.add(new BigDecimal(0.3).multiply(new BigDecimal(count))).setScale(2, RoundingMode.HALF_UP);
            }
        }
        if ("彩印通".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
            paperLength = 297;
            paperWidth = 420;
            if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
                return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
            }
            Map<String, Map<String, String>> kindValuePrice = new HashMap<>();

            // 统一键的类型为字符串
            kindValuePrice.put("1", createPriceMap("1", "2.5", "2", "3"));//300g铜版纸
            kindValuePrice.put("芳怡", createPriceMap("1", "5.5", "2", "5.5"));//草香
            kindValuePrice.put("溪雪", createPriceMap("1", "3.5", "2", "3.5"));//珠光
            kindValuePrice.put("萱姿", createPriceMap("1", "5", "2", "5"));//雅柔
            if (!kindValuePrice.containsKey(material)) {
                return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
            }
            // 检查是否超出纸张尺寸限制
            if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
                return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
            }

            // 计算一张纸能容纳的最大金属标数量
            double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);

            // 计算所需纸张数量
            int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
            //单双面单价不一致
            Map<String, String> prices = kindValuePrice.get(material);
            if ("双面印刷".equals(dto.getCraftShua())) {
                basePrice = prices.get("2");
            } else {
                basePrice = prices.get("1");
            }
            if (craft_list.contains("异形")) {
                basePrice = new BigDecimal(basePrice).add(new BigDecimal("0.5")).setScale(2, RoundingMode.HALF_UP).toString();
            }
            price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);

            if ("刮刮卡".equals(kindValue)) {
                BigDecimal ggPrice = new BigDecimal("0.02").multiply(new BigDecimal(count));
                price = price.add(ggPrice.compareTo(new BigDecimal("30")) > 0 ? ggPrice : new BigDecimal("30")).setScale(2, RoundingMode.HALF_UP);
            }
        }
        if ("种子纸".equals(kindValue) && "鸿晟".equals(plantName)) {
            if (!StringUtils.isEmpty(dto.getSwitchz3Size()) || "2".equals(dto.getZ3type())) {
                count = Math.max(count, 300);
            }
            price = BigDecimal.valueOf((length * width * count * 70) / 1000000).setScale(2, RoundingMode.HALF_UP);//价格计算尺寸*数量*200/10000

            if (craft_list.contains("编码")) {//起步价10
                price = price.add(max(new BigDecimal(count * 0.4), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("打孔")) {
                price = price.add(max(new BigDecimal(count * 0.1), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("手撕线")) {
                price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("压痕")) {
                price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            price = price.multiply(new BigDecimal(number));//款数翻倍
            price = max(price, new BigDecimal(80)).setScale(2, RoundingMode.HALF_UP);

            if (!StringUtils.isEmpty(dto.getSwitchz3Size())) {
                price = price.add(new BigDecimal(100)).add(new BigDecimal(count * 0.1)).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.size() > 0 && craft_list.contains("绳子")) {
                price = price.add(max(new BigDecimal(0.1 * number * count), new BigDecimal(5))).setScale(2, RoundingMode.HALF_UP);
            }
        }
        if ("种子纸".equals(kindValue) && "驰远".equals(plantName)) {
            if (!StringUtils.isEmpty(dto.getSwitchz3Size()) || "2".equals(dto.getZ3type())) {
                count = Math.max(count, 300);
            }
            basePrice = "45";
            if (!StringUtils.isEmpty(dto.getSwitchz3Size())) {
                basePrice = "65";
                if (length > 12 || width > 12) {
                    return new PricingListVo(100, "纸张尺寸超出");
                }
            }
            price = BigDecimal.valueOf((length * width * count) / 1000000).multiply(new BigDecimal(basePrice)).setScale(2, RoundingMode.HALF_UP);//价格计算尺寸*数量*200/10000

            if (craft_list.contains("编码")) {//起步价10
                price = price.add(max(new BigDecimal(count * 0.4), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("打孔")) {
                price = price.add(max(new BigDecimal(count * 0.1), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("手撕线")) {
                price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            if (craft_list.contains("压痕")) {
                price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
            }
            price = price.multiply(new BigDecimal(number));//款数翻倍
            price = max(price, new BigDecimal(80)).setScale(2, RoundingMode.HALF_UP);


            if (craft_list.size() > 0 && craft_list.contains("绳子")) {
                price = price.add(max(new BigDecimal(0.1 * number * count), new BigDecimal(5))).setScale(2, RoundingMode.HALF_UP);
            }
        }
        weight = BigDecimal.valueOf(number * (length) / 1000 * (width) / 1000 * count * 0.25 * 1.15);
        // 创建产品对象并添加到结果列表
        ProductVo pro = new ProductVo();
        pro.setPrice(price.doubleValue());
        pro.setCount(count);
        pro.setWeight(weight.toString());
        resultList.add(pro);
        return new PricingListVo(resultList);
    }

    public static BigDecimal max(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.compareTo(b) >= 0 ? a : b;
    }

    /**
     * 创建价格映射
     *
     * @param keysAndValues 键值对数组
     * @return 初始化后的价格映射
     */
    private Map<String, String> createPriceMap(String... keysAndValues) {
        if (keysAndValues.length % 2 != 0) {
            throw new IllegalArgumentException("键值对数量必须为偶数");
        }
        Map<String, String> priceMap = new HashMap<>();
        for (int i = 0; i < keysAndValues.length; i += 2) {
            priceMap.put(keysAndValues[i], keysAndValues[i + 1]);
        }
        return priceMap;
    }

    /**
     * 将给定的尺寸转换为毫米，并在每边增加3毫米的边距
     *
     * @param size 需要转换的原始尺寸
     * @return 转换后的尺寸，单位为毫米，包括边距
     */
    private double convertToMillimetersWithMargin(double size) {
        return size * 10 + 2 * 2; // 换成毫米，每边+2
    }

    /**
     * 检查给定的长度和宽度是否在纸张尺寸范围内
     *
     * @param length      需要检查的长度
     * @param width       需要检查的宽度
     * @param paperLength 纸张的长度
     * @param paperWidth  纸张的宽度
     * @return 如果给定尺寸在纸张尺寸范围内，则返回true；否则返回false
     */
    private boolean isWithinPaperSize(double length, double width, double paperLength, double paperWidth) {
        return (length <= paperLength && width <= paperWidth) || (length <= paperWidth && width <= paperLength);
    }

    /**
     * 计算每张纸最多可以容纳的物品数量
     *
     * @param length      物品的长度
     * @param width       物品的宽度
     * @param paperLength 纸张的长度
     * @param paperWidth  纸张的宽度
     * @return 每张纸最多可以容纳的物品数量
     */
    private double calculateMaxItemsPerSheet(double length, double width, double paperLength, double paperWidth) {
        return Math.max(
                Math.floor(paperLength / length) * Math.floor(paperWidth / width),
                Math.floor(paperLength / width) * Math.floor(paperWidth / length)
        );
    }

    /**
     * 计算完成指定数量的物品所需的纸张数量
     *
     * @param count            物品的总数量
     * @param number           每个物品需要的数量
     * @param maxItemsPerSheet 每张纸最多可以容纳的物品数量
     * @return 完成指定数量的物品所需的纸张数量
     */
    private int calculateRequiredSheets(int count, int number, double maxItemsPerSheet) {
        return (int) Math.ceil((count * number) / maxItemsPerSheet);
    }
}
