package com.unibuy.smartdevice.tools;

import android.content.Context;
import android.util.Log;

import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.ReportFlowInfoStructure;
import com.unibuy.smartdevice.structure.mqtt.TransactionFinalizePayload;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * 交易結案 Payload 的組裝工具。
 *
 * 使用方式：
 * 1. 在支付成功進入出貨流程前，建立此 Builder 實例。
 * 2. 每次一個貨道出貨完成，呼叫 {@link #addDispenseRecord} 加入結果。
 * 3. 全部出貨完成後，呼叫 {@link #build()} 取得完整的 Payload。
 *
 * 此 Builder 取代舊的 B600 / B601 / B602 分段 HTTP 上報機制。
 */
public class TransactionFinalizeBuilder {

    private static final String TAG = "TransactionFinalizeBuilder";
    private static final SimpleDateFormat SDF =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    private static final int ORDER_STATUS_FAILED = 0;
    private static final int ORDER_STATUS_SUCCESS = 1;
    private static final int ORDER_STATUS_PARTIAL_FAILED = 2;

    /** 訂單建立時間（支付完成時的時間點） */
    private final String orderMachineTime;

    /** 機台本地流水號（格式：YYYYMMDDXXXX，例如 202605110001） */
    private String flowId;

    /** 銷貨紀錄訂單號，預設同 flow_id，特殊流程可覆寫 */
    private String orderNo;

    /** 累積的出貨結果清單 */
    private final List<TransactionFinalizePayload.DispenseRecord> dispenseRecords = new ArrayList<>();

    private String codeId = "0";

    public TransactionFinalizeBuilder() {
        this.orderMachineTime = SDF.format(new Date());
        // 在進入出貨流程時立即生成本次交易流水號（一次交易只生成一次）
        this.flowId = FlowIdGenerator.next(MyApp.getInstance());
        this.orderNo = this.flowId;
        Log.i(TAG, "TransactionFinalizeBuilder created, flow_id=" + this.flowId);
    }

    public void setFlowId(String flowId) {
        this.flowId = flowId;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public void setCodeId(String codeId) {
        this.codeId = codeId;
    }


    /**
     * 加入一筆出貨結果記錄（每個貨道出貨後呼叫一次）。
     *
     * @param slotNo          貨道號碼（整數）
     * @param productId       商品 ID（整數，後台 ID）
     * @param amount          此貨道的商品金額
     * @param pointsUsed      使用點數
     * @param isSuccess       是否出貨成功
     * @param remainingStock  出貨後剩餘庫存
     */
    public void addDispenseRecord(int slotNo, int productId, int amount,
                                  int pointsUsed, boolean isSuccess, int remainingStock) {
        TransactionFinalizePayload.DispenseRecord record = new TransactionFinalizePayload.DispenseRecord(
                String.valueOf(slotNo),
                productId,
                amount,
                pointsUsed,
                isSuccess ? 1 : 0,
                remainingStock,
                SDF.format(new Date())
        );
        dispenseRecords.add(record);
        Log.d(TAG, "Added dispense record: slot=" + slotNo + " status=" + (isSuccess ? "success" : "failed"));
    }

    /**
     * 組裝完整的 TransactionFinalizePayload。
     * 應在所有出貨流程結束後呼叫。
     *
     * @return 完整的 MQTT finalize payload
     */
    public TransactionFinalizePayload build() {
        ReportFlowInfoStructure flowInfo = MyApp.getInstance().getReportFlowInfoData();

        TransactionFinalizePayload payload = new TransactionFinalizePayload();

        // --- flow_id：機台本地流水號 (YYYYMMDDXXXX) ---
        // 由 FlowIdGenerator 在建立 Builder 時生成，不依賴後端 API 回傳。
        payload.setFlow_id(flowId);

        // --- code_id：特殊驗證碼 ID (B660/B670/B680 取得) ---
        // 一般現金/電子支付交易為 "0"。
        if (this.codeId != null && !this.codeId.equals("0")) {
            payload.setCode_id(this.codeId);
        } else {
            String accessCodeId = MyApp.getInstance().getReportAccessCodeStructure().getAccessCodeId();
            if (accessCodeId != null && !accessCodeId.isEmpty()) {
                payload.setCode_id(accessCodeId);
            } else {
                payload.setCode_id("0");
            }
        }


        // --- payment_type：支付類型 (Root 級別) ---
        payload.setPayment_type(flowInfo.getFlowType());

        // --- 組裝 order ---
        TransactionFinalizePayload.OrderPayload order = buildOrderPayload(flowInfo);
        order.setDelivery_status(calculateOrderStatus());
        payload.setOrder(order);

        // --- 出貨記錄 ---
        payload.setDispense(new ArrayList<>(dispenseRecords));

        Log.i(TAG, "TransactionFinalizePayload built: flow_id=" + flowId
                + ", order_no=" + order.getOrder_no()
                + ", items=" + order.getItems().size()
                + ", dispense=" + dispenseRecords.size());

        return payload;
    }

    private int calculateOrderStatus() {
        boolean hasSuccess = false;
        boolean hasFailed = false;

        for (TransactionFinalizePayload.DispenseRecord record : dispenseRecords) {
            if (record.getDispense_status() == 1) {
                hasSuccess = true;
            } else {
                hasFailed = true;
            }
        }

        if (hasSuccess && hasFailed) {
            return ORDER_STATUS_PARTIAL_FAILED;
        }
        if (hasSuccess) {
            return ORDER_STATUS_SUCCESS;
        }
        return ORDER_STATUS_FAILED;
    }

    /**
     * 從 MyApp 的全域狀態組裝 OrderPayload。
     */
    private TransactionFinalizePayload.OrderPayload buildOrderPayload(ReportFlowInfoStructure flowInfo) {
        TransactionFinalizePayload.OrderPayload order = new TransactionFinalizePayload.OrderPayload();

        order.setOrder_no(orderNo != null && !orderNo.isEmpty() ? orderNo : flowId);

        // 金額資訊
        int totalAmount = flowInfo.getTotalPrice();
        order.setOriginal_amount(totalAmount);
        order.setDiscount_amount(0); // TODO: 如有折扣活動需進一步填入
        order.setTotal_amount(totalAmount);
        order.setPay_amount(totalAmount);
        order.setChange_amount(flowInfo.getGiveChange());
        order.setPoints_used(flowInfo.getUsePoints());

        // 支付類型：flowType 直接對應 payment_type
        order.setPayment_type(flowInfo.getFlowType());
        order.setPayment_status(1); // 走到出貨流程代表支付已成功

        // 支付流程原始資料
        order.setPayment_request(
                flowInfo.getFlowSendInfo() != null ? flowInfo.getFlowSendInfo() : "");
        order.setPayment_response(
                flowInfo.getFlowRequestInfo() != null ? flowInfo.getFlowRequestInfo() : "");

        // 會員資訊
        order.setMember_barcode(
                flowInfo.getFlowBarCode() != null ? flowInfo.getFlowBarCode() : "");

        // 發票資訊
        order.setInvoice_info(
                flowInfo.getInvoiceInfo() != null ? flowInfo.getInvoiceInfo() : "");

        // 機台時間
        order.setMachine_time(orderMachineTime);

        // --- 組裝購買商品清單 (items) ---
        List<TransactionFinalizePayload.ItemRecord> items = new ArrayList<>();
        List<BuyStructure> buyList = MyApp.getInstance().getBuyList();
        if (buyList != null) {
            for (BuyStructure buy : buyList) {
                int productId = 0;
                try {
                    productId = Integer.parseInt(buy.getProduct().getProductID());
                } catch (NumberFormatException e) {
                    Log.w(TAG, "Cannot parse productID to int: " + buy.getProduct().getProductID());
                }
                int price = buy.getProduct().getRealPrice();
                int quantity = buy.getCount() > 0 ? buy.getCount() : 1;
                items.add(new TransactionFinalizePayload.ItemRecord(productId, price, quantity));
            }
        }
        order.setItems(items);

        return order;
    }
}
