# styles/style_manager.py
from PySide6.QtCore import QObject
import logging

LOGGER = logging.getLogger(__name__)


class StyleManager(QObject):
    """Manager untuk mengelola stylesheet aplikasi"""

    # Theme colors
    THEMES = {
        "default": {
            "primary": "#28a745",
            "secondary": "#6c757d",
            "success": "#28a745",
            "danger": "#dc3545",
            "warning": "#ffc107",
            "info": "#17a2b8",
            "light": "#f8f9fa",
            "dark": "#343a40",
            "background": "#ffffff",
            "text": "#212529"
        },
        "dark": {
            "primary": "#0d6efd",
            "secondary": "#6c757d",
            "success": "#198754",
            "danger": "#dc3545",
            "warning": "#ffc107",
            "info": "#0dcaf0",
            "light": "#f8f9fa",
            "dark": "#212529",
            "background": "#1a1d20",
            "text": "#ffffff"
        },
        "blue": {
            "primary": "#3498db",
            "secondary": "#2c3e50",
            "success": "#27ae60",
            "danger": "#e74c3c",
            "warning": "#f39c12",
            "info": "#17a2b8",
            "light": "#ecf0f1",
            "dark": "#2c3e50",
            "background": "#ffffff",
            "text": "#2c3e50"
        }
    }

    @classmethod
    def get_label_style(cls, style_type="default"):
        colors = cls.THEMES.get(style_type, cls.THEMES["default"])

        return f"""
            QLabel {{
                color: {colors['text']};
                font-weight: 600;
                font-size: 14px;
                padding: 8px 0px 4px 0px;
            }}
            QLabel:disabled {{
                color: {colors['secondary']};
                opacity: 0.6;
            }}
        """

    @classmethod
    def get_input_style(cls, style_type="default"):
        colors = cls.THEMES.get(style_type, cls.THEMES["default"])
        # edited by glg
        # Qt menggunakan format warna 8-digit #AARRGGBB.
        # Jangan gunakan pola #RRGGBBAA karena menghasilkan warna tidak konsisten.
        secondary_50 = cls._with_alpha(colors.get("secondary"), "50")
        primary_80 = cls._with_alpha(colors.get("primary"), "80")
        light_20 = cls._with_alpha(colors.get("light"), "20")
        light_10 = cls._with_alpha(colors.get("light"), "10")
        secondary_20 = cls._with_alpha(colors.get("secondary"), "20")
        secondary_30 = cls._with_alpha(colors.get("secondary"), "30")
        background = str(colors.get("background") or "#ffffff")

        return f"""
            QLineEdit {{
                padding: 10px 12px;
                border: 2px solid {secondary_50};
                border-radius: 8px;
                font-size: 14px;
                background-color: {background};
                color: {colors['text']};
                selection-background-color: {colors['primary']};
            }}
            QLineEdit:focus {{
                border-color: {colors['primary']};
                background-color: {light_20};
            }}
            QLineEdit:hover {{
                border-color: {primary_80};
                background-color: {light_10};
            }}
            QLineEdit:disabled {{
                background-color: {secondary_20};
                color: {colors['secondary']};
                border-color: {secondary_30};
            }}
            QLineEdit::placeholder {{
                color: {colors['secondary']};
                font-style: italic;
            }}
        """

    @classmethod
    def get_button_style(cls, style_type="default", button_type="primary"):
        colors = cls.THEMES.get(style_type, cls.THEMES["default"])
        disabled_bg = "#e9edf3"
        disabled_text = "#8b98a9"
        disabled_border = "#c8d1dd"

        if button_type == "primary":
            bg_color = colors['primary']
            hover_color = cls._darken_color(bg_color, 20)
            pressed_color = cls._darken_color(bg_color, 30)
        elif button_type == "secondary":
            bg_color = colors['secondary']
            hover_color = cls._darken_color(bg_color, 20)
            pressed_color = cls._darken_color(bg_color, 30)
        else:
            bg_color = colors['light']
            hover_color = cls._with_alpha(colors.get("secondary"), "20")
            pressed_color = cls._with_alpha(colors.get("secondary"), "30")

        return f"""
            QPushButton {{
                background-color: {bg_color};
                color: white;
                font-weight: bold;
                padding: 10px 20px;
                border-radius: 8px;
                border: none;
                font-size: 14px;
            }}
            QPushButton:hover {{
                background-color: {hover_color};
            }}
            QPushButton:pressed {{
                background-color: {pressed_color};
            }}
            QPushButton:disabled {{
                background-color: {disabled_bg};
                color: {disabled_text};
                border: 1px solid {disabled_border};
            }}
            QPushButton[compactButton="true"] {{
                min-width: 1px;
                padding: 6px 10px;
                font-size: 12px;
                border-radius: 6px;
            }}
        """

    @classmethod
    def get_checkbox_style(cls, style_type="default"):
        colors = cls.THEMES.get(style_type, cls.THEMES["default"])
        secondary_50 = cls._with_alpha(colors.get("secondary"), "50")
        secondary_20 = cls._with_alpha(colors.get("secondary"), "20")

        check_image = ":/qt-project.org/styles/commonstyle/images/checkbox-checked.png"
        try:
            from pypos.core.utils.path_utils import get_app_data_resource_dir
            from pypos.core.utils.ui_image_asset_utils import find_related_image_files
            import os
            check_path = os.path.join(get_app_data_resource_dir(), "icons", "checkbox-checked.png")
            related = find_related_image_files(check_path)
            if related:
                # edited by glg
                # Prefer SVG bila tersedia agar indikator checkbox tetap tajam di DPI tinggi.
                related_sorted = sorted(
                    related,
                    key=lambda p: 0 if str(os.path.splitext(p)[1] or "").lower() == ".svg" else 1,
                )
                resolved = str(related_sorted[0]).replace("\\", "/")
                if os.path.exists(resolved):
                    check_image = resolved
        except Exception as e:
            LOGGER.warning("Gagal resolve icon checkbox: %s", e)

        return f"""
            QCheckBox {{
                spacing: 8px;
                font-size: 13px;
                color: {colors['text']};
            }}
            QCheckBox::indicator {{
                width: 16px;
                height: 16px;
            }}
            QCheckBox::indicator:unchecked {{
                border: 2px solid {colors['secondary']};
                background-color: {colors['light']};
                border-radius: 3px;
                image: none;
            }}
            QCheckBox::indicator:checked {{
                border: 2px solid {colors['primary']};
                background-color: {colors['light']};
                border-radius: 3px;
                image: url("{check_image}");
            }}
            QCheckBox::indicator:hover {{
                border: 2px solid {colors['primary']};
            }}
            QCheckBox:disabled {{
                color: {colors['secondary']};
            }}
            QCheckBox::indicator:disabled {{
                border: 2px solid {secondary_50};
                background-color: {secondary_20};
            }}
        """

    @classmethod
    def get_window_style(cls, style_type="default"):
        colors = cls.THEMES.get(style_type, cls.THEMES["default"])
        background = str(colors.get("background") or "#ffffff")

        return f"""
            QWidget {{
                background-color: {background};
                color: {colors['text']};
            }}
        """

    @staticmethod
    def _with_alpha(hex_color, alpha_hex):
        # edited by glg
        # Konversi warna ke format Qt 8-digit: #AARRGGBB.
        base = str(hex_color or "").strip().lstrip("#")
        alpha = str(alpha_hex or "").strip().lstrip("#")
        if len(base) not in {3, 6}:
            return str(hex_color or "#FFFFFFFF")
        if len(base) == 3:
            base = "".join([c * 2 for c in base])
        if len(alpha) == 1:
            alpha = alpha * 2
        if len(alpha) != 2:
            alpha = "FF"
        return f"#{alpha.upper()}{base.upper()}"

    @staticmethod
    def _darken_color(hex_color, factor=20):
        """Darken a hex color by given factor"""
        hex_color = hex_color.lstrip('#')
        r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16)

        r = max(0, r - factor)
        g = max(0, g - factor)
        b = max(0, b - factor)

        return f"#{r:02x}{g:02x}{b:02x}"

    @classmethod
    def apply_theme(cls, widget, style_type="default"):
        """Apply theme to entire widget"""
        widget.setStyleSheet(cls.get_window_style(style_type))
