package com.unibuy.smartdevice.structure.mqtt;

import java.util.List;

/**
 * MQTT Finalize 交易結案訊息的資料結構。
 * 對應後台 machine/[ID]/transaction Topic 的 payload 格式。
 *
 * 此訊息在 App 端完成所有本地動作（支付 + 出貨）後，統一發送一次。
 * 取代原本的分段式 HTTP 上報 (B600/B601/B602)。
 */
public class TransactionFinalizePayload {

    /** 固定為 "finalize" */
    private final String action = "finalize";

    /** 機台流水號（由 reportFlowId 填入，若無則以 order_no 代替） */
    private String flow_id;

    /**
     * 特定交易的資料庫原始 ID。
     * B660(取貨碼) / B670(通行碼) / B680(員工卡) 驗證成功後，後台返回的 ID。
     * 一般現金/電子支付交易此欄位填 0。
     */
    private String code_id;

    /**
     * 支付類型 (Root 級別，用於後端快速判斷)
     */
    private int payment_type;

    /** 訂單資訊 */
    private OrderPayload order;

    /** 每個貨道的出貨結果列表 */
    private List<DispenseRecord> dispense;

    // =========== Getters & Setters ===========

    public String getAction() {
        return action;
    }

    public String getFlow_id() {
        return flow_id;
    }

    public void setFlow_id(String flow_id) {
        this.flow_id = flow_id;
    }

    public String getCode_id() {
        return code_id;
    }

    public void setCode_id(String code_id) {
        this.code_id = code_id;
    }


    public int getPayment_type() {
        return payment_type;
    }

    public void setPayment_type(int payment_type) {
        this.payment_type = payment_type;
    }

    public OrderPayload getOrder() {
        return order;
    }

    public void setOrder(OrderPayload order) {
        this.order = order;
    }

    public List<DispenseRecord> getDispense() {
        return dispense;
    }

    public void setDispense(List<DispenseRecord> dispense) {
        this.dispense = dispense;
    }

    // =========== 內部類別：訂單資訊 ===========

    public static class OrderPayload {
        /** 訂單編號（本地時間戳 UUID） */
        private String order_no;

        /** 商品原始總金額 */
        private int original_amount;

        /** 折扣金額 */
        private int discount_amount;

        /** 實際應付金額 */
        private int total_amount;

        /** 實際支付金額 */
        private int pay_amount;

        /** 找零金額 */
        private int change_amount;

        /** 使用點數 */
        private int points_used;

        /**
         * 支付類型代碼：
         * 1:信用卡, 2:悠遊卡/一卡通, 3:掃碼支付, 4:紙鈔機, 5:通行碼, 6:取貨碼,
         * 7:來店禮, 8:問卷, 9:零錢, 30:LINE Pay, 31:街口, 32:悠遊付, 33:Pi,
         * 34:全盈+, 40:會員驗證取貨, 41:員工卡, 60:點數全額折抵。
         */
        private int payment_type;

        /**
         * 支付狀態：1 = 成功
         */
        private int payment_status;

        /**
         * 訂單出貨狀態：0 = 全部失敗, 1 = 全部成功, 2 = 部分失敗
         */
        private int delivery_status;

        /** 支付 Request 原始內容 (JSON String) */
        private String payment_request;

        /** 支付 Response 原始內容 (JSON String) */
        private String payment_response;

        /** 會員條碼 */
        private String member_barcode;

        /** 發票資訊 */
        private String invoice_info;

        /** 機台本地時間 (yyyy-MM-dd HH:mm:ss) */
        private String machine_time;

        /** 購買商品列表 */
        private List<ItemRecord> items;

        // Getters & Setters
        public String getOrder_no() {
            return order_no;
        }

        public void setOrder_no(String order_no) {
            this.order_no = order_no;
        }

        public int getOriginal_amount() {
            return original_amount;
        }

        public void setOriginal_amount(int original_amount) {
            this.original_amount = original_amount;
        }

        public int getDiscount_amount() {
            return discount_amount;
        }

        public void setDiscount_amount(int discount_amount) {
            this.discount_amount = discount_amount;
        }

        public int getTotal_amount() {
            return total_amount;
        }

        public void setTotal_amount(int total_amount) {
            this.total_amount = total_amount;
        }

        public int getPay_amount() {
            return pay_amount;
        }

        public void setPay_amount(int pay_amount) {
            this.pay_amount = pay_amount;
        }

        public int getChange_amount() {
            return change_amount;
        }

        public void setChange_amount(int change_amount) {
            this.change_amount = change_amount;
        }

        public int getPoints_used() {
            return points_used;
        }

        public void setPoints_used(int points_used) {
            this.points_used = points_used;
        }

        public int getPayment_type() {
            return payment_type;
        }

        public void setPayment_type(int payment_type) {
            this.payment_type = payment_type;
        }

        public int getPayment_status() {
            return payment_status;
        }

        public void setPayment_status(int payment_status) {
            this.payment_status = payment_status;
        }

        public int getDelivery_status() {
            return delivery_status;
        }

        public void setDelivery_status(int delivery_status) {
            this.delivery_status = delivery_status;
        }

        public String getPayment_request() {
            return payment_request;
        }

        public void setPayment_request(String payment_request) {
            this.payment_request = payment_request;
        }

        public String getPayment_response() {
            return payment_response;
        }

        public void setPayment_response(String payment_response) {
            this.payment_response = payment_response;
        }

        public String getMember_barcode() {
            return member_barcode;
        }

        public void setMember_barcode(String member_barcode) {
            this.member_barcode = member_barcode;
        }

        public String getInvoice_info() {
            return invoice_info;
        }

        public void setInvoice_info(String invoice_info) {
            this.invoice_info = invoice_info;
        }

        public String getMachine_time() {
            return machine_time;
        }

        public void setMachine_time(String machine_time) {
            this.machine_time = machine_time;
        }

        public List<ItemRecord> getItems() {
            return items;
        }

        public void setItems(List<ItemRecord> items) {
            this.items = items;
        }
    }

    // =========== 內部類別：購買商品記錄 ===========

    public static class ItemRecord {
        /** 商品 ID（後台數字 ID，由 productID 字串轉換；若無法解析則填 0） */
        private int product_id;

        /** 單價 */
        private int price;

        /** 數量 */
        private int quantity;

        public ItemRecord(int product_id, int price, int quantity) {
            this.product_id = product_id;
            this.price = price;
            this.quantity = quantity;
        }

        public int getProduct_id() {
            return product_id;
        }

        public int getPrice() {
            return price;
        }

        public int getQuantity() {
            return quantity;
        }
    }

    // =========== 內部類別：出貨記錄 ===========

    public static class DispenseRecord {
        /** 貨道號碼（字串型態） */
        private String slot_no;

        /** 商品 ID */
        private int product_id;

        /** 商品金額 */
        private int amount;

        /** 使用點數 */
        private int points_used;

        /**
         * 出貨狀態：1 = 成功, 0 = 失敗
         */
        private int dispense_status;

        /** 出貨後剩餘庫存 */
        private int remaining_stock;

        /** 出貨完成時的機台本地時間 (yyyy-MM-dd HH:mm:ss) */
        private String machine_time;

        public DispenseRecord(String slot_no, int product_id, int amount, int points_used,
                int dispense_status, int remaining_stock, String machine_time) {
            this.slot_no = slot_no;
            this.product_id = product_id;
            this.amount = amount;
            this.points_used = points_used;
            this.dispense_status = dispense_status;
            this.remaining_stock = remaining_stock;
            this.machine_time = machine_time;
        }

        public String getSlot_no() {
            return slot_no;
        }

        public int getProduct_id() {
            return product_id;
        }

        public int getAmount() {
            return amount;
        }

        public int getPoints_used() {
            return points_used;
        }

        public int getDispense_status() {
            return dispense_status;
        }

        public int getRemaining_stock() {
            return remaining_stock;
        }

        public String getMachine_time() {
            return machine_time;
        }
    }
}
