package cn.nianxx.thhotel.workflows.reservation.common.enums;

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * M002 V3 SuperAgent P0 路由定义。每条记录对应一条稳定三元组或入口通知路由。
 */
public enum ReservationAiRouteDefinition {
    NEW_FIT_RESERVATION_NORMAL(
            "R01_NEW_FIT_RESERVATION_NORMAL",
            "normal_task",
            "New Booking",
            "new_fit_reservation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    NEW_FIT_RESERVATION_REVIEW(
            "R01_NEW_FIT_RESERVATION_REVIEW",
            "manual_review",
            "New Booking",
            "new_fit_reservation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    NEW_GROUP_BLOCK_NORMAL(
            "R02_NEW_GROUP_BLOCK_NORMAL",
            "normal_task",
            "New Booking",
            "new_group_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    NEW_GROUP_BLOCK_REVIEW(
            "R02_NEW_GROUP_BLOCK_REVIEW",
            "manual_review",
            "New Booking",
            "new_group_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    NEW_ALLOTMENT_CONTROL_BLOCK_NORMAL(
            "R03_NEW_ALLOTMENT_CONTROL_BLOCK_NORMAL",
            "normal_task",
            "New Booking",
            "new_allotment_control_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    NEW_ALLOTMENT_CONTROL_BLOCK_REVIEW(
            "R03_NEW_ALLOTMENT_CONTROL_BLOCK_REVIEW",
            "manual_review",
            "New Booking",
            "new_allotment_control_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.NEW_BOOKING,
            ReservationTaskCardType.NEW_BOOKING),
    UPDATE_BOOKING_AMENDMENT_NORMAL(
            "R04_UPDATE_BOOKING_AMENDMENT_NORMAL",
            "normal_task",
            "Update Booking",
            "update_booking_amendment",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.UPDATE_BOOKING),
    UPDATE_BOOKING_AMENDMENT_REVIEW(
            "R04_UPDATE_BOOKING_AMENDMENT_REVIEW",
            "manual_review",
            "Update Booking",
            "update_booking_amendment",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.UPDATE_BOOKING),
    CANCEL_FIT_RESERVATION_NORMAL(
            "R05_CANCEL_FIT_RESERVATION_NORMAL",
            "normal_task",
            "Cancel Booking",
            "cancel_fit_reservation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_BOOKING),
    CANCEL_FIT_RESERVATION_REVIEW(
            "R05_CANCEL_FIT_RESERVATION_REVIEW",
            "manual_review",
            "Cancel Booking",
            "cancel_fit_reservation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_BOOKING),
    CANCEL_GROUP_BLOCK_NORMAL(
            "R06_CANCEL_GROUP_BLOCK_NORMAL",
            "normal_task",
            "Cancel Booking",
            "cancel_group_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_BOOKING),
    CANCEL_GROUP_BLOCK_REVIEW(
            "R06_CANCEL_GROUP_BLOCK_REVIEW",
            "manual_review",
            "Cancel Booking",
            "cancel_group_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_BOOKING),
    CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL(
            "R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL",
            "normal_task",
            "Cancel Allotment",
            "cancel_allotment_control_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_ALLOTMENT),
    CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW(
            "R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW",
            "manual_review",
            "Cancel Allotment",
            "cancel_allotment_control_block",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.CANCEL_BOOKING,
            ReservationTaskCardType.CANCEL_ALLOTMENT),
    LIAN_TAI_CREDIT_VOUCHER_NORMAL(
            "R09_LIAN_TAI_CREDIT_VOUCHER_NORMAL",
            "normal_task",
            "Voucher Received",
            "lian_tai_credit_voucher",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.VOUCHER_RECEIVED),
    LIAN_TAI_CREDIT_VOUCHER_REVIEW(
            "R09_LIAN_TAI_CREDIT_VOUCHER_REVIEW",
            "manual_review",
            "Voucher Received",
            "lian_tai_credit_voucher",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.VOUCHER_RECEIVED),
    PAYMENT_EVIDENCE_NORMAL(
            "R10_PAYMENT_EVIDENCE_NORMAL",
            "normal_task",
            "Payment Evidence",
            "payment_evidence",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.PAYMENT_EVIDENCE),
    PAYMENT_EVIDENCE_REVIEW(
            "R10_PAYMENT_EVIDENCE_REVIEW",
            "manual_review",
            "Payment Evidence",
            "payment_evidence",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.PAYMENT_EVIDENCE),
    ROOMING_LIST_NORMAL(
            "R11_ROOMING_LIST_NORMAL",
            "normal_task",
            "Rooming List",
            "rooming_list",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.ROOMING_LIST),
    ROOMING_LIST_REVIEW(
            "R11_ROOMING_LIST_REVIEW",
            "manual_review",
            "Rooming List",
            "rooming_list",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.ROOMING_LIST),
    AMEND_GROUP_CODE_NORMAL(
            "R12_AMEND_GROUP_CODE_NORMAL",
            "normal_task",
            "Amend Group Code",
            "amend_group_code",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.AMEND_GROUP_CODE),
    AMEND_GROUP_CODE_REVIEW(
            "R12_AMEND_GROUP_CODE_REVIEW",
            "manual_review",
            "Amend Group Code",
            "amend_group_code",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.AMEND_GROUP_CODE),
    EXTRA_BED_NORMAL(
            "R13_EXTRA_BED_NORMAL",
            "normal_task",
            "Trace / Reservation Notes",
            "extra_bed",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TRACE_RESERVATION_NOTES),
    EXTRA_BED_REVIEW(
            "R13_EXTRA_BED_REVIEW",
            "manual_review",
            "Trace / Reservation Notes",
            "extra_bed",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TRACE_RESERVATION_NOTES),
    GENERAL_REQUEST_NORMAL(
            "R14_GENERAL_REQUEST_NORMAL",
            "normal_task",
            "Trace / Reservation Notes",
            "general_request",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TRACE_RESERVATION_NOTES),
    GENERAL_REQUEST_REVIEW(
            "R14_GENERAL_REQUEST_REVIEW",
            "manual_review",
            "Trace / Reservation Notes",
            "general_request",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TRACE_RESERVATION_NOTES),
    MAINTAIN_TA_RECORDER_NORMAL(
            "R15_MAINTAIN_TA_RECORDER_NORMAL",
            "normal_task",
            "TA Recorder",
            "maintain_ta_recorder",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TA_RECORDER),
    MAINTAIN_TA_RECORDER_REVIEW(
            "R15_MAINTAIN_TA_RECORDER_REVIEW",
            "manual_review",
            "TA Recorder",
            "maintain_ta_recorder",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.TA_RECORDER),
    INVOICE_GENERATION_NORMAL(
            "R16_INVOICE_GENERATION_NORMAL",
            "normal_task",
            "Invoice Generation",
            "invoice_generation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.INVOICE_GENERATION),
    INVOICE_GENERATION_REVIEW(
            "R16_INVOICE_GENERATION_REVIEW",
            "manual_review",
            "Invoice Generation",
            "invoice_generation",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.INVOICE_GENERATION),
    INVOICE_RECEIVED_NORMAL(
            "R17_INVOICE_RECEIVED_NORMAL",
            "normal_task",
            "Invoice Received",
            "invoice_received",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.INVOICE_RECEIVED),
    INVOICE_RECEIVED_REVIEW(
            "R17_INVOICE_RECEIVED_REVIEW",
            "manual_review",
            "Invoice Received",
            "invoice_received",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.INVOICE_RECEIVED),
    PAYMENT_NOTICE_NORMAL(
            "R18_PAYMENT_NOTICE_NORMAL",
            "normal_task",
            "Payment Notice",
            "payment_notice",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.PAYMENT_NOTICE),
    PAYMENT_NOTICE_REVIEW(
            "R18_PAYMENT_NOTICE_REVIEW",
            "manual_review",
            "Payment Notice",
            "payment_notice",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.PAYMENT_NOTICE),
    MANUAL_RATE_CODE_NORMAL(
            "R19_MANUAL_RATE_CODE_NORMAL",
            "normal_task",
            "Manual RateCode",
            "manual_rate_code",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.MANUAL_RATE_CODE),
    MANUAL_RATE_CODE_REVIEW(
            "R19_MANUAL_RATE_CODE_REVIEW",
            "manual_review",
            "Manual RateCode",
            "manual_rate_code",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.UPDATE_BOOKING,
            ReservationTaskCardType.MANUAL_RATE_CODE),
    SOURCE_MESSAGE_S10(
            "S10",
            "source_message_review_notification",
            "Message Notification",
            "S10",
            ReservationAiSystemProcessCategory.SOURCE_MESSAGE_NOTIFICATION,
            ReservationSystemTaskType.SOURCE_MESSAGE_ONLY,
            ReservationTaskCardType.SOURCE_MESSAGE_ONLY),
    SOURCE_MESSAGE_S99(
            "S99",
            "source_message_review_notification",
            "Message Notification",
            "S99",
            ReservationAiSystemProcessCategory.SOURCE_MESSAGE_NOTIFICATION,
            ReservationSystemTaskType.SOURCE_MESSAGE_ONLY,
            ReservationTaskCardType.SOURCE_MESSAGE_ONLY),
    FALLBACK_BUSINESS_EVENT_REVIEW(
            "R41_FALLBACK_BUSINESS_EVENT_REVIEW",
            "manual_review",
            "Fallback",
            "business_event_review",
            ReservationAiSystemProcessCategory.BUSINESS_TASK,
            ReservationSystemTaskType.MANUAL_REVIEW,
            ReservationTaskCardType.FALLBACK_REVIEW),
    UNHANDLED_CURRENT_INTENT(
            "R42_UNHANDLED_CURRENT_INTENT",
            "unhandled_current_intent",
            "Unhandled Current Intent",
            "requires_business_approval_or_unsupported_task_card",
            ReservationAiSystemProcessCategory.UNHANDLED_CURRENT_INTENT,
            ReservationSystemTaskType.SOURCE_MESSAGE_ONLY,
            ReservationTaskCardType.SOURCE_MESSAGE_ONLY);

    private static final Map<String, ReservationAiRouteDefinition> BY_TRIPLET = Arrays.stream(values())
            .collect(Collectors.toUnmodifiableMap(
                    route -> routeKey(route.resultType, route.taskType, route.taskSubtype),
                    Function.identity()));

    private static final Map<String, ReservationAiRouteDefinition> BY_ROUTE_CODE = Arrays.stream(values())
            .collect(Collectors.toUnmodifiableMap(ReservationAiRouteDefinition::routeCode, Function.identity()));

    private final String routeCode;
    private final String resultType;
    private final String taskType;
    private final String taskSubtype;
    private final ReservationAiSystemProcessCategory systemProcessCategory;
    private final ReservationSystemTaskType systemTaskType;
    private final ReservationTaskCardType taskCardType;

    ReservationAiRouteDefinition(
            String routeCode,
            String resultType,
            String taskType,
            String taskSubtype,
            ReservationAiSystemProcessCategory systemProcessCategory,
            ReservationSystemTaskType systemTaskType,
            ReservationTaskCardType taskCardType) {
        this.routeCode = routeCode;
        this.resultType = resultType;
        this.taskType = taskType;
        this.taskSubtype = taskSubtype;
        this.systemProcessCategory = systemProcessCategory;
        this.systemTaskType = systemTaskType;
        this.taskCardType = taskCardType;
    }

    public String routeCode() {
        return routeCode;
    }

    public String resultType() {
        return resultType;
    }

    public String taskType() {
        return taskType;
    }

    public String taskSubtype() {
        return taskSubtype;
    }

    public ReservationAiSystemProcessCategory systemProcessCategory() {
        return systemProcessCategory;
    }

    public ReservationSystemTaskType systemTaskType() {
        return systemTaskType;
    }

    public ReservationTaskCardType taskCardType() {
        return taskCardType;
    }

    /**
     * 按 AI 三元组查找路由定义，大小写敏感，避免外部值被误归类。
     */
    public static Optional<ReservationAiRouteDefinition> findByTriplet(
            String resultType,
            String taskType,
            String taskSubtype) {
        return Optional.ofNullable(BY_TRIPLET.get(routeKey(resultType, taskType, taskSubtype)));
    }

    /**
     * 按 route_code 查找路由定义，主要用于 S10/S99 和内部生成的稳定路由码。
     */
    public static Optional<ReservationAiRouteDefinition> findByRouteCode(String routeCode) {
        return Optional.ofNullable(BY_ROUTE_CODE.get(routeCode));
    }

    /**
     * 判断当前路由是否为只读来源邮件通知。
     */
    public boolean sourceMessageNotification() {
        return systemProcessCategory == ReservationAiSystemProcessCategory.SOURCE_MESSAGE_NOTIFICATION;
    }

    /**
     * 判断当前路由是否会进入业务任务模型。
     */
    public boolean businessTask() {
        return systemProcessCategory == ReservationAiSystemProcessCategory.BUSINESS_TASK;
    }

    private static String routeKey(String resultType, String taskType, String taskSubtype) {
        return nullToEmpty(resultType) + "|" + nullToEmpty(taskType) + "|" + nullToEmpty(taskSubtype);
    }

    private static String nullToEmpty(String value) {
        return value == null ? "" : value;
    }
}
