import customtkinter as ctk
from tkinter import filedialog
from view.theme import theme_manager
from pathlib import Path
from updater.__version__ import VERSION, APP_NAME


class HoverTooltip:
    """마우스 오버 시 표시되는 간단한 툴팁"""

    def __init__(self, widget, text: str, delay_ms: int = 300):
        self.widget = widget
        self.text = text
        self.delay_ms = delay_ms
        self._after_id = None
        self._tooltip = None

        self.widget.bind("<Enter>", self._on_enter)
        self.widget.bind("<Leave>", self._on_leave)
        self.widget.bind("<ButtonPress>", self._on_leave)

    def _on_enter(self, _event=None):
        self._schedule_show()

    def _on_leave(self, _event=None):
        self._cancel_show()
        self._hide()

    def _schedule_show(self):
        self._cancel_show()
        self._after_id = self.widget.after(self.delay_ms, self._show)

    def _cancel_show(self):
        if self._after_id is not None:
            self.widget.after_cancel(self._after_id)
            self._after_id = None

    def _show(self):
        if self._tooltip is not None:
            return

        x = self.widget.winfo_pointerx() + 12
        y = self.widget.winfo_pointery() + 12

        self._tooltip = ctk.CTkToplevel(self.widget)
        self._tooltip.overrideredirect(True)
        self._tooltip.attributes("-topmost", True)
        self._tooltip.geometry(f"+{x}+{y}")

        label = ctk.CTkLabel(
            self._tooltip,
            text=self.text,
            justify="left",
            wraplength=320,
            corner_radius=8,
            fg_color=("#f2f2f2", "#2b2b2b"),
            text_color=("#111111", "#f0f0f0"),
            padx=10,
            pady=8,
            font=theme_manager.get_font(11),
        )
        label.pack()

    def _hide(self):
        if self._tooltip is not None:
            self._tooltip.destroy()
            self._tooltip = None

class SettingsDialog(ctk.CTkToplevel):
    def __init__(self, controller, parent=None):
        super().__init__(master=parent)
        self.controller = controller
        self.author = "KH.Choi"
        self.title(f"{APP_NAME} 설정")
        self.geometry("500x500")
        
        # parent가 있으면 transient 설정 (Z-order 문제 해결)
        if parent:
            self.transient(parent)
            self.lift()
            self.focus_force()
        
        # 1. Tabview 생성
        self.tabview = ctk.CTkTabview(self)
        self.tabview.pack(padx=20, pady=20, fill="both", expand=True)
        
        self.tab_login = self.tabview.add("로그인")
        self.tab_noti = self.tabview.add("알림 설정")
        self.tab_crawl = self.tabview.add("수집 설정") # 기존 크롤링 설정 통합 가능
        self.tab_theme = self.tabview.add("테마")
        self.tab_system = self.tabview.add("시스템")
        
        self._init_login_tab()
        self._init_crawl_tab()
        self._init_theme_tab()
        self._init_system_tab()
        self._init_notification_tab()

        self.meta_label = ctk.CTkLabel(
            self,
            text=f"버전 v{VERSION} | 제작 {self.author}",
            font=theme_manager.get_font(11),
            text_color=("gray45", "gray65")
        )
        self.meta_label.pack(pady=(0, 10))

    def _init_login_tab(self):
        font = theme_manager.get_font(12)
        ctk.CTkLabel(self.tab_login, text="사번 (ID)", font=font).pack(pady=5)
        self.entry_id = ctk.CTkEntry(self.tab_login)
        self.entry_id.pack(pady=5)
        self.entry_id.insert(0, self.controller.settings['login']['id'])
        
        ctk.CTkLabel(self.tab_login, text="비밀번호", font=font).pack(pady=5)
        self.entry_pw = ctk.CTkEntry(self.tab_login, show="*")
        self.entry_pw.pack(pady=5)
        self.entry_pw.insert(0, self.controller.settings['login']['pw'])

        ctk.CTkButton(self.tab_login, text="설정 저장", command=self.save_all).pack(pady=20)

    def _init_crawl_tab(self):
        font = theme_manager.get_font(12)
        ctk.CTkLabel(self.tab_crawl, text="수집 주기 (분)", font=font).pack(pady=5)
        self.combo_interval = ctk.CTkComboBox(self.tab_crawl, values=["3", "5", "10", "15", "30"])
        self.combo_interval.pack(pady=5)
        self.combo_interval.set(str(self.controller.settings['crawling']['interval_minutes']))

        ctk.CTkLabel(self.tab_crawl, text="신규 알림 주기 (분)", font=font).pack(pady=5)
        self.combo_noti_interval = ctk.CTkComboBox(self.tab_crawl, values=["1", "3", "5", "10", "15", "30"])
        self.combo_noti_interval.pack(pady=5)
        self.combo_noti_interval.set(
            str(self.controller.settings.get('noti', {}).get('db_check_interval_minutes', 5))
        )

        ctk.CTkLabel(self.tab_crawl, text="미확인 알림 주기 (분)", font=font).pack(pady=5)
        self.combo_unchecked_interval = ctk.CTkComboBox(self.tab_crawl, values=["5", "10", "15", "30", "60"])
        self.combo_unchecked_interval.pack(pady=5)
        self.combo_unchecked_interval.set(
            str(self.controller.settings.get('noti', {}).get('unchecked_check_interval_minutes', 30))
        )

        self.unchecked_delay_var = ctk.BooleanVar(
            value=self.controller.settings.get('noti', {}).get('unchecked_delay_enabled', True)
        )
        unchecked_delay_frame = ctk.CTkFrame(self.tab_crawl, fg_color="transparent")
        unchecked_delay_frame.pack(pady=8, anchor="w", padx=20)

        self.check_unchecked_delay = ctk.CTkSwitch(
            unchecked_delay_frame,
            text="미확인 글 30분 경과 후에만 알림",
            variable=self.unchecked_delay_var
        )
        self.check_unchecked_delay.pack(side="left")

        self.unchecked_delay_help = ctk.CTkLabel(
            unchecked_delay_frame,
            text="?",
            width=20,
            height=20,
            corner_radius=10,
            fg_color=("#d9d9d9", "#3a3a3a"),
            text_color=("#222222", "#f0f0f0"),
            font=theme_manager.get_font(11, "bold"),
            cursor="hand2"
        )
        self.unchecked_delay_help.pack(side="left", padx=(8, 0))
        self.unchecked_delay_tooltip = HoverTooltip(
            self.unchecked_delay_help,
            "ON: 생성 후 30분이 지난 미확인 글만 알림합니다.\n"
            "OFF: 생성 시간과 무관하게 미확인 글 전체를 알림합니다."
        )
        
        ctk.CTkLabel(self.tab_crawl, text="관심 키워드 (콤마로 구분)", font=font).pack(pady=5)
        self.entry_crawl_kw = ctk.CTkEntry(self.tab_crawl, width=300)
        self.entry_crawl_kw.pack(pady=5)
        self.entry_crawl_kw.insert(0, ",".join(self.controller.settings['crawling']['keywords']))

        ctk.CTkLabel(self.tab_crawl, text="관심 부서 (콤마로 구분)", font=font).pack(pady=5)
        self.entry_dept = ctk.CTkEntry(self.tab_crawl, width=300)
        self.entry_dept.pack(pady=5)
        self.entry_dept.insert(0, ",".join(self.controller.settings['crawling']['target_depts']))

        ctk.CTkButton(self.tab_crawl, text="설정 저장", command=self.save_all).pack(pady=20)

    def _init_theme_tab(self):
        font = theme_manager.get_font(12)
        ctk.CTkLabel(self.tab_theme, text="UI 테마 모드", font=font).pack(pady=10)
        self.combo_theme = ctk.CTkComboBox(self.tab_theme, values=["System", "Dark", "Light"])
        self.combo_theme.pack(pady=5)
        
        current_theme = self.controller.settings.get('theme', 'System')
        self.combo_theme.set(current_theme)
        
        ctk.CTkButton(self.tab_theme, text="테마 적용 및 저장", command=self.save_all).pack(pady=20)

    def _init_system_tab(self):
        font_bold = theme_manager.get_font(13, "bold")
        
        # === 로그 관리 섹션 ===
        ctk.CTkLabel(self.tab_system, text="시스템 로그 관리", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
        
        def open_logs():
            from view.dialogs.log_viewer_dialog import LogViewerDialog
            LogViewerDialog(self)
            
        ctk.CTkButton(
            self.tab_system, 
            text="📋 로그 확인", 
            command=open_logs,
            width=200,
            height=35
        ).pack(pady=5, padx=20, anchor="w")
        
        # 구분선
        ctk.CTkLabel(self.tab_system, text="", height=1, fg_color="gray").pack(fill="x", padx=20, pady=15)
        
        # === 보고서 저장 경로 섹션 ===
        ctk.CTkLabel(self.tab_system, text="보고서 저장 경로", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
        
        # 현재 경로 표시 프레임
        path_frame = ctk.CTkFrame(self.tab_system, fg_color="transparent")
        path_frame.pack(fill="x", padx=20, pady=5)
        
        # 현재 경로 가져오기 (기본값: output 폴더)
        current_path = self.controller.settings.get('report', {}).get('output_path', '')
        if not current_path:
            # 기본 경로 설정
            from utils.path_utils import get_base_dir
            current_path = str(get_base_dir().parent / "output")
        
        self.report_path_label = ctk.CTkLabel(
            path_frame,
            text=current_path,
            font=theme_manager.get_font(11),
            text_color=("gray40", "gray60"),
            anchor="w"
        )
        self.report_path_label.pack(side="left", fill="x", expand=True, padx=(0, 10))
        
        # 경로 변경 버튼
        ctk.CTkButton(
            path_frame,
            text="📁 폴더 선택",
            command=self._select_report_folder,
            width=120,
            height=35,
            fg_color=("#1f538d", "#2980b9"),
            hover_color=("#174a7a", "#1f6fa8")
        ).pack(side="left")
        
        # 안내 문구
        ctk.CTkLabel(
            self.tab_system,
            text="※ HWP 및 PDF 보고서가 저장될 폴더를 지정합니다.",
            font=theme_manager.get_font(10),
            text_color="gray"
        ).pack(anchor="w", padx=45, pady=(5, 0))

        ctk.CTkButton(self.tab_system, text="설정 저장", command=self.save_all).pack(pady=20)
    
    def _select_report_folder(self):
        """보고서 저장 폴더 선택 다이얼로그"""
        current_path = self.report_path_label.cget("text")
        
        # 폴더 선택 다이얼로그
        selected_folder = filedialog.askdirectory(
            title="보고서 저장 폴더 선택",
            initialdir=current_path if Path(current_path).exists() else None
        )
        
        if selected_folder:
            self.report_path_label.configure(text=selected_folder)
            # 즉시 저장 (사용자 편의)
            if 'report' not in self.controller.settings:
                self.controller.settings['report'] = {}
            self.controller.settings['report']['output_path'] = selected_folder
            self.controller.save_settings()

    def _init_notification_tab(self):
        
        # 1. 알림 소리 설정
        self.sound_var = ctk.BooleanVar(value=self.controller.settings.get('noti', {}).get('sound', True))
        self.check_sound = ctk.CTkSwitch(self.tab_noti, text="알림 발생 시 소리 재생", variable=self.sound_var)
        self.check_sound.pack(pady=15, anchor="w", padx=20)

        ctk.CTkLabel(self.tab_noti, text="", height=1, fg_color="gray").pack(fill="x", padx=20, pady=10)

        # 2. 관심 조건 필터링 토글
        self.use_related_filter_var = ctk.BooleanVar(
            value=self.controller.settings.get('noti', {}).get('use_related_filter', True)
        )
        related_filter_frame = ctk.CTkFrame(self.tab_noti, fg_color="transparent")
        related_filter_frame.pack(pady=10, anchor="w", padx=20)

        self.sw_kw = ctk.CTkSwitch(
            related_filter_frame,
            text="관심 조건(키워드/부서) 일치 글만 알림",
            variable=self.use_related_filter_var
        )
        self.sw_kw.pack(side="left")

        self.related_filter_help = ctk.CTkLabel(
            related_filter_frame,
            text="?",
            width=20,
            height=20,
            corner_radius=10,
            fg_color=("#d9d9d9", "#3a3a3a"),
            text_color=("#222222", "#f0f0f0"),
            font=theme_manager.get_font(11, "bold"),
            cursor="hand2"
        )
        self.related_filter_help.pack(side="left", padx=(8, 0))
        self.related_filter_tooltip = HoverTooltip(
            self.related_filter_help,
            "ON: 수집 설정의 키워드/관심부서 조건(OR)을 만족한 글만 신규/미확인 알림합니다.\n"
            "OFF: 조건과 무관하게 신규/미확인 전체 글을 알림합니다."
        )
        
        # 가이드 문구
        self.lbl_guide = ctk.CTkLabel(
            self.tab_noti, 
            text=(
                "※ ON: 수집 설정의 키워드/관심부서 조건(OR)을 만족한 글만 알림\n"
                "※ OFF: 조건과 무관하게 신규/미확인 전체 글에 대해 알림"
            ),
            font=theme_manager.get_font(11),
            text_color="gray"
        )
        self.lbl_guide.pack(anchor="w", padx=45)

        ctk.CTkButton(self.tab_noti, text="설정 저장", command=self.save_all).pack(pady=20)

    def save_all(self):
        self.controller.settings['login']['id'] = self.entry_id.get()
        self.controller.settings['login']['pw'] = self.entry_pw.get()
        self.controller.settings['crawling']['interval_minutes'] = int(self.combo_interval.get())
        self.controller.settings['crawling']['keywords'] = [k.strip() for k in self.entry_crawl_kw.get().split(',') if k.strip()]
        self.controller.settings['crawling']['target_depts'] = [k.strip() for k in self.entry_dept.get().split(',') if k.strip()]

        if 'noti' not in self.controller.settings:
            self.controller.settings['noti'] = {}
        self.controller.settings['noti']['db_check_interval_minutes'] = int(self.combo_noti_interval.get())
        self.controller.settings['noti']['unchecked_check_interval_minutes'] = int(self.combo_unchecked_interval.get())
        self.controller.settings['noti']['unchecked_delay_enabled'] = self.unchecked_delay_var.get()
        
        # 테마 저장 및 적용
        selected_theme = self.combo_theme.get()
        self.controller.settings['theme'] = selected_theme
        theme_manager.set_theme(selected_theme)
        
        self.controller.settings['noti']['sound'] = self.sound_var.get()
        self.controller.settings['noti']['use_related_filter'] = self.use_related_filter_var.get()
        # 과거 알림 키워드 설정 정리 (현재는 수집 설정 키워드만 사용)
        self.controller.settings['noti'].pop('use_keywords', None)
        self.controller.settings['noti'].pop('keywords', None)
        
        # 보고서 경로 저장 (이미 _select_report_folder에서 저장되지만 일관성 유지)
        if 'report' not in self.controller.settings:
            self.controller.settings['report'] = {}
        self.controller.settings['report']['output_path'] = self.report_path_label.cget("text")

        self.controller.save_settings()
        self.controller.update_config_runtime()

        self.destroy()
