from PyQt5.QtCore import Qt, QTimer, QRectF
from PyQt5.QtGui import QPainter, QColor, QPen, QFont, QLinearGradient
from PyQt5.QtWidgets import (
    QWidget,
    QLabel,
    QVBoxLayout,
    QHBoxLayout,
    QScrollArea,
    QPushButton,
    QSizePolicy,
)

from services.design_academy_service import design_academy_service
from services.forge_learning_service import forge_learning_service
from services.cadquery_engine_service import cadquery_engine_service
from modules.unified_learning import UnifiedLearningDialog
from modules.unified_academy_dashboard import install_unified_academy_dashboard


GREEN = "#00ff72"
PURPLE = "#c02cff"
WHITE = "#ffffff"
DARK = "#020406"
PANEL = "rgba(0, 10, 18, 230)"


class AnimatedForgeBar(QWidget):
    """
    ENG-SHIRE-0001D
    Visual-only animated mastery / XP bar.
    """

    def __init__(self, title, subtitle, value=0, height=62):
        super().__init__()
        self.title = str(title)
        self.subtitle = str(subtitle)
        self.target_value = max(0, min(100, int(value)))
        self.current_value = 0
        self.setMinimumHeight(height)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.animate_step)
        self.timer.start(25)

    def set_value(self, value, subtitle=None):
        self.target_value = max(0, min(100, int(value)))
        if subtitle is not None:
            self.subtitle = str(subtitle)
        self.timer.start(25)

    def animate_step(self):
        if self.current_value < self.target_value:
            self.current_value += 2
        elif self.current_value > self.target_value:
            self.current_value -= 2

        if abs(self.current_value - self.target_value) <= 2:
            self.current_value = self.target_value
            self.timer.stop()

        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        rect = self.rect().adjusted(2, 2, -2, -2)

        painter.setPen(QPen(QColor(GREEN), 2))
        painter.setBrush(QColor(0, 8, 12, 230))
        painter.drawRoundedRect(rect, 12, 12)

        painter.setFont(QFont("monospace", 10, QFont.Bold))
        painter.setPen(QColor(WHITE))
        painter.drawText(rect.adjusted(12, 7, -12, -30), Qt.AlignLeft | Qt.AlignVCenter, self.title)

        painter.setPen(QColor(PURPLE))
        painter.drawText(rect.adjusted(12, 7, -12, -30), Qt.AlignRight | Qt.AlignVCenter, f"{self.current_value}%")

        bar_rect = QRectF(rect.left() + 12, rect.bottom() - 24, rect.width() - 24, 12)
        painter.setPen(QPen(QColor(PURPLE), 1))
        painter.setBrush(QColor(0, 0, 0, 160))
        painter.drawRoundedRect(bar_rect, 6, 6)

        fill_width = bar_rect.width() * (self.current_value / 100.0)
        fill_rect = QRectF(bar_rect.left(), bar_rect.top(), fill_width, bar_rect.height())

        grad = QLinearGradient(fill_rect.left(), fill_rect.top(), fill_rect.right(), fill_rect.bottom())
        grad.setColorAt(0.0, QColor(GREEN))
        grad.setColorAt(1.0, QColor(PURPLE))
        painter.setBrush(grad)
        painter.setPen(Qt.NoPen)
        painter.drawRoundedRect(fill_rect, 6, 6)

        painter.setFont(QFont("monospace", 8, QFont.Bold))
        painter.setPen(QColor(210, 210, 210))
        painter.drawText(rect.adjusted(12, 26, -12, -22), Qt.AlignLeft | Qt.AlignVCenter, self.subtitle)


class ForgeStatCard(QWidget):
    def __init__(self, title, value, sub):
        super().__init__()
        layout = QVBoxLayout()
        layout.setContentsMargins(10, 8, 10, 8)
        layout.setSpacing(3)

        label = QLabel(str(title))
        label.setAlignment(Qt.AlignCenter)
        label.setStyleSheet(f"color:{PURPLE}; font-size:11px; font-weight:900; background:transparent;")

        number = QLabel(str(value))
        number.setAlignment(Qt.AlignCenter)
        number.setStyleSheet(f"color:{GREEN}; font-size:26px; font-weight:900; background:transparent;")

        detail = QLabel(str(sub))
        detail.setAlignment(Qt.AlignCenter)
        detail.setWordWrap(True)
        detail.setStyleSheet("color:#d8d8d8; font-size:9px; font-weight:900; background:transparent;")

        layout.addWidget(label)
        layout.addWidget(number)
        layout.addWidget(detail)

        self.setLayout(layout)
        self.setMinimumHeight(92)
        self.setStyleSheet(f"""
            QWidget {{
                background: {PANEL};
                border: 2px solid {GREEN};
                border-radius: 12px;
            }}
            QLabel {{
                border: none;
            }}
        """)



class AcademyPage(QWidget):
    """Read-only Design Academy library and certification dashboard."""

    def __init__(self, stack):
        super().__init__()
        self.stack = stack
        self.bars = []
        self.build_ui()

        self.refresh_timer = QTimer(self)
        self.refresh_timer.timeout.connect(self.refresh_dashboard)
        self.refresh_timer.start(2500)

        self.refresh_dashboard()

    def build_ui(self):
        self.setStyleSheet(f"""
            QWidget {{
                background: {DARK};
                color: {WHITE};
                font-family: monospace;
            }}
            QLabel {{
                color: {WHITE};
                background: transparent;
                font-family: monospace;
            }}
            QPushButton {{
                background: rgba(0, 24, 14, 230);
                color: {GREEN};
                border: 3px solid {GREEN};
                border-radius: 12px;
                font-size: 14px;
                font-weight: 900;
                padding: 10px;
            }}
            QPushButton:hover {{
                color: {PURPLE};
                border: 3px solid {PURPLE};
                background: rgba(38, 0, 70, 235);
            }}
        """)

        root = QVBoxLayout()
        root.setContentsMargins(18, 12, 18, 12)
        root.setSpacing(10)

        header = QHBoxLayout()

        title = QLabel("✦ ACADEMY DESIGN MASTERY")
        title.setStyleSheet(f"color:{GREEN}; font-size:28px; font-weight:900;")

        self.mode = QLabel("LIBRARY CONNECTED • FORGE LOCKED UNTIL CERTIFIED")
        self.mode.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.mode.setStyleSheet(f"color:{PURPLE}; font-size:15px; font-weight:900;")

        header.addWidget(title, 2)
        header.addWidget(self.mode, 1)
        root.addLayout(header)

        self.oath = QLabel(
            "Academy law: reading is not mastery. SHiRE must practise, validate, record provenance "
            "and pass safety gates before any skill can become available to Forge."
        )
        self.oath.setAlignment(Qt.AlignCenter)
        self.oath.setWordWrap(True)
        self.oath.setStyleSheet(f"""
            QLabel {{
                color:{WHITE};
                background:{PANEL};
                border:2px solid {PURPLE};
                border-radius:10px;
                padding:9px;
                font-size:13px;
                font-weight:900;
            }}
        """)
        root.addWidget(self.oath)

        self.xp_bar = AnimatedForgeBar(
            "LIBRARY INTEGRITY",
            "Checking the installed Design Academy index...",
            0,
            70,
        )
        root.addWidget(self.xp_bar)

        self.mastery_bar = AnimatedForgeBar(
            "FORGE CERTIFICATION PROGRESS",
            "No skill is unlocked by reading alone.",
            0,
            70,
        )
        root.addWidget(self.mastery_bar)

        self.practice_bar = AnimatedForgeBar(
            "PRACTICE PROGRESS",
            "The controlled practice queue has not been initialised.",
            0,
            70,
        )
        root.addWidget(self.practice_bar)

        stats = QHBoxLayout()
        stats.setSpacing(8)

        self.stat_domains = ForgeStatCard("DOMAINS", "0", "Design disciplines")
        self.stat_skills = ForgeStatCard("SKILLS", "0", "Structured skill packs")
        self.stat_cards = ForgeStatCard("CARDS", "0", "Searchable knowledge")
        self.stat_practised = ForgeStatCard("PRACTISED", "0", "Completed practice attempts")
        self.stat_certified = ForgeStatCard("CERTIFIED", "0", "Forge-eligible skills")

        stats.addWidget(self.stat_domains)
        stats.addWidget(self.stat_skills)
        stats.addWidget(self.stat_cards)
        stats.addWidget(self.stat_practised)
        stats.addWidget(self.stat_certified)

        root.addLayout(stats)

        section = QLabel("INSTALLED DESIGN DOMAINS")
        section.setStyleSheet(
            f"color:{GREEN}; font-size:17px; font-weight:900; padding-top:8px;"
        )
        root.addWidget(section)

        self.scroll = QScrollArea()
        self.scroll.setWidgetResizable(True)
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scroll.setStyleSheet("""
            QScrollArea {
                border: none;
                background: transparent;
            }
        """)

        self.list_holder = QWidget()
        self.list_layout = QVBoxLayout()
        self.list_layout.setContentsMargins(0, 0, 0, 0)
        self.list_layout.setSpacing(8)
        self.list_holder.setLayout(self.list_layout)
        self.scroll.setWidget(self.list_holder)

        root.addWidget(self.scroll, 1)

        buttons = QHBoxLayout()

        refresh = QPushButton("REFRESH")
        refresh.clicked.connect(self.refresh_dashboard)

        # SHIRE-UNIFIED-LEARNING-0002: Academy launch action
        unified_learning = QPushButton("SHIRE LEARN")
        unified_learning.setToolTip("Create a real custom learning plan")
        unified_learning.clicked.connect(
            lambda: UnifiedLearningDialog.open_for_prompt("", self)
        )

        tasks = QPushButton("OPEN TASKS")
        tasks.clicked.connect(lambda: self.stack.setCurrentIndex(8))

        home = QPushButton("↩ RETURN")
        home.clicked.connect(lambda: self.stack.setCurrentIndex(0))

        buttons.addWidget(unified_learning)
        buttons.addWidget(refresh)
        buttons.addWidget(tasks)
        buttons.addWidget(home)
        root.addLayout(buttons)

        self.setLayout(root)

        # SHIRE-UNIFIED-LEARNING-0003: calm unified Academy dashboard
        install_unified_academy_dashboard(self)

    def clear_skill_bars(self):
        while self.list_layout.count():
            item = self.list_layout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()
        self.bars = []

    def add_empty_bar(self, message="Design Academy index unavailable."):
        bar = AnimatedForgeBar("DESIGN ACADEMY UNAVAILABLE", str(message), 0)
        self.list_layout.addWidget(bar)
        self.bars.append(bar)

    def refresh_dashboard(self):
        design = design_academy_service.dashboard_data()
        legacy = forge_learning_service.mastery_dashboard_data()

        integrity = design.get("library_integrity_percent", 0)
        certification = design.get("certification_percent", 0)
        practice = design.get("practice") or {}
        cadquery = cadquery_engine_service.status()

        if cadquery.get("available"):
            self.mode.setText(
                f"CADQUERY {cadquery.get('engine_version') or 'ONLINE'} PRIMARY • BLENDER NOT REQUIRED"
            )
        else:
            self.mode.setText("CADQUERY PRIMARY ENGINE UNAVAILABLE • FORGE REMAINS LOCKED")

        self.xp_bar.set_value(
            integrity,
            (
                f"{design.get('domains', 0)} domains • "
                f"{design.get('skills', 0)} skills • "
                f"{design.get('knowledge_cards', 0)} cards"
            ),
        )
        self.mastery_bar.set_value(
            certification,
            (
                f"{design.get('certified_skills', 0)} of "
                f"{design.get('skills', 0)} skills Forge-certified • "
                f"{practice.get('knowledge_certified_skills', 0)} knowledge-certified"
            ),
        )
        self.practice_bar.set_value(
            practice.get("practice_percent", 0),
            (
                f"{practice.get('practised_skills', 0)} of "
                f"{practice.get('total_skills', design.get('skills', 0))} skills practised • "
                f"{practice.get('pending_skills', 0)} pending • "
                f"{practice.get('failed_skills', 0)} need retry • "
                f"{practice.get('cadquery_candidate_skills', 0)} awaiting CadQuery evidence"
            ),
        )

        self.stat_domains.layout().itemAt(1).widget().setText(
            str(design.get("domains", 0))
        )
        self.stat_skills.layout().itemAt(1).widget().setText(
            str(design.get("skills", 0))
        )
        self.stat_cards.layout().itemAt(1).widget().setText(
            str(design.get("knowledge_cards", 0))
        )
        self.stat_practised.layout().itemAt(1).widget().setText(
            str(practice.get("practised_skills", 0))
        )
        self.stat_certified.layout().itemAt(1).widget().setText(
            str(design.get("certified_skills", 0))
        )

        self.clear_skill_bars()

        rows = design.get("domain_rows", [])
        if not design.get("available") or not rows:
            self.add_empty_bar(design.get("error") or "No domain records were returned.")
        else:
            for row in rows:
                title = str(row.get("domain_name") or row.get("domain_id")).upper()
                subtitle = (
                    f"{row.get('skill_count', 0)} skills • "
                    f"{row.get('practised_count', 0)} practised • "
                    f"{row.get('knowledge_certified_count', 0)} knowledge-certified • "
                    f"{row.get('certified_count', 0)} Forge-certified"
                )
                bar = AnimatedForgeBar(title, subtitle, row.get("progress", 0))
                self.list_layout.addWidget(bar)
                self.bars.append(bar)

        legacy_counts = legacy.get("counts", {})
        if legacy_counts.get("total", 0):
            bar = AnimatedForgeBar(
                "ACTIVE LEGACY PRACTICE QUEUE",
                (
                    f"{legacy_counts.get('total', 0)} requests • "
                    f"{legacy_counts.get('sandbox_packs', 0)} sandbox packs • "
                    "tracked separately"
                ),
                legacy.get("overall_progress", 0),
            )
            self.list_layout.addWidget(bar)
            self.bars.append(bar)

        self.list_layout.addStretch()

    def paintEvent(self, event):
        painter = QPainter(self)
        rect = self.rect()

        grad = QLinearGradient(0, 0, rect.width(), rect.height())
        grad.setColorAt(0.0, QColor(0, 12, 8))
        grad.setColorAt(0.5, QColor(14, 0, 26))
        grad.setColorAt(1.0, QColor(0, 12, 8))

        painter.fillRect(rect, grad)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(QColor(GREEN), 2))
        painter.drawRoundedRect(rect.adjusted(6, 6, -6, -6), 18, 18)
        painter.setPen(QPen(QColor(PURPLE), 2))
        painter.drawRoundedRect(rect.adjusted(12, 12, -12, -12), 14, 14)

        super().paintEvent(event)
