package com.starry.admin.modules.order.module.constant;

import lombok.Getter;

/**
 * 订单相关枚举和常量
 *
 * @author admin
 * @since 2024/5/8 15:41
 */
public class OrderConstant {

    /**
     * 订单状态枚举
     */
    @Getter
    public enum OrderStatus {
        PENDING("0", "已下单（待接单）"),
        ACCEPTED("1", "已接单（待开始）"),
        IN_PROGRESS("2", "已开始（服务中）"),
        COMPLETED("3", "已完成"),
        CANCELLED("4", "已取消"),
        REVOKED("5", "已撤销");

        private final String code;
        private final String description;

        OrderStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static OrderStatus fromCode(String code) {
            for (OrderStatus status : values()) {
                if (status.code.equals(code)) {
                    return status;
                }
            }
            throw new IllegalArgumentException("Unknown order status code: " + code);
        }
    }

    /**
     * 订单类型枚举
     */
    @Getter
    public enum OrderType {
        REFUND("-1", "退款订单"),
        RECHARGE("0", "充值订单"),
        WITHDRAWAL("1", "提现订单"),
        NORMAL("2", "普通订单"),
        GIFT("3", "礼物订单"),
        BLIND_BOX_PURCHASE("4", "盲盒购买订单");

        private final String code;
        private final String description;

        OrderType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static OrderType fromCode(String code) {
            for (OrderType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown order type code: " + code);
        }
    }

    @Getter
    public enum PaymentSource {
        BALANCE("BALANCE", "余额扣款"),
        WX_PAY("WX_PAY", "微信支付"),
        ALI_PAY("ALI_PAY", "支付宝支付"),
        BLIND_BOX("BLIND_BOX", "盲盒奖励抵扣");

        private final String code;
        private final String description;

        PaymentSource(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static PaymentSource fromCode(String code) {
            for (PaymentSource source : values()) {
                if (source.code.equals(code)) {
                    return source;
                }
            }
            throw new IllegalArgumentException("Unknown payment source code: " + code);
        }
    }

    /**
     * 下单类型枚举
     */
    @Getter
    public enum PlaceType {
        OTHER("-1", "其他类型"),
        SPECIFIED("0", "指定单"),
        RANDOM("1", "随机单"),
        REWARD("2", "打赏单");

        private final String code;
        private final String description;

        PlaceType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static PlaceType fromCode(String code) {
            for (PlaceType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown place type code: " + code);
        }
    }

    /**
     * 性别枚举
     */
    @Getter
    public enum Gender {
        UNKNOWN("0", "未知"),
        MALE("1", "男"),
        FEMALE("2", "女");

        private final String code;
        private final String description;

        Gender(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static Gender fromCode(String code) {
            for (Gender gender : values()) {
                if (gender.code.equals(code)) {
                    return gender;
                }
            }
            throw new IllegalArgumentException("Unknown gender code: " + code);
        }
    }

    /**
     * 打赏类型枚举
     */
    @Getter
    public enum RewardType {
        NOT_APPLICABLE("", "非打赏订单"),
        BALANCE("0", "余额打赏"),
        GIFT("1", "礼物打赏");

        private final String code;
        private final String description;

        RewardType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static RewardType fromCode(String code) {
            // Handle null, empty string, or whitespace as NOT_APPLICABLE
            if (code == null || code.trim().isEmpty()) {
                return NOT_APPLICABLE;
            }

            for (RewardType type : values()) {
                if (code.equals(type.code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown reward type code: " + code);
        }
    }

    /**
     * 商品类型枚举
     */
    @Getter
    public enum CommodityType {
        GIFT("0", "礼物"),
        SERVICE("1", "服务");

        private final String code;
        private final String description;

        CommodityType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static CommodityType fromCode(String code) {
            for (CommodityType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown commodity type code: " + code);
        }
    }

    /**
     * 操作人类型枚举
     */
    @Getter
    public enum OperatorType {
        CUSTOMER("0", "顾客"),
        CLERK("1", "店员"),
        ADMIN("2", "管理员"),
        GROUP_LEADER("3", "组长");

        private final String code;
        private final String description;

        OperatorType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public static OperatorType fromCode(String code) {
            for (OperatorType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown operator type code: " + code);
        }
    }

    @Getter
    public enum OrderActor {
        CUSTOMER,
        CLERK,
        GROUP_LEADER,
        ADMIN,
        SYSTEM;
    }

    // 排除历史记录常量
    public static final String EXCLUDE_HISTORY_NO = "0";
    public static final String EXCLUDE_HISTORY_YES = "1";

    @Getter
    public enum OrderRefundFlag {
        NOT_REFUNDED("0"),
        REFUNDED("1");

        private final String code;

        OrderRefundFlag(String code) {
            this.code = code;
        }

        public static OrderRefundFlag fromCode(String code) {
            for (OrderRefundFlag flag : values()) {
                if (flag.code.equals(code)) {
                    return flag;
                }
            }
            throw new IllegalArgumentException("Unknown order refund flag code: " + code);
        }
    }

    @Getter
    public enum OrderRefundRecordType {
        FULL("0"),
        PARTIAL("1");

        private final String code;

        OrderRefundRecordType(String code) {
            this.code = code;
        }

        public static OrderRefundRecordType fromCode(String code) {
            for (OrderRefundRecordType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown refund record type code: " + code);
        }
    }

    @Getter
    public enum OrderRefundState {
        PROCESSING("0"),
        SUCCESS("1"),
        CLOSED("2"),
        ABNORMAL("-1");

        private final String code;

        OrderRefundState(String code) {
            this.code = code;
        }

        public static OrderRefundState fromCode(String code) {
            for (OrderRefundState state : values()) {
                if (state.code.equals(code)) {
                    return state;
                }
            }
            throw new IllegalArgumentException("Unknown refund state code: " + code);
        }
    }

    @Getter
    public enum ReviewRequirement {
        NOT_REQUIRED("0"),
        REQUIRED("1");

        private final String code;

        ReviewRequirement(String code) {
            this.code = code;
        }

        public static ReviewRequirement fromCode(String code) {
            for (ReviewRequirement requirement : values()) {
                if (requirement.code.equals(code)) {
                    return requirement;
                }
            }
            throw new IllegalArgumentException("Unknown review requirement code: " + code);
        }
    }

    @Getter
    public enum BalanceOperationType {
        RECHARGE("0"),
        CONSUME("1"),
        SERVICE("2"),
        REFUND("3");

        private final String code;

        BalanceOperationType(String code) {
            this.code = code;
        }

        public static BalanceOperationType fromCode(String code) {
            for (BalanceOperationType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Unknown balance operation type code: " + code);
        }
    }

    @Getter
    public enum YesNoFlag {
        NO("0"),
        YES("1");

        private final String code;

        YesNoFlag(String code) {
            this.code = code;
        }

        public static YesNoFlag fromCode(String code) {
            for (YesNoFlag flag : values()) {
                if (flag.code.equals(code)) {
                    return flag;
                }
            }
            throw new IllegalArgumentException("Unknown yes/no flag code: " + code);
        }
    }

    @Getter
    public enum OrderSettlementState {
        NOT_SETTLED("0"),
        SETTLED("1");

        private final String code;

        OrderSettlementState(String code) {
            this.code = code;
        }

        public static OrderSettlementState fromCode(String code) {
            for (OrderSettlementState state : values()) {
                if (state.code.equals(code)) {
                    return state;
                }
            }
            throw new IllegalArgumentException("Unknown settlement state code: " + code);
        }
    }

    @Getter
    public enum OrdersExpiredState {
        NOT_EXPIRED("0"),
        EXPIRED("1");

        private final String code;

        OrdersExpiredState(String code) {
            this.code = code;
        }

        public static OrdersExpiredState fromCode(String code) {
                for (OrdersExpiredState state : values()) {
                    if (state.code.equals(code)) {
                        return state;
                    }
                }
                throw new IllegalArgumentException("Unknown orders expired state code: " + code);
        }
    }

    @Getter
    public enum PayMethod {
        BALANCE("0"),
        WECHAT("1"),
        ALIPAY("2"),
        BANK_CARD("3"),
        OTHER("4");

        private final String code;

        PayMethod(String code) {
            this.code = code;
        }

        public static PayMethod fromCode(String code) {
            for (PayMethod method : values()) {
                if (method.code.equals(code)) {
                    return method;
                }
            }
            throw new IllegalArgumentException("Unknown pay method code: " + code);
        }
    }


    @Getter
    public enum OrderTriggerSource {
        /**
         * 未标记来源的兜底，通常用于兼容历史数据
         */
        UNKNOWN("unknown"),
        /**
         * 运营或客服后台人工处理触发
         */
        MANUAL("manual"),
        /**
         * 微信顾客端（小程序/公众号）下单触发
         */
        WX_CUSTOMER("wx_customer"),
        /**
         * 微信店员端操作触发
         */
        WX_CLERK("wx_clerk"),
        /**
         * 微信店员端管理能力触发（组长/运营）
         */
        WX_CLERK_MGMT("wx_clerk_mgmt"),
        /**
         * 管理后台控制台界面发起
         */
        ADMIN_CONSOLE("admin_console"),
        /**
         * 管理后台开放接口调用
         */
        ADMIN_API("admin_api"),
        /**
         * 打赏单自动生成的订单流程
         */
        REWARD_ORDER("reward_order"),
        /**
         * 定时任务/调度器触发
         */
        SCHEDULER("scheduler"),
        /**
         * 平台内部系统逻辑触发
         */
        SYSTEM("system");

        private final String code;

        OrderTriggerSource(String code) {
            this.code = code;
        }

        public static OrderTriggerSource fromCode(String code) {
            for (OrderTriggerSource source : values()) {
                if (source.code.equals(code)) {
                    return source;
                }
            }
            throw new IllegalArgumentException("Unknown order trigger source code: " + code);
        }
    }

}
