from datetime import datetime

from pypos.modules.penjualan.config.penjualan_config import (
    get_preorder_disable_cooldown_sec,
)


class LoadTransaksiService:
    def parse_transaksi_id(self, transaksi_id_text):
        text = str(transaksi_id_text or "").strip()
        if not text:
            return None
        try:
            value = int(text)
        except (TypeError, ValueError):
            return None
        return value if value > 0 else None

    def _as_float(self, value, default=0.0):
        try:
            return float(value)
        except (TypeError, ValueError):
            return float(default)

    def _as_int(self, value, default=0):
        try:
            return int(float(value))
        except (TypeError, ValueError):
            return int(default)

    def parse_header(self, header):
        if not header or len(header) < 5:
            return None
        customers_id = header[0]
        customers_nama = header[1]
        diskon = header[2] or 0
        ppn = header[3] or 0
        total_harga = header[4] or 0
        return customers_id, customers_nama, diskon, ppn, total_harga

    def build_preorder_payload(self, raw_transaksi, detail_rows, transaksi_id):
        if not raw_transaksi:
            return None
        return {
            "transaksi": raw_transaksi,
            "detail_rows": detail_rows or [],
            "transaksi_id": transaksi_id,
        }

    # edited by glg
    def get_preorder_disable_cooldown_sec(self, default=120):
        return int(get_preorder_disable_cooldown_sec(default=default))

    # edited by glg
    def is_remote_unavailable_reason(self, reason):
        text = str(reason or "").strip().lower()
        if not text:
            return False
        if text in ("data preorder kosong", "empty", "empty_data"):
            return False
        if text.startswith("missing_required:"):
            return True
        if text.startswith("missing_"):
            return True
        if text.startswith("http_error_"):
            return True
        if text.startswith("unexpected_error"):
            return True
        return text in (
            "timeout",
            "connection_error",
            "invalid_json",
            "request_failed",
            "invalid_remote_data",
        )

    # edited by glg
    def parse_remote_preorder_list(self, api_result):
        payload = api_result if isinstance(api_result, dict) else {}
        status = self._as_int(payload.get("status"), 0)
        if status != 1:
            reason = str(payload.get("reason") or "").strip()
            return [], reason
        rows = payload.get("data")
        if not isinstance(rows, list):
            return [], "invalid_remote_data"
        items = []
        for item in rows:
            if not isinstance(item, dict):
                continue
            preorder_id = str(item.get("id") or "").strip()
            if not preorder_id:
                continue
            items.append(item)
        return items, ""

    # edited by glg
    def build_remote_display_rows(self, remote_items):
        rows = []
        contexts = []
        for item in list(remote_items or []):
            if not isinstance(item, dict):
                continue
            preorder_id = str(item.get("id") or "").strip()
            if not preorder_id:
                continue
            prefaktur = str(item.get("prefaktur") or "").strip() or f"PO-{preorder_id}"
            dtime_order = str(item.get("dtime_order") or "").strip()
            customer_nama = str(item.get("customer_nama") or "Tunai").strip() or "Tunai"
            nilai_transaksi = self._as_float(item.get("nilai_transaksi"), 0.0)
            rows.append(
                (
                    f"API-{preorder_id}",
                    prefaktur,
                    dtime_order,
                    customer_nama,
                    nilai_transaksi,
                )
            )
            contexts.append(
                {
                    "source": "api",
                    "preorder": item,
                }
            )
        return rows, contexts

    # edited by glg
    def build_local_display_rows(self, local_rows):
        rows = []
        contexts = []
        for row in list(local_rows or []):
            try:
                transaksi_id = self._as_int(row[0], 0)
            except (TypeError, ValueError, IndexError):
                transaksi_id = 0
            if transaksi_id <= 0:
                continue
            rows.append(row)
            contexts.append(
                {
                    "source": "local",
                    "transaksi_id": transaksi_id,
                }
            )
        return rows, contexts

    # edited by glg
    def combine_display_rows(self, remote_items, local_rows):
        remote_display, remote_context = self.build_remote_display_rows(remote_items)
        local_display, local_context = self.build_local_display_rows(local_rows)
        return remote_display + local_display, remote_context + local_context

    # edited by glg
    def parse_use_preorder_result(self, api_result):
        payload = api_result if isinstance(api_result, dict) else {}
        status = payload.get("status", None)
        if status is not None and self._as_int(status, 0) == 0:
            reason = str(payload.get("reason") or "").strip() or "use_preorder_failed"
            return None, reason

        datas = payload.get("datas") if isinstance(payload.get("datas"), dict) else {}
        items_map = datas.get("items") if isinstance(datas.get("items"), dict) else {}
        detail_rows = []
        subtotal_sum = 0.0
        for produk_id, item in items_map.items():
            if not isinstance(item, dict):
                continue
            qty = max(0, self._as_int(item.get("jml"), 0))
            if qty <= 0:
                continue
            harga = max(0.0, self._as_float(item.get("harga"), 0.0))
            subtotal = max(0.0, self._as_float(item.get("subtotal"), harga * qty))
            gross = max(0.0, harga * qty)
            diskon_persen = 0.0
            if gross > 0 and subtotal <= gross:
                diskon_persen = max(0.0, ((gross - subtotal) / gross) * 100.0)
            detail_rows.append(
                (
                    str(produk_id),
                    str(item.get("nama") or "-"),
                    harga,
                    qty,
                    diskon_persen,
                    str(item.get("satuan") or ""),
                )
            )
            subtotal_sum += subtotal

        if not detail_rows:
            return None, "detail_preorder_kosong"

        customer_id = self._as_int(payload.get("customer_id"), 1)
        customer_nama = str(payload.get("customer_nama") or "Tunai")
        diskon = self._as_float(payload.get("diskon_persen"), 0.0)
        ppn = self._as_float(payload.get("ppn_persen"), 0.0)
        total_harga = self._as_float(payload.get("nilai_transaksi"), subtotal_sum)
        if total_harga <= 0:
            total_harga = subtotal_sum

        preorder_payload = self.build_remote_preorder_payload(payload, detail_rows, total_harga)
        return {
            "detail_rows": detail_rows,
            "customers_id": customer_id if customer_id > 0 else 1,
            "customers_nama": customer_nama,
            "diskon": diskon,
            "ppn": ppn,
            "total_harga": total_harga,
            "preorder_payload": preorder_payload,
        }, ""

    # edited by glg
    def build_remote_preorder_payload(self, api_payload, detail_rows, total_harga):
        payload = api_payload if isinstance(api_payload, dict) else {}
        dtime = str(
            payload.get("dtime_request")
            or payload.get("last_update")
            or datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        ).strip()
        nomer = str(
            payload.get("shoppingcart_order_id")
            or f"PO-{payload.get('id') or datetime.now().strftime('%Y%m%d%H%M%S')}"
        ).strip()
        raw_transaksi = {
            "nomer": nomer,
            "dtime": dtime,
            "transaksi_nilai": self._as_float(total_harga, 0.0),
            "diskon_persen": self._as_float(payload.get("diskon_persen"), 0.0),
            "ppn_persen": self._as_float(payload.get("ppn_persen"), 0.0),
            "transaksi_bulat": self._as_float(total_harga, 0.0),
            "customers_id": self._as_int(payload.get("customer_id"), 1),
            "customers_nama": str(payload.get("customer_nama") or "Tunai"),
            "fulldate": dtime[:10],
            "oleh_id": self._as_int(payload.get("oleh_id"), 0),
            "oleh_nama": str(payload.get("oleh_nama") or ""),
            "jenis_label": "simpan_transaksi",
            "transaksi_jenis": "758",
            "settlement_id": 1,
        }
        return {
            "transaksi": raw_transaksi,
            "detail_rows": detail_rows or [],
            "transaksi_id": None,
        }
