﻿from PySide6.QtCore import QDate, Qt, Signal
from PySide6.QtGui import QDoubleValidator
from PySide6.QtWidgets import (
    QAbstractItemView,
    QDialog,
    QFrame,
    QGroupBox,
    QHBoxLayout,
    QHeaderView,
    QLabel,
    QLineEdit,
    QPushButton,
    QScrollArea,
    QSizePolicy,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
    QWidget,
    QDateEdit,
)

from pypos.core.base_view import BaseView
from pypos.modules.penjualan.views.settlement_view_formatter import SettlementViewFormatter
from pypos.modules.penjualan.config.penjualan_config import (
    get_settlement_history_reprint_button_label,
    is_settlement_history_reprint_enabled,
)


class SettlementDialogView(BaseView, QDialog):
    # edited by glg
    # Signal lintas-thread untuk refresh data settlement (daftar + history + non tunai).
    refresh_payload_ready = Signal(int, object)
    # edited by glg
    # Signal lintas-thread untuk detail item transaksi settlement.
    preview_detail_payload_ready = Signal(int, object)
    # edited by glg
    # Signal lintas-thread untuk detail history settlement.
    history_detail_payload_ready = Signal(int, object)

    def __init__(self, controller, parent=None, as_page=False, on_close_requested=None):
        super().__init__(parent)
        self.controller = controller
        self.is_page = bool(as_page)
        self._on_close_requested = on_close_requested
        self.transaksi_data = []
        self.history_data = []
        self._total_settlement = 0.0
        self._refresh_payload_handler = None
        self._preview_detail_payload_handler = None
        self._history_detail_payload_handler = None
        self.refresh_payload_ready.connect(self._on_refresh_payload_ready, Qt.QueuedConnection)
        self.preview_detail_payload_ready.connect(self._on_preview_detail_payload_ready, Qt.QueuedConnection)
        self.history_detail_payload_ready.connect(self._on_history_detail_payload_ready, Qt.QueuedConnection)

        if self.is_page:
            self.setWindowFlags(Qt.Widget)
        else:
            self.setWindowTitle("Settlement Transaksi")
            from pypos.core.utils.window_size_helper import set_window_size_by_screen

            set_window_size_by_screen(self)

        self.init_ui()
        self._is_initialized = True

    # edited by glg
    def set_preview_detail_payload_handler(self, handler):
        self._preview_detail_payload_handler = handler

    # edited by glg
    def set_refresh_payload_handler(self, handler):
        self._refresh_payload_handler = handler

    # edited by glg
    def emit_refresh_payload(self, request_id, payload):
        try:
            self.refresh_payload_ready.emit(int(request_id), payload)
        except Exception:
            return

    # edited by glg
    def _on_refresh_payload_ready(self, request_id, payload):
        if callable(self._refresh_payload_handler):
            self._refresh_payload_handler(int(request_id), payload)

    # edited by glg
    def emit_preview_detail_payload(self, request_id, payload):
        try:
            self.preview_detail_payload_ready.emit(int(request_id), payload)
        except Exception:
            return

    # edited by glg
    def _on_preview_detail_payload_ready(self, request_id, payload):
        if callable(self._preview_detail_payload_handler):
            self._preview_detail_payload_handler(int(request_id), payload)

    # edited by glg
    def set_history_detail_payload_handler(self, handler):
        self._history_detail_payload_handler = handler

    # edited by glg
    def emit_history_detail_payload(self, request_id, payload):
        try:
            self.history_detail_payload_ready.emit(int(request_id), payload)
        except Exception:
            return

    # edited by glg
    def _on_history_detail_payload_ready(self, request_id, payload):
        if callable(self._history_detail_payload_handler):
            self._history_detail_payload_handler(int(request_id), payload)

    def init_ui(self):
        self.setContentsMargins(0, 0, 0, 0)
        layout = QVBoxLayout()
        layout.setSpacing(10)
        layout.setContentsMargins(10, 10, 10, 10)

        self._build_transaksi_section(layout)
        self._build_input_section(layout)
        self._build_history_section(layout)
        self._build_footer_section(layout)

        self.setLayout(layout)
        self._connect_internal_events()
        self._sync_total_settlement()

    def _build_transaksi_section(self, parent_layout):
        header_container = QWidget()
        header_layout = QVBoxLayout(header_container)
        header_layout.setSpacing(0)
        header_layout.setContentsMargins(0, 0, 0, 0)

        label_info = QLabel("Daftar Transaksi yang Belum Disettle (Sebelum Jam 20:00 Hari Ini):")
        label_info.setContentsMargins(0, 0, 0, 0)
        label_info.setStyleSheet("padding: 2px 5px; margin: 0px; background: #f0f0f0;")
        label_info.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # edited by glg
        # Pakai minimum-height agar label header tetap responsif saat font/DPI berubah.
        label_info.setMinimumHeight(label_info.sizeHint().height())
        header_layout.addWidget(label_info)

        self.transaksi_scroll = QScrollArea()
        self.transaksi_scroll.setWidgetResizable(True)
        self.transaksi_scroll.setFrameShape(QFrame.NoFrame)
        self.transaksi_scroll.setLineWidth(0)
        self.transaksi_scroll.setMidLineWidth(0)
        self.transaksi_scroll.viewport().setContentsMargins(0, 0, 0, 0)
        self.transaksi_scroll.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.transaksi_scroll.setMaximumHeight(300)
        self.transaksi_scroll.setStyleSheet(
            "QScrollArea { background: #f9f9f9; border: none; margin: 0px; padding: 0px; }"
        )

        self.transaksi_container = QWidget()
        self.transaksi_layout = QVBoxLayout(self.transaksi_container)
        self.transaksi_layout.setContentsMargins(0, 0, 0, 0)
        self.transaksi_layout.setSpacing(0)
        self.transaksi_scroll.setWidget(self.transaksi_container)

        header_layout.addWidget(self.transaksi_scroll)
        parent_layout.addWidget(header_container)

    def _build_input_section(self, parent_layout):
        uang_group = QGroupBox("Input Settlement")
        uang_group.setStyleSheet(
            """
            QGroupBox {
                font-weight: bold;
                color: #333;
                border: 2px solid #007bff;
                border-radius: 6px;
                margin-top: 0.5em;
                padding-top: 0.5em;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                subcontrol-position: top left;
                left: 10px;
                padding: 0 3px 0 3px;
                font-size: 11pt;
            }
            """
        )

        inner = QVBoxLayout()
        inner.setSpacing(8)
        inner.setContentsMargins(15, 10, 15, 6)

        self.info_label = QLabel(SettlementViewFormatter.format_info_transaksi(self.transaksi_data))
        self.info_label.setStyleSheet("color: #333; font-size: 10pt; margin-bottom: 2px;")
        self.info_label.setTextFormat(Qt.RichText)
        inner.addWidget(self.info_label)

        desc = QLabel("Masukkan total uang tunai yang diterima untuk settlement hari ini")
        desc.setStyleSheet("color: #666; font-size: 10pt; font-style: italic;")
        inner.addWidget(desc)

        input_row = QHBoxLayout()
        input_row.setSpacing(5)
        prefix_label = QLabel("Rp")
        prefix_label.setStyleSheet(
            "font-size: 12pt; font-weight: bold; color: #007bff; margin-left: 8px; margin-right: 4px;"
        )
        input_row.addWidget(prefix_label)

        self.uang_input = QLineEdit()
        self.uang_input.setPlaceholderText("0")
        self.uang_input.setValidator(QDoubleValidator(0.0, 999999999.99, 0))
        self.uang_input.setStyleSheet(
            """
            QLineEdit {
                border: 2px solid #ddd;
                border-radius: 4px;
                padding: 10px 12px;
                font-size: 12pt;
                background-color: #f8f9fa;
                selection-background-color: #007bff;
            }
            QLineEdit:focus {
                border: 2px solid #007bff;
                background-color: #ffffff;
            }
            QLineEdit:hover {
                border: 2px solid #80bdff;
            }
            """
        )
        self.uang_input.setMinimumHeight(35)
        self.uang_input.setMinimumWidth(250)
        input_row.addWidget(self.uang_input)
        input_row.addStretch()
        inner.addLayout(input_row)

        helper = QLabel("Format: Angka tanpa pemisah (contoh: 1000000)")
        helper.setStyleSheet("color: #999; font-size: 9pt;")
        inner.addWidget(helper)

        self.uang_preview_label = QLabel("Tampilan nominal: Rp -")
        self.uang_preview_label.setStyleSheet(
            "color: #333; font-size: 10pt; font-weight: bold; "
            "background: #f3f3f3; border: 1px solid #ddd; "
            "padding: 4px 6px; border-radius: 4px;"
        )
        inner.addWidget(self.uang_preview_label)

        self.status_setoran_label = QLabel("")
        self.status_setoran_label.setStyleSheet("font-size: 10pt; font-weight: bold; margin-top: 2px;")
        self.status_setoran_label.setVisible(False)
        inner.addWidget(self.status_setoran_label)

        self.non_tunai_header_label = QLabel("Transaksi Non Tunai")
        self.non_tunai_header_label.setStyleSheet(
            "font-weight: bold; color: #0056b3; margin-top: 2px; margin-bottom: 0px;"
        )
        inner.addWidget(self.non_tunai_header_label)

        self.non_tunai_label = QLabel("<i>Info non tunai tidak tersedia</i>")
        self.non_tunai_label.setStyleSheet("color: #444; font-size: 9pt; margin-bottom: 0px;")
        self.non_tunai_label.setTextFormat(Qt.RichText)
        inner.addWidget(self.non_tunai_label)

        self.uang_action_layout = QHBoxLayout()
        self.uang_action_layout.addStretch()
        inner.addLayout(self.uang_action_layout)

        uang_group.setLayout(inner)
        parent_layout.addWidget(uang_group)

    def _build_history_section(self, parent_layout):
        garis = QFrame()
        garis.setFrameShape(QFrame.HLine)
        garis.setFrameShadow(QFrame.Sunken)
        parent_layout.addWidget(garis)

        self.tabel_detail = QTableWidget()
        self.tabel_detail.setColumnCount(5)
        self.tabel_detail.setHorizontalHeaderLabels(["ID", "Waktu", "Produk", "Qty", "Total"])
        self.tabel_detail.setEditTriggers(QTableWidget.NoEditTriggers)
        self.tabel_detail.setSelectionBehavior(QTableWidget.SelectRows)
        self.tabel_detail.setStyleSheet("QTableWidget::item:selected { background: #d0d0d0; color: black; }")
        self.tabel_detail.setVisible(False)
        parent_layout.addWidget(self.tabel_detail)

        self.history_label = QLabel("History Settlement:")
        parent_layout.addWidget(self.history_label)

        history_filter_layout = QHBoxLayout()
        history_filter_layout.setContentsMargins(0, 0, 0, 0)
        history_filter_layout.setSpacing(6)

        self.history_start_date = QDateEdit()
        self.history_start_date.setCalendarPopup(True)
        self.history_start_date.setDisplayFormat("yyyy-MM-dd")
        self.history_start_date.setDate(QDate.currentDate())

        self.history_end_date = QDateEdit()
        self.history_end_date.setCalendarPopup(True)
        self.history_end_date.setDisplayFormat("yyyy-MM-dd")
        self.history_end_date.setDate(QDate.currentDate())

        self.history_filter_button = QPushButton("Filter")
        self.history_filter_button.setProperty("class", "primary")

        history_filter_layout.addWidget(QLabel("Dari:"))
        history_filter_layout.addWidget(self.history_start_date)
        history_filter_layout.addWidget(QLabel("Sampai:"))
        history_filter_layout.addWidget(self.history_end_date)
        history_filter_layout.addWidget(self.history_filter_button)
        history_filter_layout.addStretch()
        parent_layout.addLayout(history_filter_layout)

        # edited by glg
        self._history_reprint_enabled = bool(is_settlement_history_reprint_enabled())
        self._history_reprint_tooltip = str(
            get_settlement_history_reprint_button_label() or "Print ulang nota settlement"
        ).strip()
        if self._history_reprint_enabled:
            column_count = 7
            headers = ["Tanggal", "Admin", "Kasir", "Disetor (Tunai)", "Non Tunai", "Status", "Aksi"]
        else:
            column_count = 6
            headers = ["Tanggal", "Admin", "Kasir", "Disetor (Tunai)", "Non Tunai", "Status"]

        self.table_history = QTableWidget()
        self.table_history.setColumnCount(column_count)
        self.table_history.setHorizontalHeaderLabels(headers)
        self.table_history.setEditTriggers(QTableWidget.NoEditTriggers)
        self.table_history.setSelectionBehavior(QTableWidget.SelectRows)
        self.table_history.setStyleSheet("QTableWidget::item:selected { background: #d0d0d0; color: black; }")
        header_history = self.table_history.horizontalHeader()
        header_history.setSectionResizeMode(QHeaderView.Stretch)
        if self._history_reprint_enabled:
            header_history.setSectionResizeMode(column_count - 1, QHeaderView.ResizeToContents)
        self.table_history.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.table_history.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.table_history.setWordWrap(False)
        self.table_history.cellClicked.connect(self._handle_history_row_click)

        parent_layout.addWidget(self.table_history)

    def _build_footer_section(self, parent_layout):
        button_layout = QHBoxLayout()
        self.settle_button = QPushButton("SETTLE")
        self.settle_button.setProperty("class", "primary")
        self.settle_button.setEnabled(False)
        self.cancel_button = QPushButton("TUTUP")
        self.cancel_button.setProperty("class", "danger")

        if self.uang_action_layout is not None:
            self.uang_action_layout.addWidget(self.settle_button)

        button_layout.addStretch()
        button_layout.addWidget(self.cancel_button)
        parent_layout.addLayout(button_layout)

    def _connect_internal_events(self):
        self.uang_input.textChanged.connect(self._validate_uang_input)
        self.uang_input.textChanged.connect(self._update_status_setoran)
        self.uang_input.textChanged.connect(self._update_uang_preview)
        self.settle_button.setDefault(True)
        self.settle_button.setAutoDefault(True)

    def _sync_total_settlement(self):
        if self.transaksi_data:
            raw_total = self.transaksi_data[0].get("total", 0)
            self._total_settlement = SettlementViewFormatter.parse_uang_value(raw_total)
        elif hasattr(self, "controller") and hasattr(self.controller, "get_total_settlement"):
            raw_total = self.controller.get_total_settlement() or 0
            self._total_settlement = SettlementViewFormatter.parse_uang_value(raw_total)
        else:
            self._total_settlement = 0
        self._update_status_setoran()

    def _update_status_setoran(self):
        total = self._total_settlement
        uang = SettlementViewFormatter.parse_uang_value(self.uang_input.text()) if hasattr(self, "uang_input") else 0
        if not total:
            self.status_setoran_label.setText("")
            self.status_setoran_label.setVisible(False)
            return

        # edited by glg
        # Status teks "Setoran sudah sesuai" dihilangkan sesuai permintaan.
        _ = uang
        self.status_setoran_label.setText("")
        self.status_setoran_label.setVisible(False)

    def set_cancel_button_enabled(self, enabled):
        if hasattr(self, "cancel_button") and self.cancel_button:
            self.cancel_button.setEnabled(bool(enabled))

    def tampilkan_info_transaksi(self, nilai):
        self.info_label.setText(SettlementViewFormatter.format_info_transaksi(self.transaksi_data, nilai))

    def tampilkan_info_non_tunai(self, summary):
        if hasattr(self, "non_tunai_label") and self.non_tunai_label:
            self.non_tunai_label.setText(SettlementViewFormatter.format_non_tunai(summary))

    def tampilkan_history(self, history_list):
        if not hasattr(self, "table_history") or self.table_history is None:
            return
        self.history_data = history_list or []
        self.table_history.setUpdatesEnabled(False)
        self.table_history.blockSignals(True)
        self.table_history.setRowCount(len(self.history_data))
        try:
            for row, data in enumerate(self.history_data):
                self.table_history.setItem(row, 0, QTableWidgetItem(str(data.get("tanggal", "-"))))
                self.table_history.setItem(row, 1, QTableWidgetItem(str(data.get("admin", "-"))))
                self.table_history.setItem(row, 2, QTableWidgetItem(str(data.get("kasir", "-"))))
                self.table_history.setItem(row, 3, QTableWidgetItem(f"{float(data.get('total_disetor', 0) or 0):,.0f}"))
                self.table_history.setItem(row, 4, QTableWidgetItem(f"{float(data.get('total_non_tunai', 0) or 0):,.0f}"))
                self.table_history.setItem(row, 5, QTableWidgetItem("Sudah disettle"))
                if self._history_reprint_enabled:
                    # edited by glg
                    # Hindari setCellWidget per-row (berat di history besar);
                    # gunakan item teks ringan + handler klik kolom aksi.
                    action_item = QTableWidgetItem("Print")
                    action_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                    action_item.setTextAlignment(Qt.AlignCenter)
                    action_item.setToolTip(self._history_reprint_tooltip)
                    self.table_history.setItem(row, 6, action_item)
        finally:
            self.table_history.blockSignals(False)
            self.table_history.setUpdatesEnabled(True)

    def get_history_filter_range(self):
        if not hasattr(self, "history_start_date") or not hasattr(self, "history_end_date"):
            return None, None
        return (
            self.history_start_date.date().toString("yyyy-MM-dd"),
            self.history_end_date.date().toString("yyyy-MM-dd"),
        )

    def _handle_history_row_click(self, row, column):
        if not self.history_data:
            return
        if row < 0 or row >= len(self.history_data):
            return
        if self._history_reprint_enabled and int(column or -1) == 6:
            self._handle_history_reprint_click(self.history_data[row])
            return
        if hasattr(self, "controller") and self.controller:
            self.controller.tampilkan_detail_history_settlement(self.history_data[row])

    # edited by glg
    def _handle_history_reprint_click(self, history_data):
        if not self._history_reprint_enabled:
            return
        if hasattr(self, "controller") and self.controller:
            self.controller.print_ulang_settlement_history(history_data)

    def tampilkan_detail_transaksi(self, text):
        if hasattr(self, "detail_text") and self.detail_text:
            self.detail_text.setText(text)

    def render_detail_transaksi(self, detail_list):
        if not hasattr(self, "detail_text") or self.detail_text is None:
            return
        lines = []
        for item in detail_list or []:
            lines.append(f"{item.get('nama', '-')} x{item.get('jumlah', 0)} = {item.get('total', 0):,}")
        self.detail_text.setText("\n".join(lines))

    def tampilkan_admin_section(self, admin_list):
        if not hasattr(self, "admin_combo") or self.admin_combo is None:
            return
        if not hasattr(self, "admin_group") or self.admin_group is None:
            return
        self.admin_combo.clear()
        self.admin_combo.addItems(admin_list or [])
        self.admin_group.setVisible(True)

    def tampilkan_pesan(self, pesan):
        super().show_info("Info", pesan)

    def tampilkan_error(self, pesan):
        super().show_error(pesan, title="Error")

    def tampilkan_rekap(self, text):
        if hasattr(self, "rekap_text") and self.rekap_text:
            self.rekap_text.setText(text)

    def render_transaksi_list(self, transaksi_data):
        self.transaksi_data = transaksi_data or []
        self._sync_total_settlement()

        container = QWidget()
        layout = QVBoxLayout(container)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        if not self.transaksi_data:
            no_data_label = QLabel("<i>Tidak ada transaksi yang perlu disettle.</i>", container)
            no_data_label.setStyleSheet("color: #888; font-style: italic;")
            layout.addWidget(no_data_label)
        else:
            for data in self.transaksi_data:
                row_widget = QFrame(container)
                row_widget.setFrameShape(QFrame.Box)
                row_widget.setStyleSheet(
                    "QFrame { background: white; border: 1px solid #ddd; border-radius: 3px; padding: 3px; }"
                )
                row_layout = QHBoxLayout(row_widget)
                row_layout.setContentsMargins(4, 4, 4, 4)

                info_layout = QVBoxLayout()
                info_layout.setSpacing(1)
                nama_hari = SettlementViewFormatter.resolve_hari(data.get("hari"))
                tanggal_label = QLabel(f"<b>- Tanggal:</b> {data.get('tanggal', '-')} ({nama_hari})")
                kasir_label = QLabel(f"<b>  Kasir:</b> {data.get('kasir', '-')}")
                jumlah_label = QLabel(f"<b>  Jumlah Transaksi:</b> {data.get('jumlah_transaksi', 0)}")
                info_layout.addWidget(tanggal_label)
                info_layout.addWidget(kasir_label)
                info_layout.addWidget(jumlah_label)
                row_layout.addLayout(info_layout, stretch=1)

                detail_button = QPushButton("Detail")
                # edited by glg
                # Hindari fixed-width supaya tombol detail tetap fleksibel di resolusi kecil.
                detail_button.setMinimumWidth(100)
                detail_button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
                detail_button.setStyleSheet(
                    "QPushButton { background-color: #007bff; color: white; border: none; border-radius: 4px; padding: 8px 16px; font-weight: bold; }"
                    "QPushButton:hover { background-color: #0056b3; }"
                    "QPushButton:pressed { background-color: #004085; }"
                )
                detail_button.clicked.connect(
                    lambda _checked=False, d=data: self.controller.tampilkan_detail_transaksi(
                        d.get("tanggal", ""),
                        d.get("kasir", ""),
                    )
                )
                row_layout.addWidget(detail_button, alignment=Qt.AlignVCenter)
                layout.addWidget(row_widget)

        self.transaksi_scroll.setWidget(container)
        self.transaksi_container = container
        self.transaksi_layout = layout

    def _validate_uang_input(self, text):
        if not hasattr(self, "uang_input") or self.uang_input is None:
            return
        cleaned = SettlementViewFormatter.sanitize_uang_input(text)
        if cleaned == text:
            return
        self.uang_input.blockSignals(True)
        self.uang_input.setText(cleaned)
        self.uang_input.blockSignals(False)

    def _update_uang_preview(self, text):
        if hasattr(self, "uang_preview_label") and self.uang_preview_label:
            self.uang_preview_label.setText(SettlementViewFormatter.format_preview_nominal(text))

    def get_uang_tunai(self):
        if not hasattr(self, "uang_input") or self.uang_input is None:
            return 0.0
        try:
            return float(self.uang_input.text().strip() or 0)
        except ValueError:
            return 0.0

    def nonaktifkan_form_internal(self):
        if not getattr(self, "_is_initialized", False):
            return
        try:
            if hasattr(self, "uang_input") and self.uang_input:
                self.uang_input.setEnabled(False)
            if hasattr(self, "settle_button") and self.settle_button:
                self.settle_button.setEnabled(False)
        except (AttributeError, RuntimeError):
            return

    def open_with_disabled_form(self):
        self.nonaktifkan_form_internal()
        self.exec()

    def setup_controller_events(self, controller):
        if not getattr(self, "_is_initialized", False):
            return
        if hasattr(self, "uang_input") and self.uang_input:
            self.uang_input.textChanged.connect(controller.aktifkan_admin_section)
        if hasattr(self, "cancel_button") and self.cancel_button:
            self.cancel_button.clicked.connect(self._handle_close_request)
        if hasattr(self, "settle_button") and self.settle_button:
            self.settle_button.clicked.connect(self._handle_settle_click)
        if hasattr(self, "history_filter_button") and self.history_filter_button:
            self.history_filter_button.clicked.connect(controller.filter_history_by_range)

    def _handle_close_request(self):
        if callable(self._on_close_requested):
            self._on_close_requested()
            return
        self.close()

    def _handle_settle_click(self):
        if not self.transaksi_data:
            self.tampilkan_pesan("Tidak ada transaksi yang perlu di settle.")
            return
        if hasattr(self, "controller") and self.controller:
            self.controller.proses_settlement()

