from functools import partial

from PySide6.QtCore import Qt, QTimer
from PySide6.QtWidgets import (
    QAbstractItemView,
    QDialog,
    QDialogButtonBox,
    QFormLayout,
    QHBoxLayout,
    QHeaderView,
    QLabel,
    QLineEdit,
    QPushButton,
    QSizePolicy,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
)

from pypos.core.base_view import BaseView
from pypos.core.utils.dialog_size_helper import set_fixed_dialog_size
from pypos.modules.customer.config.customer_config import get_customer_search_dialog_size


class CustomerSearchView(BaseView, QDialog):
    def __init__(self, controller, parent=None):
        super().__init__(parent)
        self.log_debug("CustomerSearchView.__init__ dipanggil")
        self.setWindowTitle("Cari dan Pilih Member")
        self.controller = controller
        self.selected_customer_id = None
        self.customer_list = []
        # edited by glg
        # Debounce input search agar count+query customer tidak dipanggil tiap karakter.
        self._search_debounce_timer = QTimer(self)
        self._search_debounce_timer.setSingleShot(True)
        self._search_debounce_timer.setInterval(280)
        self._search_debounce_timer.timeout.connect(self._trigger_filter_table)
        self._build_ui()
        self.search_input.setFocus()

    def _build_ui(self):
        layout = QVBoxLayout()

        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("Cari Nama/Kode/Email/Telepon")
        self.search_input.textChanged.connect(self._schedule_filter_table)
        layout.addWidget(self.search_input)

        nav_layout = QHBoxLayout()
        self.btn_prev = QPushButton("Sebelumnya")
        self.btn_prev.clicked.connect(self.controller.go_prev_page)
        self.btn_next = QPushButton("Berikutnya")
        self.btn_next.clicked.connect(self.controller.go_next_page)
        self.lbl_page_info = QLabel("Menampilkan 0-0 dari 0")
        nav_layout.addWidget(self.btn_prev)
        nav_layout.addWidget(self.btn_next)
        nav_layout.addWidget(self.lbl_page_info)
        nav_layout.addStretch(1)
        layout.addLayout(nav_layout)

        self.table = QTableWidget(0, 9)
        self.table.setHorizontalHeaderLabels(
            ["No", "Kode Member", "Level", "Nama Member", "eMail", "Telp", "Point", "Propinsi", "Detail"]
        )
        self.table.setSelectionBehavior(QTableWidget.SelectRows)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.cellClicked.connect(self.controller.handle_cell_clicked)
        self.table.installEventFilter(self)
        self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(8, QHeaderView.ResizeToContents)
        self.table.setStyleSheet("QTableWidget::item:selected { background: #d0d0d0; color: black; }")
        layout.addWidget(self.table)

        self.setLayout(layout)
        dialog_width, dialog_height = get_customer_search_dialog_size()
        set_fixed_dialog_size(self, dialog_width, dialog_height)

    # edited by glg
    def _schedule_filter_table(self, _text=""):
        if hasattr(self, "_search_debounce_timer") and self._search_debounce_timer is not None:
            self._search_debounce_timer.start()

    # edited by glg
    def _trigger_filter_table(self):
        if hasattr(self, "controller") and self.controller is not None:
            self.controller.filter_table(self.search_input.text())

    def render_customers(self, customers, current_offset):
        self.customer_list = list(customers or [])
        self.table.setRowCount(0)
        for idx, customer in enumerate(self.customer_list, start=1):
            row = self.table.rowCount()
            self.table.insertRow(row)
            no_item = QTableWidgetItem(str(current_offset + idx))
            no_item.setData(Qt.UserRole, int(customer.get("id") or 0))
            self.table.setItem(row, 0, no_item)
            self.table.setItem(row, 1, QTableWidgetItem(str(customer.get("kode_member", ""))))
            self.table.setItem(row, 2, QTableWidgetItem(str(customer.get("level_nama", ""))))
            self.table.setItem(row, 3, QTableWidgetItem(str(customer.get("nama", ""))))
            self.table.setItem(row, 4, QTableWidgetItem(str(customer.get("email", ""))))
            self.table.setItem(row, 5, QTableWidgetItem(str(customer.get("telp", ""))))
            self.table.setItem(row, 6, QTableWidgetItem(str(customer.get("point", ""))))
            self.table.setItem(row, 7, QTableWidgetItem(str(customer.get("propinsi", ""))))
            btn = QPushButton("DETAIL")
            btn.setProperty("class", "btn-detail-member")
            btn.clicked.connect(partial(self.controller.show_detail_dialog, row))
            self.table.setCellWidget(row, 8, btn)
        if self.table.rowCount() > 0:
            self.table.selectRow(0)

    def update_pagination(self, current_offset, total_count, page_size, current_count):
        start = 0 if total_count == 0 else (current_offset + 1)
        end = min(total_count, current_offset + current_count)
        self.lbl_page_info.setText(f"Menampilkan {start}-{end} dari {total_count}")
        self.btn_prev.setEnabled(current_offset > 0)
        self.btn_next.setEnabled(end < total_count and page_size > 0)

    def show_customer_detail(self, customer):
        dialog = QDialog(self)
        dialog.setWindowTitle("Detail Member")
        layout = QFormLayout()
        layout.addRow(QLabel("Kode Member:"), QLabel(str(customer.get("kode_member", ""))))
        layout.addRow(QLabel("Level:"), QLabel(str(customer.get("level_nama", ""))))
        layout.addRow(QLabel("Nama Member:"), QLabel(str(customer.get("nama", ""))))
        layout.addRow(QLabel("eMail:"), QLabel(str(customer.get("email", ""))))
        layout.addRow(QLabel("Telp:"), QLabel(str(customer.get("telp", ""))))
        layout.addRow(QLabel("Point:"), QLabel(str(customer.get("point", ""))))
        layout.addRow(QLabel("Propinsi:"), QLabel(str(customer.get("propinsi", ""))))
        buttons = QDialogButtonBox(QDialogButtonBox.Close)
        buttons.rejected.connect(dialog.reject)
        layout.addRow(buttons)
        dialog.setLayout(layout)
        dialog.exec()

    def eventFilter(self, obj, event):
        if obj == self.table and event.type() == event.Type.KeyPress:
            key = event.key()

            if key in (Qt.Key_Down, Qt.Key_Up, Qt.Key_PageDown, Qt.Key_PageUp):
                return False

            if key in (Qt.Key_Return, Qt.Key_Enter):
                return False

            if key == Qt.Key_Escape:
                return False

            if key == Qt.Key_Backspace:
                current_text = self.search_input.text()
                if current_text:
                    self.search_input.setText(current_text[:-1])
                return True

            if event.text() and event.text().isprintable():
                self.search_input.setText(self.search_input.text() + event.text())
                return True

        return super().eventFilter(obj, event)

    def keyPressEvent(self, event):
        key = event.key()

        if key in (Qt.Key_Return, Qt.Key_Enter):
            self.controller.key_pressed(event)
        elif key == Qt.Key_Escape:
            self.controller.key_pressed(event)
        elif key in (Qt.Key_Down, Qt.Key_Up):
            self.table.setFocus()
            if self.table.currentRow() == -1:
                for row in range(self.table.rowCount()):
                    if not self.table.isRowHidden(row):
                        self.table.selectRow(row)
                        break

    def get_selected_customer_id(self):
        return self.selected_customer_id
