import logging
import requests
from pypos.core.utils.config_utils import read_config
from pypos.core.utils.http_retry import get_with_retry
from pypos.core.utils.db_helper import connect_sqlite
from pypos.core.utils.sql_identifier_utils import quote_sql_identifier
from pypos.core.utils.sql_query_builder import build_pragma_table_info_sql, render_sql_template
from PySide6.QtWidgets import QDialog, QMessageBox, QWidget
from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QLabel, QComboBox, QTableWidget, QTableWidgetItem,
    QPushButton, QHBoxLayout, QLineEdit, QSpinBox, QHeaderView, QDialog,
    QFormLayout, QDialogButtonBox, QCheckBox, QFrame, QAbstractItemView,
    QCompleter ,QPlainTextEdit,QRadioButton,QGroupBox, QMessageBox
)
import sqlite3

LOGGER = logging.getLogger(__name__)

class SettlementChecker(QThread):
    hasil_cek = Signal(list)

    def run(self):
        try:
            config = read_config() or {}
            url = config.get("settlement_check_url")
            if not url:
                LOGGER.warning("settlement_check_url belum dikonfigurasi, skip cek settlement.")
                self.hasil_cek.emit([])
                return
            timeout = int(config.get("request_timeout", 5))
            response = get_with_retry(url, timeout=timeout)
            LOGGER.debug("Settlement checker status HTTP: %s", response.status_code)
            if response.status_code == 200:
                try:
                    data = response.json()
                except (ValueError, TypeError) as e:
                    LOGGER.warning("Response settlement bukan JSON: %s", e)
                    self.hasil_cek.emit([])
                    return
                LOGGER.debug("Settlement checker payload diterima (len=%s)", len(data) if isinstance(data, list) else 1)
                self.hasil_cek.emit(data)
            else:
                self.hasil_cek.emit([])
        except (requests.exceptions.RequestException, RuntimeError, ValueError, TypeError, OSError) as e:
            LOGGER.warning("Error saat memeriksa settlement: %s", e)
            self.hasil_cek.emit([])


class SettlementHandler:
    def __init__(self, form_widget: QWidget, transaksi_modal: QDialog):
        self.form_widget = form_widget
        self.transaksi_modal = transaksi_modal

    # edited by glg
    def _table_has_columns(self, cursor, table_name, required_columns):
        try:
            cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,))
            if cursor.fetchone() is None:
                return False
            cursor.execute(f"PRAGMA table_info({table_name})")
            cols = {str(row[1]) for row in cursor.fetchall()}
            for col in required_columns:
                if col not in cols:
                    return False
            return True
        except (sqlite3.Error, ValueError):
            return False

    # edited by glg
    def _resolve_settlement_source(self, cursor):
        base_required = ("jenis_label", "settlement_id", "dtime")
        if self._table_has_columns(cursor, "transaksi", base_required):
            return "transaksi"
        if self._table_has_columns(cursor, "transaksi_copy", base_required):
            return "transaksi_copy"
        return ""

    def cek_transaksi_settlement(self):
        conn = None
        cursor = None
        try:
            from pypos.core.utils.path_utils import get_db_path
            conn = connect_sqlite(get_db_path())
            LOGGER.debug("DB Path settlement checker: %s", get_db_path())
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()

            table_name = self._resolve_settlement_source(cursor)
            if not table_name:
                LOGGER.warning("Tabel settlement source tidak ditemukan (transaksi/transaksi_copy).")
                return []

            filter_trash = ""
            try:
                table_sql = quote_sql_identifier(table_name, strict=True)
            except ValueError:
                LOGGER.warning("Nama tabel settlement tidak valid: %s", table_name)
                return []
            try:
                cursor.execute(build_pragma_table_info_sql(table_name))
                table_cols = {str(row[1]) for row in cursor.fetchall()}
                if "trash" in table_cols:
                    filter_trash = " AND COALESCE(trash, 0) = 0 "
                elif "is_deleted" in table_cols:
                    filter_trash = " AND COALESCE(is_deleted, 0) = 0 "
            except (sqlite3.Error, ValueError):
                filter_trash = ""

            query = render_sql_template(
                """
                SELECT * FROM {table_name}
                WHERE jenis_label = 'invoice'
                  AND settlement_id = 1
                  AND DATE(dtime) <= DATE('now')
                  {filter_trash}
                """,
                table_name=table_sql,
                filter_trash=filter_trash,
            )
            cursor.execute(query)
            hasil = cursor.fetchall()

            result = [dict(row) for row in hasil]

            LOGGER.debug(
                "Settlement checker source=%s menemukan %s transaksi belum settle",
                table_name,
                len(result),
            )
            return result

        except sqlite3.Error as db_err:
            LOGGER.warning("Kesalahan koneksi/query SQLite settlement: %s", db_err)
            return []

        finally:
            if cursor:
                cursor.close()
            if conn:
                conn.close()

    def cek_status_settlement(self):
        data = self.cek_transaksi_settlement()
        self.settlement_result(data)

    def settlement_result(self, data):
        LOGGER.debug("Settlement result diproses, jumlah data=%s", len(data))
        if len(data) > 0:
            QMessageBox.warning(
                self.form_widget,
                "Perhatian",
                "Ada transaksi yang belum diselesaikan. Silakan selesaikan terlebih dahulu."
            )
            self.nonaktifkan_form()
            self.transaksi_modal.open_with_disabled_form()
        else:
            LOGGER.debug("Tidak ada transaksi unsettled, form diaktifkan")
            self.aktifkan_form()

    def nonaktifkan_form(self):
        widget_types = [QLineEdit, QComboBox, QPushButton]
        for widget_type in widget_types:
            for widget in self.form_widget.findChildren(widget_type):
                try:
                    widget.setEnabled(False)
                except (AttributeError, RuntimeError) as e:
                    LOGGER.debug("Skip widget saat nonaktifkan form: %s", e)

    def aktifkan_form(self):
        widget_types = [QLineEdit, QComboBox, QPushButton]
        for widget_type in widget_types:
            for widget in self.form_widget.findChildren(widget_type):
                widget.setEnabled(True)
