﻿from PySide6.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QGroupBox, QRadioButton, QLabel,
    QLineEdit, QPushButton, QFormLayout, QButtonGroup, QGridLayout, QStackedLayout, QSpinBox,
    QMessageBox
)
from PySide6.QtCore import Qt
from PySide6.QtGui import QIntValidator
from pypos.core.base_view import BaseView
from pypos.core.utils.db_helper import get_credit_card_names,get_receive_on_account_names,get_debit_card_names,get_receive_on_account_debit  # jika kamu buat di file terpisah
from pypos.modules.penjualan.config.penjualan_config import (
    get_ppn_mode,
    get_ppn_percent_for_view,
    is_voucher_enabled_for_kasir,
)

# upgraded: inherit base class
class PembayaranView(BaseView, QDialog):
    def __init__(self, controller, parent=None, multi_payment_mode=False):
        super().__init__(parent)
        self.controller = controller
        self.setWindowTitle("Pembayaran Transaksi")
        from pypos.core.utils.dialog_size_helper import set_fixed_dialog_size
        set_fixed_dialog_size(self, 900, 600)
        self.init_ui()
        self.atur_style_form()

    def init_ui(self):
        self.main_layout = QVBoxLayout()

        # === Info Transaksi ===
        self.label_tanggal = QLabel()
        self.label_jenis = QLabel()
        self.label_qty = QLabel()
        self.label_total = QLabel()
        self.info_layout = QFormLayout()
        self.info_layout.addRow("Tanggal:", self.label_tanggal)
        self.info_layout.addRow("Jenis Item:", self.label_jenis)
        self.info_layout.addRow("Total Qty:", self.label_qty)
        self.info_layout.addRow("Total Belanja:", self.label_total)
        #kode voucher
        self.voucher_input = QLineEdit()
        self._voucher_code_label = QLabel("Kode Voucher:")
        self.info_layout.addRow(self._voucher_code_label, self.voucher_input)
        self.voucher_saldo_label = QLabel("-")
        self._voucher_saldo_label = QLabel("Saldo Voucher:")
        self.info_layout.addRow(self._voucher_saldo_label, self.voucher_saldo_label)
        self.voucher_amount_input = QLineEdit()
        self.voucher_amount_input.setPlaceholderText("0")
        self.voucher_amount_input.setValidator(QIntValidator(0, 1000000000, self.voucher_amount_input))
        self._voucher_amount_label = QLabel("Nominal Voucher Dipakai:")
        self.info_layout.addRow(self._voucher_amount_label, self.voucher_amount_input)

        self.main_layout.addLayout(self.info_layout)
        self.voucher_ui_locked = not is_voucher_enabled_for_kasir()
        if self.voucher_ui_locked:
            self.voucher_input.setEnabled(False)
            self.voucher_amount_input.setEnabled(False)
            self.set_voucher_section_visible(False)
        else:
            self.set_voucher_code_row_visible(True)
            self.set_voucher_detail_rows_visible(False)

        # === Radio Button Metode Pembayaran ===
        self.radio_tunai = QRadioButton("Tunai")
        # Table pembayaran (jika ada) - set selection color
        if hasattr(self, 'table'):
            self.table.setProperty("class", "pembayaran")
        self.radio_credit = QRadioButton("Credit Card")
        self.radio_debit = QRadioButton("Debit Card")
        self.radio_tunai.setChecked(True)

        metode_group = QGroupBox("Metode Pembayaran")

        metode_layout = QVBoxLayout()
        metode_layout.addWidget(self.radio_tunai)
        metode_layout.addWidget(self.radio_credit)
        metode_layout.addWidget(self.radio_debit)
        metode_group.setLayout(metode_layout)

        self.metode_button_group = QButtonGroup()
        self.metode_button_group.addButton(self.radio_tunai)
        self.metode_button_group.addButton(self.radio_credit)
        self.metode_button_group.addButton(self.radio_debit)

        # === FORM TUNAI ===
        self.groupbox_tunai = QGroupBox("Pembayaran Tunai")
        form_tunai = QFormLayout()
        self.input_total_tunai = QLineEdit()

        # self.diskon_tambahan_tunai = QLineEdit()
        self.diskon_tambahan_tunai = QSpinBox()
        self.diskon_tambahan_tunai.setSuffix(" %")
        self.diskon_tambahan_tunai.setMaximum(30)

        self.diskon_tambahan_rp_tunai = QLineEdit()
        self.potongan_voucher_tunai = QLineEdit()
        self.ppn_tunai = QLineEdit()
        self.input_total_harus_dibayar_tunai = QLineEdit()
        self.input_bayar_tunai = QLineEdit()
        self.input_kembalian_tunai = QLineEdit()
        form_tunai.addRow("Total Produk:", self.input_total_tunai)
        form_tunai.addRow("Diskon Tambahan (max 30%):", self.diskon_tambahan_tunai)
        form_tunai.addRow("Diskon Tambahan (Rp):", self.diskon_tambahan_rp_tunai)
        self.nilai_ppn = str(get_ppn_percent_for_view(default=11))
        # edited by glg
        self.label_ppn_tunai = QLabel("")
        form_tunai.addRow(self.label_ppn_tunai, self.ppn_tunai)
        form_tunai.addRow("Potongan Voucher:", self.potongan_voucher_tunai)
        # form_tunai.addRow("Nilai PPn :", self.ppn_tunai)

        form_tunai.addRow("Total Harus Dibayar:", self.input_total_harus_dibayar_tunai)
        form_tunai.addRow("Bayar Tunai:", self.input_bayar_tunai)
        form_tunai.addRow("Kembalian:", self.input_kembalian_tunai)
        self.groupbox_tunai.setLayout(form_tunai)

        # === FORM CREDIT ===
        self.groupbox_credit = QGroupBox("Pembayaran Credit Card")
        form_credit = QFormLayout()
        self.input_total_credit = QLineEdit()
        # self.diskon_tambahan_credit = QLineEdit()
        self.diskon_tambahan_credit = QSpinBox()
        self.diskon_tambahan_credit.setSuffix(" %")
        self.diskon_tambahan_credit.setMaximum(30)

        self.diskon_tambahan_rp_credit = QLineEdit()
        self.potongan_voucher_credit = QLineEdit()
        self.ppn_credit = QLineEdit()
        self.input_total_harus_dibayar_credit = QLineEdit()
        self.input_no_kartu_credit = QLineEdit()
        self.input_approval_credit = QLineEdit()
        form_credit.addRow("Total Produk:", self.input_total_credit)
        form_credit.addRow("Diskon Tambahan (max 30%):", self.diskon_tambahan_credit)
        form_credit.addRow("Diskon Tambahan (Rp):", self.diskon_tambahan_rp_credit)
        # form_credit.addRow("Diskon (%):", self.diskon_tambahan_credit)
        # nilai_ppn =  str(get_ppn_from_profile(get_db_path()))
        # edited by glg
        self.label_ppn_credit = QLabel("")
        form_credit.addRow(self.label_ppn_credit, self.ppn_credit)
        form_credit.addRow("Potongan Voucher:", self.potongan_voucher_credit)

        # form_credit.addRow("PPN (%):", self.ppn_credit)
        form_credit.addRow("Total Bayar:", self.input_total_harus_dibayar_credit)
        form_credit.addRow("No. Kartu:", self.input_no_kartu_credit)
        form_credit.addRow("Approval Code:", self.input_approval_credit)

        credit_inner_layout = QGridLayout()
        credit_inner_layout.addLayout(form_credit, 0, 0)

        jenis_kartu_credit = QGroupBox("Jenis Credit Card")
        jenis_kartu_layout_credit = QVBoxLayout()

        # Ambil daftar bank dari query
        credit_card_names = get_credit_card_names()

        # Simpan radio button dalam list supaya bisa diakses lagi
        self.radio_credit_cards = []

        for idx, bank_name in enumerate(credit_card_names):
            radio_btn = QRadioButton(bank_name)
            if idx == 0:  # Radio pertama di-set terpilih default
                radio_btn.setChecked(True)
            jenis_kartu_layout_credit.addWidget(radio_btn)
            self.radio_credit_cards.append(radio_btn)

        jenis_kartu_credit.setLayout(jenis_kartu_layout_credit)
        credit_inner_layout.addWidget(jenis_kartu_credit, 0, 1)


        receive_credit = QGroupBox("Receive on Account")
        receive_layout_credit = QVBoxLayout()

        # Ambil daftar EDC dari query
        receive_names = get_receive_on_account_names()

        # Simpan radio button supaya bisa diakses nanti
        self.radio_receive_accounts = []

        for idx, receive_name in enumerate(receive_names):
            radio_btn = QRadioButton(receive_name)
            self.log_debug(f"edc idx {idx} = {receive_name}")
            if idx == 0:  # Pilih default radio pertama
                radio_btn.setChecked(True)
            receive_layout_credit.addWidget(radio_btn)
            self.radio_receive_accounts.append(radio_btn)

        receive_credit.setLayout(receive_layout_credit)
        credit_inner_layout.addWidget(receive_credit, 0, 2)


        self.groupbox_credit.setLayout(credit_inner_layout)

        # === FORM DEBIT ===
        self.groupbox_debit = QGroupBox("Pembayaran Debit Card")
        form_debit = QFormLayout()
        self.input_total_debit = QLineEdit()
        # self.diskon_tambahan_debit = QLineEdit()
        self.diskon_tambahan_debit = QSpinBox()
        self.diskon_tambahan_debit.setSuffix(" %")
        self.diskon_tambahan_debit.setMaximum(100)
        # self.diskon_tambahan_debit.valueChanged.connect(self.update_ringkasan)

        self.diskon_tambahan_rp_debit = QLineEdit()
        self.potongan_voucher_debit = QLineEdit()
        self.ppn_debit = QLineEdit()
        self.input_total_harus_dibayar_debit = QLineEdit()
        self.input_no_kartu_debit = QLineEdit()
        self.input_approval_debit = QLineEdit()
        form_debit.addRow("Total Produk:", self.input_total_debit)
        form_debit.addRow("Diskon Tambahan (max 30%):", self.diskon_tambahan_debit)
        form_debit.addRow("Diskon Tambahan (Rp):", self.diskon_tambahan_rp_debit)
        # form_debit.addRow("Diskon Tambahan (Rp):", self.diskon_tambahan_debit)

        # nilai_ppn =  str(get_ppn_from_profile(get_db_path()))
        # edited by glg
        self.label_ppn_debit = QLabel("")
        form_debit.addRow(self.label_ppn_debit, self.ppn_debit)
        form_debit.addRow("Potongan Voucher:", self.potongan_voucher_debit)
        # form_debit.addRow("Diskon Member (%):", self.ppn_debit)
        form_debit.addRow("Total Bayar:", self.input_total_harus_dibayar_debit)
        form_debit.addRow("No. Kartu:", self.input_no_kartu_debit)
        form_debit.addRow("Approval Code:", self.input_approval_debit)

        debit_inner_layout = QGridLayout()
        debit_inner_layout.addLayout(form_debit, 0, 0)

        jenis_debit = QGroupBox("Jenis Debit Card")
        jenis_debit_layout = QVBoxLayout()

        # Ambil daftar debit card dari query
        debit_names = get_debit_card_names()

        # Simpan radio button supaya bisa diakses nanti
        self.radio_debit_cards = []

        for idx, debit_name in enumerate(debit_names):
            radio_btn = QRadioButton(debit_name)
            if idx == 0:  # Default pilih pertama
                radio_btn.setChecked(True)
            jenis_debit_layout.addWidget(radio_btn)
            self.radio_debit_cards.append(radio_btn)

        jenis_debit.setLayout(jenis_debit_layout)
        debit_inner_layout.addWidget(jenis_debit, 0, 1)

        receive_debit = QGroupBox("Receive on Account")
        receive_debit_layout = QVBoxLayout()

        # Ambil daftar receive on account dari query
        receive_names = get_receive_on_account_debit()

        # Simpan radio button untuk akses nanti
        self.radio_receive_debit = []

        for idx, receive_name in enumerate(receive_names):
            radio_btn = QRadioButton(receive_name)
            if idx == 0:  # default pilih pertama
                radio_btn.setChecked(True)
            receive_debit_layout.addWidget(radio_btn)
            self.radio_receive_debit.append(radio_btn)

        receive_debit.setLayout(receive_debit_layout)
        debit_inner_layout.addWidget(receive_debit, 0, 2)


        self.groupbox_debit.setLayout(debit_inner_layout)

        # === Stack Layout
        self.stacked_layout = QStackedLayout()
        self.stacked_layout.addWidget(self.groupbox_tunai)
        self.stacked_layout.addWidget(self.groupbox_credit)
        self.stacked_layout.addWidget(self.groupbox_debit)

        self.radio_tunai.toggled.connect(lambda checked: self.update_stacked_layout("tunai") if checked else None)
        self.radio_credit.toggled.connect(lambda checked: self.update_stacked_layout("credit") if checked else None)
        self.radio_debit.toggled.connect(lambda checked: self.update_stacked_layout("debit") if checked else None)

        metode_dan_form = QHBoxLayout()
        metode_dan_form.addWidget(metode_group)
        metode_dan_form.addLayout(self.stacked_layout)
        self.main_layout.addLayout(metode_dan_form)

        # === Tombol
        tombol_layout = QHBoxLayout()
        self.batal_btn = QPushButton("Batal")
        self.batal_btn.setProperty("class", "pembayaran-batal")
        self.ok_btn = QPushButton("Lanjutkan Pembayaran")
        self.ok_btn.setProperty("class", "pembayaran-ok")
        self.batal_btn.clicked.connect(self.reject)
        self.ok_btn.clicked.connect(self.on_ok_pressed)

        # Set tombol OK sebagai default button (akan aktif saat tekan Enter)
        self.ok_btn.setDefault(True)
        self.ok_btn.setAutoDefault(True)

        tombol_layout.addStretch()
        tombol_layout.addWidget(self.batal_btn)
        tombol_layout.addWidget(self.ok_btn)

        self.main_layout.addLayout(tombol_layout)
        self.setLayout(self.main_layout)
        # edited by glg
        self.set_ppn_mode(
            mode=get_ppn_mode(default="include"),
            percent=int(self.nilai_ppn or 11),
        )
        # self.input_total_tunai.setReadOnly(True) # bisa jalan

    def keyPressEvent(self, event):
        # Hanya Enter dan Esc, tidak ada shortcut lain
        if event.key() in (Qt.Key_Return, Qt.Key_Enter):
            self.ok_btn.click()
            event.accept()
        elif event.key() == Qt.Key_Escape:
            self.reject()
            event.accept()
        else:
            super().keyPressEvent(event)

    def atur_style_form(self):
        self.log_debug("masuk atur style")

        from pypos.core.utils.myhelper import set_readonly_style  # jika helper-nya kamu simpan di file terpisah
        set_readonly_style(self.input_total_tunai, True)
        self.log_debug(
            f"input_total_tunai type={type(self.input_total_tunai)} "
            f"enabled={self.input_total_tunai.isEnabled()} "
            f"readonly={getattr(self.input_total_tunai, 'isReadOnly', lambda: 'n/a')()}"
        )

        set_readonly_style(self.diskon_tambahan_tunai, False)
        self.log_debug(
            f"diskon_tambahan_tunai type={type(self.diskon_tambahan_tunai)} "
            f"enabled={self.diskon_tambahan_tunai.isEnabled()} "
            f"readonly={getattr(self.diskon_tambahan_tunai, 'isReadOnly', lambda: 'n/a')()}"
        )

        # edited by glg
        # Diskon tambahan nominal bisa diinput manual.
        set_readonly_style(self.diskon_tambahan_rp_tunai, False)
        set_readonly_style(self.ppn_tunai, True)
        set_readonly_style(self.potongan_voucher_tunai, True)
        set_readonly_style(self.input_total_harus_dibayar_tunai, True)
        set_readonly_style(self.input_bayar_tunai, False)
        set_readonly_style(self.input_kembalian_tunai, True)

        set_readonly_style(self.input_total_credit, True)
        set_readonly_style(self.diskon_tambahan_credit, False)
        # edited by glg
        # Diskon tambahan nominal bisa diinput manual.
        set_readonly_style(self.diskon_tambahan_rp_credit, False)
        set_readonly_style(self.ppn_credit, True)
        set_readonly_style(self.potongan_voucher_credit, True)
        set_readonly_style(self.input_total_harus_dibayar_credit, True)
        set_readonly_style(self.input_no_kartu_credit, False)  # No kartu tetap bisa input
        set_readonly_style(self.input_approval_credit, False)  # Approval code tetap bisa input

        set_readonly_style(self.input_total_debit, True)
        set_readonly_style(self.diskon_tambahan_debit, False)
        # edited by glg
        # Diskon tambahan nominal bisa diinput manual.
        set_readonly_style(self.diskon_tambahan_rp_debit, False)
        set_readonly_style(self.ppn_debit, True)
        set_readonly_style(self.potongan_voucher_debit, True)
        set_readonly_style(self.input_total_harus_dibayar_debit, True)
        set_readonly_style(self.input_no_kartu_debit, False)  # No kartu tetap bisa input
        set_readonly_style(self.input_approval_debit, False)  # Approval code tetap bisa input

    def set_voucher_code_row_visible(self, visible: bool):
        if hasattr(self, "info_layout"):
            self.info_layout.setRowVisible(self._voucher_code_label, visible)
            self.info_layout.setRowVisible(self.voucher_input, visible)

    def set_voucher_detail_rows_visible(self, visible: bool):
        if hasattr(self, "info_layout"):
            self.info_layout.setRowVisible(self._voucher_saldo_label, visible)
            self.info_layout.setRowVisible(self.voucher_saldo_label, visible)
            self.info_layout.setRowVisible(self._voucher_amount_label, visible)
            self.info_layout.setRowVisible(self.voucher_amount_input, visible)

    def set_voucher_section_visible(self, visible: bool):
        self.set_voucher_code_row_visible(visible)
        self.set_voucher_detail_rows_visible(visible)

    def set_voucher_rows_visible(self, visible: bool):
        self.set_voucher_detail_rows_visible(visible)

    # edited by glg
    def set_ppn_mode(self, mode: str, percent: int):
        mode_value = str(mode or "include").strip().lower()
        if mode_value not in {"include", "exclude"}:
            mode_value = "include"
        try:
            ppn_percent = int(percent)
        except Exception:
            ppn_percent = 11
        if ppn_percent < 0:
            ppn_percent = 0

        if mode_value == "include":
            label_text = f"Termasuk PPN ({ppn_percent}%):"
        else:
            label_text = f"PPN {ppn_percent}%:"

        for attr_name in ("label_ppn_tunai", "label_ppn_credit", "label_ppn_debit"):
            label = getattr(self, attr_name, None)
            if label is not None:
                label.setText(label_text)

    def update_stacked_layout(self, mode):
        if mode == "tunai":
            self.stacked_layout.setCurrentWidget(self.groupbox_tunai)
            self.controller.cek_radiobutton("tunai")
        elif mode == "credit":
            self.stacked_layout.setCurrentWidget(self.groupbox_credit)
            self.controller.cek_radiobutton("credit")
        elif mode == "debit":
            self.stacked_layout.setCurrentWidget(self.groupbox_debit)
            self.controller.cek_radiobutton("debit")

    def on_ok_pressed(self):
        self.controller.process_payment()

    def format_rupiah(self, angka: float) -> str:
        """Mengubah angka float ke format rupiah lokal seperti 12.345,67"""
        return f"{angka:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")

    def parse_rupiah(self, text: str) -> float:
        """Konversi string rupiah lokal ke float (dipakai controller)."""
        if not text:
            return 0.0
        try:
            cleaned = text.replace(".", "").replace(",", ".")
            return float(cleaned)
        except Exception:
            return 0.0

    def ask_split_payment(self, metode_text: str, short_text: str) -> bool:
        """Tampilkan konfirmasi split payment."""
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setWindowTitle("Pembayaran Kurang")
        msg.setText(f"Pembayaran {metode_text} kurang {short_text}.\nApakah Anda ingin membayar sisanya dengan metode lain?")
        msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        return msg.exec() == QMessageBox.Yes

    def warn_payment_not_enough(self, metode_text: str, total_dibayar: float, jumlah_dibayar: float, kurang: float):
        """Tampilkan peringatan pembayaran kurang."""
        QMessageBox.warning(
            self,
            "Pembayaran Tidak Cukup",
            (
                f"Pembayaran {metode_text} tidak boleh kurang dari total yang harus dibayar.\n\n"
                f"Total: {self.format_rupiah(total_dibayar)}\n"
                f"Dibayar: {self.format_rupiah(jumlah_dibayar)}\n"
                f"Kurang: {self.format_rupiah(kurang)}"
            ),
        )

    def prepare_split_payment_ui(self, remaining_amount: float):
        """Siapkan UI untuk input pembayaran sisa."""
        remaining_str = self.format_rupiah(remaining_amount)
        self.input_total_tunai.setEnabled(False)
        self.input_bayar_tunai.setEnabled(False)
        self.radio_tunai.setEnabled(False)

        self.radio_credit.setChecked(True)
        self.input_total_credit.setText(remaining_str)
        self.input_total_harus_dibayar_credit.setText(remaining_str)
        self.input_total_debit.setText(remaining_str)
        self.input_total_harus_dibayar_debit.setText(remaining_str)
        self.setWindowTitle(f"Pembayaran Sisa: {remaining_str}")
