"""
Service untuk menangani seluruh proses cetak/preview struk transaksi agar controller penjualan tetap ringan.
"""
from pathlib import Path
import csv
from typing import Callable, Optional
import logging

LOGGER = logging.getLogger(__name__)


class TransactionPrintService:
    def __init__(self, printer_settings_controller, print_controller_factory: Callable = None):
        self.printer_settings_controller = printer_settings_controller
        self.print_controller_factory = print_controller_factory
        self._print_controller = None

    def _build_default_print_controller(self):
        module = __import__(
            "pypos.modules.printer.controllers.print_controller",
            fromlist=["PrintController"],
        )
        return module.PrintController(self.printer_settings_controller)

    def _get_print_controller(self):
        controller = getattr(self, "_print_controller", None)
        if controller is not None:
            return controller
        factory = self.print_controller_factory
        if callable(factory):
            controller = factory(self.printer_settings_controller)
        else:
            controller = self._build_default_print_controller()
        self._print_controller = controller
        return controller

    # --- Util mode cetak ---
    def get_print_mode_from_csv(self, resources_path: Path) -> str:
        """
        Baca nilai print_mode dari resources/setting_struk.csv; fallback ke 'preview'.
        """
        csv_path = resources_path / "setting_struk.csv"
        try:
            with open(csv_path, newline="", encoding="utf-8") as csvfile:
                reader = csv.reader(csvfile)
                for row in reader:
                    if len(row) >= 2 and row[0].strip() == "print_mode":
                        return row[1].strip().lower()
        except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError) as e:  # pragma: no cover
            LOGGER.error("Gagal membaca print_mode dari CSV: %s", e)
        return "preview"

    def print_transaction(self, transaksi_data, detail_data, transaksi_data_dict, index_printer: Optional[int] = None, copy_no: int = 0):
        self._get_print_controller().print_struk(
            transaksi_data,
            detail_data,
            transaksi_data_dict,
            index_printer=index_printer,
            copy_no=copy_no,
        )

    def preview_transaction(self, transaksi_data, detail_data, transaksi_data_dict, index_printer: Optional[int] = None, parent=None):
        self._get_print_controller().preview_struk(
            transaksi_data,
            detail_data,
            transaksi_data_dict,
            index_printer=index_printer,
            parent=parent,
        )

    def print_last_transaction(self, detail_data, transaksi_data_dict, mode: str, parent=None):
        """
        Cetak/preview struk terakhir berdasarkan mode (print/preview).
        transaksi_data=None untuk layout yang sama dengan preview yang terakhir.
        """
        try:
            if mode == "print":
                self._get_print_controller().print_struk(None, detail_data, transaksi_data_dict)
            else:
                self._get_print_controller().preview_struk(
                    None,
                    detail_data,
                    transaksi_data_dict,
                    parent=parent,
                )
        except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
            LOGGER.exception("print_last_transaction gagal")
