package com.czg.order.entity;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.czg.order.dto.LimitRateDTO;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;

import java.io.Serial;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 订单表 实体类。
 *
 * @author ww
 * @since 2025-02-13
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("tb_order_info")
@Accessors(chain = true)
public class OrderInfo implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    @Id(keyType = KeyType.Auto)
    private Long id;

    /**
     * 订单编号
     * pc 收银机客户端  PC+雪花ID
     * wechat 微信小程序 WX+雪花ID
     * alipay 支付宝小程序 ALI+雪花ID
     * admin-pc PC管理端 WEB+雪花ID
     * admin-app APP管理端 APP+雪花ID
     */
    private String orderNo;

    /**
     * 店铺Id
     */
    private Long shopId;

    /**
     * 用户Id user_info表的id
     */
    private Long userId;

    /**
     * 退单金额
     */
    private BigDecimal refundAmount;

    /**
     * 订单原金额 不含折扣价格
     */
    private BigDecimal originAmount;
    /**
     * 抹零金额 减免多少钱
     */
    private BigDecimal roundAmount;

    /**
     * 订单金额 (扣除各类折扣)
     */
    private BigDecimal orderAmount;
    /**
     * 优惠总金额
     */
    private BigDecimal discountAllAmount;

    /**
     * 实际支付金额
     */
    private BigDecimal payAmount;

    /**
     * 积分抵扣金额
     */
    private BigDecimal pointsDiscountAmount;

    /**
     * 使用的积分数量
     */
    private Integer pointsNum;

    /**
     * 新客立减金额
     */
    private BigDecimal newCustomerDiscountAmount;

    /**
     * 商品优惠券抵扣金额
     */
    private BigDecimal productCouponDiscountAmount;

    /**
     * 用户使用的卡券
     */
    private String couponInfoList;

    /**
     * 满减活动抵扣金额
     */
    private BigDecimal discountActAmount;
    /**
     * 其它优惠券抵扣金额
     */
    private BigDecimal otherCouponDiscountAmount;
    /**
     * 会员折扣金额
     */
    private BigDecimal vipDiscountAmount;

    /**
     * 折扣金额
     */
    private BigDecimal discountAmount;

//    /**
//     * 折扣比例
//     */
//    private BigDecimal discountRatio;

    /**
     * 打包费
     */
    private BigDecimal packFee;

    /**
     * 台桌Id
     */
    private String tableCode;

    /**
     * 台桌名称
     */
    private String tableName;
    /**
     * 退款方式 现金退款-cash 原路退回-payBack
     */
    private String refundType;

    /**
     * 订单类型-
     * cash收银(除小程序以外 都属于收银)
     * miniapp小程序
     */
    private String orderType;

    /**
     * 平台类型  pc 收银机客户端 wechat 微信小程序 alipay 支付宝小程序 admin-pc PC管理端 admin-app APP管理端
     */
    private String platformType;

    /**
     * 用餐模式 堂食 dine-in  外带 take-out 外卖 take-away
     */
    private String dineMode;

    /**
     * 支付模式:
     * 后付费 after-pay
     * 先付费 before-pay
     * 无桌码 no-table
     */
    private String payMode;

    /**
     * {@link com.czg.order.enums.PayEnums}
     * 支付类型
     * 二维码收款 main_scan
     * 扫码收款 back_scan
     * 微信小程序 wechat_mini
     * 支付宝小程序 alipay_mini
     * 会员支付 vip_pay
     * 现金支付 cash_pay
     * 挂账支付 credit_pay
     * 霸王餐支付 free_pay
     */
    private String payType;

    /**
     * {@link com.czg.service.order.enums.OrderStatusEnums}
     * 状态: unpaid-待支付;in-production 制作中;wait_out 待取餐;;done-订单完成;refunding-申请退单;refund-退单;part_refund 部分退单;cancelled-取消订单
     */
    private String status;

    /**
     * 折扣信息 json
     */
    private String discountInfo;
    /**
     * 限时折扣信息 json
     */
    private String limitRateJson;
    /**
     * 限时折扣信息 json
     */
    @Column(ignore = true)
    private LimitRateDTO limitRate;

    /**
     * 是否支持退款，1支持退单， 0不支持退单
     */
    private Integer refundAble;

    /**
     * 支付时间
     */
    private LocalDateTime paidTime;

    @Column(onInsertValue = "now()")
    private LocalDateTime createTime;

    @Column(onInsertValue = "now()", onUpdateValue = "now()")
    private LocalDateTime updateTime;

    /**
     * 支付订单号
     * tb_order_payment.id
     * tb_shop_user_flow.id
     */
    private Long payOrderId;

    /**
     * 交易日期
     */
    private String tradeDay;

    /**
     * 备注
     */
    private String remark;

    /**
     * 取餐码
     */
    private String takeCode;

    /**
     * 员工id
     */
    private Long staffId;

    /**
     * 当前订单下单次数
     */
    private Integer placeNum;

    /**
     * 用餐人数
     */
    private Integer seatNum;

    /**
     * 餐位费
     */
    private BigDecimal seatAmount;

    /**
     * 退款备注
     */
    private String refundRemark;

    /**
     * 是否使用了霸王餐
     */
    private Integer isFreeDine;
    /**
     * 是否打票
     */
    private Integer isPrint;

    /**
     * 是否等叫 0 否 1 等叫
     */
    private Integer isWaitCall;

    /**
     * 挂账人id
     */
    private Long creditBuyerId;

    /**
     * 是否回收站 0-否，1回收站
     */
    private Integer isDel;

    private String failMsg;
    /**
     * 打印状态 Json格式
     */
    private String printStatus;


    public String getRefundRemark() {
        return StrUtil.isBlank(refundRemark) ? "" : refundRemark + " ";
    }

//    public BigDecimal getNewCustomerDiscountAmount() {
//        return newCustomerDiscountAmount == null ? BigDecimal.ZERO : newCustomerDiscountAmount;
//    }
//
//    public BigDecimal getVipDiscountAmount() {
//        return vipDiscountAmount == null ? BigDecimal.ZERO : vipDiscountAmount;
//    }
//
//    public BigDecimal getOriginAmount() {
//        return originAmount == null ? BigDecimal.ZERO : originAmount;
//    }
//
//    public BigDecimal getSeatAmount() {
//        return seatAmount == null ? BigDecimal.ZERO : seatAmount;
//    }
//
//    public BigDecimal getPackFee() {
//        return packFee == null ? BigDecimal.ZERO : packFee;
//    }


    /**
     * 计算并设置所有优惠金额的总和
     */
    public void initDiscountAllAmount() {
        this.discountAllAmount = BigDecimal.ZERO
                .add(this.getProductCouponDiscountAmount() != null ? this.getProductCouponDiscountAmount() : BigDecimal.ZERO)
                .add(this.getOtherCouponDiscountAmount() != null ? this.getOtherCouponDiscountAmount() : BigDecimal.ZERO)
                .add(this.getPointsDiscountAmount() != null ? this.getPointsDiscountAmount() : BigDecimal.ZERO)
                .add(this.getNewCustomerDiscountAmount() != null ? this.getNewCustomerDiscountAmount() : BigDecimal.ZERO)
                .add(this.getDiscountAmount() != null ? this.getDiscountAmount() : BigDecimal.ZERO)
                .add(this.getDiscountActAmount() != null ? this.getDiscountActAmount() : BigDecimal.ZERO)
                .add(this.getVipDiscountAmount() != null ? this.getVipDiscountAmount() : BigDecimal.ZERO);
        // 如果需要加上抹零金额，可以取消下面这行注释
        // .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO);
    }

    private JSONArray getPrintStatusAsArray() {
        if (StrUtil.isBlank(printStatus)) {
            return new JSONArray();
        }
        try {
            return JSONArray.parseArray(printStatus.trim());
        } catch (Exception e) {
            return new JSONArray();
        }
    }

    public void upPrintStatus(JSONObject printJson, boolean isPrintSuccess) {
        String currentDeviceId = printJson.getString("id");
        JSONArray oldPrintStatusArray = getPrintStatusAsArray();
        // 3. 初始化新的打印状态JSON数组（用于存储处理后的结果）
        JSONArray newPrintStatusArray = new JSONArray();
        // 场景1：打印成功 - 移除原有数组中与当前设备ID一致的记录，保留其余记录
        if (oldPrintStatusArray != null && !oldPrintStatusArray.isEmpty()) {
            for (int i = 0; i < oldPrintStatusArray.size(); i++) {
                JSONObject deviceObj = oldPrintStatusArray.getJSONObject(i);
                String deviceId = deviceObj.getString("id");
                // 仅保留非当前设备ID的记录
                if (currentDeviceId != null && !currentDeviceId.equals(deviceId)) {
                    newPrintStatusArray.add(deviceObj);
                }
            }
        }
        if (!isPrintSuccess) {
            newPrintStatusArray.add(printJson);
        }
        if (!newPrintStatusArray.isEmpty()) {
            printStatus = newPrintStatusArray.toJSONString();
        } else {
            printStatus = "";
        }
    }
}
