"""
통계 대시보드 - 주간/월간 통계
"""
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
                             QPushButton, QGroupBox, QGridLayout, QTabWidget, QWidget,
                             QFrame)
from PyQt5.QtCore import Qt
from datetime import datetime, timedelta
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from core.database import Database
from core.i18n import tr
from ui.styles import apply_dark_titlebar
from ui.dark_components import (
    dialog_qss, tabs_qss, button_qss, build_stat_card, build_section_card,
    transparent_label, tc,
)


class StatsView(QDialog):
    """통계 뷰 다이얼로그"""

    def __init__(self, parent=None, db=None):
        super().__init__(parent)
        self.db = db if db else Database()
        self.init_ui()
        self.load_stats()
        apply_dark_titlebar(self)  # 현재 테마에 맞춰 타이틀바

    def init_ui(self):
        """UI 초기화"""
        self.setWindowTitle(tr('window.stats'))
        self.setModal(True)
        self.setMinimumSize(720, 600)
        self.resize(900, 720)
        self.setStyleSheet(dialog_qss())

        layout = QVBoxLayout()
        layout.setSpacing(10)
        layout.setContentsMargins(20, 16, 20, 14)

        # 다크 톤 타이틀
        title = QLabel(f"{tr('stats.title')}")
        title.setStyleSheet(
            f"font-size: 18pt; font-weight: bold; color: {tc('text')}; "
            f"background: transparent; border: none; padding: 4px 0;"
        )
        layout.addWidget(title)

        tabs = QTabWidget()
        tabs.setStyleSheet(tabs_qss())
        tabs.addTab(self.create_weekly_tab(), tr('stats.tab_weekly'))
        tabs.addTab(self.create_monthly_tab(), tr('stats.tab_monthly'))
        tabs.addTab(self.create_pattern_tab(), tr('stats.tab_pattern'))
        # 도전과제용 탭 진입 카운터
        tabs.currentChanged.connect(self._on_tab_changed)
        self._on_tab_changed(0)
        layout.addWidget(tabs, 1)

        # 닫기 버튼 — 우측 정렬
        btn_row = QHBoxLayout()
        btn_row.addStretch()
        close_button = QPushButton(tr('btn.close'))
        close_button.setMinimumWidth(100)
        close_button.setStyleSheet(button_qss('ghost'))
        close_button.clicked.connect(self.close)
        btn_row.addWidget(close_button)
        layout.addLayout(btn_row)

        self.setLayout(layout)

    def _on_tab_changed(self, idx: int) -> None:
        """탭별 진입 카운터 (도전과제 시스템용). 실패는 silent."""
        keys = ['stat_weekly_view_count', 'stat_monthly_view_count',
                'stat_pattern_view_count']
        if 0 <= idx < len(keys):
            try:
                cur = self.db.get_setting_int(keys[idx], 0)
                self.db.set_setting(keys[idx], str(cur + 1))
            except Exception:
                pass

    def create_weekly_tab(self) -> QWidget:
        """주간 통계 탭 생성"""
        widget = QWidget()
        widget.setStyleSheet("background: transparent;")
        layout = QVBoxLayout()
        layout.setSpacing(10)
        layout.setContentsMargins(8, 12, 8, 8)

        # 카드 4개 가로 배치 (총근무 / 출근일 / 평균 / 연장)
        cards_row = QHBoxLayout()
        cards_row.setSpacing(10)
        self.weekly_total_card = build_stat_card(tr('stats.total_work_hours'), tr('stats.value_hours', hours=0), tr('stats.this_week'),
                                                    theme='blue', icon='clock')
        self.weekly_days_card = build_stat_card(tr('stats.card_work_days'), tr('stats.value_days', days=0), tr('stats.this_week'),
                                                   theme='cyan', icon='calendar')
        self.weekly_avg_card = build_stat_card(tr('stats.card_avg_hours'), tr('stats.value_hours', hours=0), tr('stats.this_week'),
                                                  theme='green', icon='chart')
        self.weekly_ot_card = build_stat_card(tr('stats.card_overtime'), tr('stats.value_hours_minutes', hours=0, minutes=0), tr('stats.this_week'),
                                                 theme='gold', icon='flame')
        for c in (self.weekly_total_card, self.weekly_days_card,
                  self.weekly_avg_card, self.weekly_ot_card):
            cards_row.addWidget(c, 1)
        layout.addLayout(cards_row)

        # 주간 차트 (일별 근무시간) — 카드 안에
        from ui.chart_widget import make_chart_widget
        self.weekly_chart = make_chart_widget(widget)
        chart_card = build_section_card(tr('stats.daily_work_hours'), self.weekly_chart,
                                            theme='gray', icon='trending-up')
        layout.addWidget(chart_card, 1)

        widget.setLayout(layout)
        return widget

    def create_monthly_tab(self) -> QWidget:
        """월간 통계 탭 생성"""
        widget = QWidget()
        widget.setStyleSheet("background: transparent;")
        layout = QVBoxLayout()
        layout.setSpacing(10)
        layout.setContentsMargins(8, 12, 8, 8)

        # 카드 4개
        cards_row = QHBoxLayout()
        cards_row.setSpacing(10)
        self.monthly_total_card = build_stat_card(tr('stats.total_work_hours'), tr('stats.value_hours', hours=0), tr('stats.this_month'),
                                                     theme='blue', icon='clock')
        self.monthly_days_card = build_stat_card(tr('stats.card_work_days'), tr('stats.value_days', days=0), tr('stats.this_month'),
                                                    theme='cyan', icon='calendar')
        self.monthly_avg_card = build_stat_card(tr('stats.card_avg_hours'), tr('stats.value_hours', hours=0), tr('stats.this_month'),
                                                   theme='green', icon='chart')
        self.monthly_ot_card = build_stat_card(tr('stats.card_overtime'), tr('stats.value_hours_minutes', hours=0, minutes=0), tr('stats.this_month'),
                                                  theme='gold', icon='flame')
        for c in (self.monthly_total_card, self.monthly_days_card,
                  self.monthly_avg_card, self.monthly_ot_card):
            cards_row.addWidget(c, 1)
        layout.addLayout(cards_row)

        # 추정 급여 (옵션 활성 시)
        self.salary_label = QLabel("")
        self.salary_label.setStyleSheet(
            f"background: rgba(81, 207, 102, 0.12); "
            f"border: 1px solid {tc('green')}; border-radius: 8px; "
            f"color: {tc('green')}; font-weight: bold; "
            f"padding: 10px 14px; font-size: 11pt;"
        )
        self.salary_label.setVisible(False)
        layout.addWidget(self.salary_label)

        # 목표 진행률
        from ui.goal_widget import GoalWidget
        self.goal_widget = GoalWidget(self.db)
        layout.addWidget(self.goal_widget)

        # 월간 차트
        from ui.chart_widget import make_chart_widget
        self.monthly_chart = make_chart_widget(widget)
        chart_card = build_section_card(tr('stats.weekday_avg'), self.monthly_chart,
                                            theme='gray', icon='chart')
        layout.addWidget(chart_card, 1)

        widget.setLayout(layout)
        return widget

    def create_pattern_tab(self) -> QWidget:
        """패턴 분석 탭 생성"""
        widget = QWidget()
        widget.setStyleSheet("background: transparent;")
        layout = QVBoxLayout()
        layout.setSpacing(10)
        layout.setContentsMargins(8, 12, 8, 8)

        # 패턴 텍스트 카드
        self.pattern_text = QLabel(tr('stats.analyzing'))
        self.pattern_text.setWordWrap(True)
        self.pattern_text.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.pattern_text.setStyleSheet(
            f"font-size: 11pt; color: {tc('text')}; "
            f"background: transparent; border: none; padding: 4px 0;"
        )
        layout.addWidget(build_section_card(tr('stats.pattern_insights'), self.pattern_text,
                                                theme='cyan', icon='search'))

        # 출근 시각 분포 차트
        from ui.chart_widget import make_chart_widget
        self.clock_in_chart = make_chart_widget(widget)
        layout.addWidget(build_section_card(tr('stats.clock_in_distribution'), self.clock_in_chart,
                                                theme='gray', icon='clock'), 1)

        widget.setLayout(layout)
        return widget

    def _set_card_value(self, card, value: str) -> None:
        """build_stat_card로 만든 카드의 큰 숫자 라벨 업데이트.

        카드 구조: QFrame > QHBoxLayout > [icon QLabel] [text QVBoxLayout > title, value, subtitle]
        value는 두 번째 QLabel.
        """
        # text_box는 outer hbox의 마지막 layout
        outer = card.layout()
        if outer is None or outer.count() == 0:
            return
        # text_box 찾기 (마지막 item, layout)
        text_item = outer.itemAt(outer.count() - 1)
        text_box = text_item.layout() if text_item else None
        if text_box is None or text_box.count() < 2:
            return
        val_lbl = text_box.itemAt(1).widget()  # 두 번째가 큰 숫자
        if val_lbl is None:
            return
        # 큰 숫자 RichText 형식 유지
        from ui.dark_components import CARD_THEMES
        # tier color는 카드 자체에 알 방법이 없으니 기본 골드 톤
        val_lbl.setText(
            f"<span style='font-size: 18pt; font-weight: bold; color: #ffd24a;'>"
            f"{value}</span>"
        )

    def load_stats(self):
        """통계 로드"""
        # 주간 통계
        weekly_stats = self.db.get_weekly_stats()
        total_hours = weekly_stats.get('total_hours', 0) or 0
        self._set_card_value(self.weekly_total_card, tr('stats.value_hours', hours=f"{total_hours:.1f}"))
        self._set_card_value(self.weekly_days_card, tr('stats.value_days', days=weekly_stats.get('work_days', 0)))
        avg_hours = weekly_stats.get('avg_hours_per_day', 0) or 0
        self._set_card_value(self.weekly_avg_card, tr('stats.value_hours', hours=f"{avg_hours:.1f}"))

        overtime_minutes = weekly_stats.get('total_overtime_minutes', 0) or 0
        overtime_hours = overtime_minutes // 60
        overtime_mins = overtime_minutes % 60
        self._set_card_value(self.weekly_ot_card, tr('stats.value_hours_minutes', hours=overtime_hours, minutes=overtime_mins))

        # 주간 차트
        from ui.chart_widget import draw_daily_hours, draw_weekday_avg
        from datetime import timedelta as _td
        today = datetime.now().date()
        week_records = self.db.get_work_records_by_range(
            (today - _td(days=6)).isoformat(), today.isoformat()
        )
        if hasattr(self, 'weekly_chart'):
            # 도전과제 chart_hover 감지를 위해 db 참조 attach
            self.weekly_chart._achievement_db = self.db
            draw_daily_hours(self.weekly_chart, week_records)

        # 월간 통계
        now = datetime.now()
        monthly_stats = self.db.get_monthly_stats(now.year, now.month)
        total_hours = monthly_stats.get('total_hours', 0) or 0
        self._set_card_value(self.monthly_total_card, tr('stats.value_hours', hours=f"{total_hours:.1f}"))
        work_days = monthly_stats.get('work_days', 0) or 0
        self._set_card_value(self.monthly_days_card, tr('stats.value_days', days=work_days))

        if work_days > 0:
            avg = total_hours / work_days
            self._set_card_value(self.monthly_avg_card, tr('stats.value_hours', hours=f"{avg:.1f}"))
        else:
            self._set_card_value(self.monthly_avg_card, tr('stats.value_hours', hours=0))

        overtime_minutes = monthly_stats.get('total_overtime_minutes', 0) or 0
        overtime_hours = overtime_minutes // 60
        overtime_mins = overtime_minutes % 60
        self._set_card_value(self.monthly_ot_card,
                              tr('stats.value_hours_minutes', hours=overtime_hours, minutes=overtime_mins))

        # 월간 차트 (요일별 평균)
        if hasattr(self, 'monthly_chart'):
            draw_weekday_avg(self.monthly_chart, monthly_stats.get('records', []))

        # 추정 급여 (옵션 활성 시)
        self._update_salary_estimate(monthly_stats.get('records', []))

        # 목표 진행률
        if hasattr(self, 'goal_widget'):
            self.goal_widget.refresh()

        # 패턴 분석
        self.analyze_patterns(monthly_stats.get('records', []))

    def _update_salary_estimate(self, records):
        """월간 추정 급여 표시 (SALARY_ENABLED=true 일 때만)."""
        if not hasattr(self, 'salary_label'):
            return
        if self.db.get_setting('salary_enabled', 'false').lower() != 'true':
            self.salary_label.setVisible(False)
            return
        try:
            wage = float(self.db.get_setting('hourly_wage', '0') or 0)
            rate = float(self.db.get_setting('overtime_rate', '1.5') or 1.5)
        except (ValueError, TypeError):
            self.salary_label.setVisible(False)
            return
        if wage <= 0:
            self.salary_label.setVisible(False)
            return
        from core.salary import estimate_pay, format_won
        result = estimate_pay(records, wage, rate)
        self.salary_label.setText(
            tr('stats.salary_estimate',
               total=format_won(result['total']),
               base=format_won(result['base']),
               overtime=format_won(result['overtime']))
        )
        self.salary_label.setVisible(True)

    def analyze_patterns(self, records):
        """패턴 분석"""
        # 출근 분포 차트는 데이터 유무와 무관하게 갱신 (빈 차트 표시)
        if hasattr(self, 'clock_in_chart'):
            from ui.chart_widget import draw_clock_in_distribution
            draw_clock_in_distribution(self.clock_in_chart, records or [])

        if not records:
            self.pattern_text.setText(tr('stats.no_data'))
            return

        insights = []

        # 평균 출근 시간
        clock_in_times = []
        for record in records:
            if record.get('clock_in'):
                try:
                    time_parts = record['clock_in'].split(':')
                    hour = int(time_parts[0])
                    minute = int(time_parts[1])
                    clock_in_times.append(hour * 60 + minute)
                except (ValueError, IndexError):
                    continue

        if clock_in_times:
            avg_minutes = sum(clock_in_times) / len(clock_in_times)
            avg_hour = int(avg_minutes // 60)
            avg_min = int(avg_minutes % 60)
            insights.append(tr('stats.avg_clock_in', time=f"{avg_hour:02d}:{avg_min:02d}"))

        # 연장근무 빈도
        overtime_days = len([r for r in records if (r.get('overtime_earned') or 0) > 0])
        total_days = len([r for r in records if r.get('clock_out')])

        if total_days > 0:
            overtime_rate = (overtime_days / total_days) * 100
            insights.append(tr('stats.overtime_frequency', rate=f"{overtime_rate:.0f}", days=overtime_days, total=total_days))

        # 가장 긴 근무일
        records_with_hours = [r for r in records if (r.get('total_hours') or 0) > 0]
        if records_with_hours:
            longest_work = max(records_with_hours, key=lambda x: x.get('total_hours', 0))
            if longest_work.get('total_hours', 0) > 0:
                insights.append(tr('stats.longest_work', date=longest_work['date'], hours=f"{longest_work['total_hours']:.1f}"))

        # 건강 경고
        recent_records = records[-7:]  # 최근 7일
        consecutive_overtime = 0
        max_consecutive = 0

        for record in recent_records:
            if (record.get('overtime_earned') or 0) > 0:
                consecutive_overtime += 1
                max_consecutive = max(max_consecutive, consecutive_overtime)
            else:
                consecutive_overtime = 0

        if max_consecutive >= 3:
            insights.append(tr('stats.consecutive_ot_warning', days=max_consecutive))

        # 주 52시간 체크
        if len(recent_records) >= 7:
            week_total = sum((r.get('total_hours') or 0) for r in recent_records[-7:])
            if week_total > 52:
                insights.append(tr('stats.weekly_52_exceeded', hours=f"{week_total:.1f}"))

        self.pattern_text.setText("\n\n".join(insights) if insights else tr('stats.no_pattern_data'))


# 테스트 코드
if __name__ == "__main__":
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)
    dialog = StatsView()
    dialog.exec_()
