import tkinter as tk
from tkinter import filedialog, messagebox, ttk, scrolledtext
import fitz  # PyMuPDF
import re
import os
import threading
from tkinter import font
from tkinterdnd2 import DND_FILES, TkinterDnD
import json
from datetime import datetime

# 사용자 정의 모듈 임포트
from src.employee_manager import EmployeeManager
from src.email_sender import PayslipEmailSender, EmailConfig
from src.pdf_preview import PDFPreviewManager

def extract_birth_date_numbers(text):
    """
    텍스트에서 '생년월일' 라벨 오른쪽에 있는 날짜를 찾아 숫자만 반환합니다.
    """
    patterns = [
        r'생년월일\s*[:：]?\s*(\d{4})[-.\/\s](\d{1,2})[-.\/\s](\d{1,2})',
        r'생년월일\s+(\d{4})[-.\/](\d{1,2})[-.\/](\d{1,2})',
    ]
    
    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            year, month, day = match.groups()
            month = month.zfill(2)
            day = day.zfill(2)
            return year + month + day
    
    return None

class PayslipFileItem:
    """개별 급여명세서 파일 아이템 UI 컴포넌트"""
    
    def __init__(self, parent_frame, employee_name, email, pdf_path, preview_manager, on_status_change=None):
        self.parent_frame = parent_frame
        self.employee_name = employee_name
        self.email = email
        self.pdf_path = pdf_path
        self.preview_manager = preview_manager
        self.on_status_change = on_status_change
        
        # PDF 정보 로드
        self.pdf_info = preview_manager.get_pdf_info(pdf_path) if pdf_path and os.path.exists(pdf_path) else {}
        
        self.create_ui()
    
    def create_ui(self):
        # 메인 컨테이너 프레임
        self.main_frame = ttk.Frame(self.parent_frame, relief='ridge', padding=5)
        self.main_frame.pack(fill='x', padx=5, pady=2)
        
        # 상단: 직원 정보 및 체크박스
        top_frame = ttk.Frame(self.main_frame)
        top_frame.pack(fill='x')
        
        # 발송 여부 체크박스
        self.send_var = tk.BooleanVar(value=bool(self.email))
        self.send_check = ttk.Checkbutton(top_frame, variable=self.send_var,
                                         command=self.on_send_status_change)
        self.send_check.pack(side='left', padx=(0, 5))
        
        # 직원 정보
        email_display = self.email if self.email else "❌ 매칭되지 않음"
        info_color = 'black' if self.email else 'red'
        
        info_label = ttk.Label(top_frame, 
                              text=f"👤 {self.employee_name} → 📧 {email_display}",
                              font=('맑은 고딕', 9, 'bold'))
        info_label.pack(side='left')
        
        # 중단: 파일 정보 및 버튼들
        middle_frame = ttk.Frame(self.main_frame)
        middle_frame.pack(fill='x', pady=(5, 0))
        
        # 파일 정보
        if self.pdf_path and os.path.exists(self.pdf_path):
            file_size = self.preview_manager.format_file_size(self.pdf_info.get('file_size', 0))
            page_count = self.pdf_info.get('page_count', 0)
            
            file_info_text = f"📄 {os.path.basename(self.pdf_path)} ({file_size})"
            if self.pdf_info.get('is_encrypted'):
                file_info_text += " 🔒 비밀번호 보호"
            else:
                file_info_text += f" ({page_count}페이지)"
        else:
            file_info_text = "📄 파일을 찾을 수 없습니다"
        
        file_label = ttk.Label(middle_frame, text=file_info_text)
        file_label.pack(side='left')
        
        # 버튼들
        button_frame = ttk.Frame(middle_frame)
        button_frame.pack(side='right')
        
        if self.pdf_path and os.path.exists(self.pdf_path):
            ttk.Button(button_frame, text="📂 열기", 
                      command=self.open_file, width=8).pack(side='left', padx=2)
            ttk.Button(button_frame, text="📁 폴더", 
                      command=self.open_folder, width=8).pack(side='left', padx=2)
        
        # 발송 완료 상태 표시용
        self.sent_status = False  # 발송 완료 상태
        self.sent_label = None    # 발송 완료 라벨
    
    def mark_as_sent(self):
        """발송 완료로 표시"""
        self.sent_status = True
        if not self.sent_label:
            self.sent_label = ttk.Label(self.main_frame, text="✅ 발송 완료", 
                                      foreground='green', font=('맑은 고딕', 9, 'bold'))
            self.sent_label.pack(side='right', padx=5)
        
        # 체크박스 비활성화
        self.send_check.config(state='disabled')
    
    def open_folder(self):
        """파일이 있는 폴더 열기"""
        if self.pdf_path and os.path.exists(self.pdf_path):
            import subprocess
            import platform
            try:
                folder_path = os.path.dirname(self.pdf_path)
                if platform.system() == 'Windows':
                    subprocess.run(['explorer', '/select,', self.pdf_path])
                elif platform.system() == 'Darwin':  # macOS
                    subprocess.run(['open', '-R', self.pdf_path])
                else:  # Linux
                    subprocess.run(['xdg-open', folder_path])
            except Exception as e:
                messagebox.showerror("오류", f"폴더를 열 수 없습니다:\n{str(e)}")
        else:
            messagebox.showwarning("파일 없음", "폴더를 열 파일이 없습니다.")
    
    def open_file(self):
        """시스템 기본 프로그램으로 파일 열기"""
        if self.pdf_path and os.path.exists(self.pdf_path):
            # 비밀번호 보호된 파일이면 안내 메시지 표시
            if self.pdf_info.get('is_encrypted'):
                response = messagebox.askyesno(
                    "비밀번호 보호된 파일", 
                    f"{self.employee_name}님의 급여명세서는 비밀번호로 \n보호되어 있습니다.\n\n🔑 비밀번호: 생년월일 8자리\n(예: 1990년 1월 15일 → 19900115)\n\n파일을 여시겠습니까?"
                )
                if not response:
                    return
                    
            success = self.preview_manager.open_file_with_system(self.pdf_path)
            if not success:
                messagebox.showerror("오류", "파일을 열 수 없습니다.")
        else:
            messagebox.showwarning("파일 없음", "열 파일이 없습니다.")
    
    def on_send_status_change(self):
        """발송 상태 변경시 UI 업데이트"""
        if self.on_status_change:
            self.on_status_change()
    
    def get_send_data(self):
        """이메일 발송 데이터 반환"""
        # 발송 완료된 항목은 제외
        if self.sent_status:
            print(f"[DEBUG] 발송 완료된 항목 제외: {self.employee_name}")
            return None
            
        if self.send_var.get() and self.email and self.pdf_path:
            if os.path.exists(self.pdf_path):
                file_size = os.path.getsize(self.pdf_path)
                print(f"[DEBUG] 발송 대상: {self.employee_name} -> {self.email}")
                print(f"[DEBUG] PDF 파일: {self.pdf_path} ({file_size} bytes)")
                return {
                    "name": self.employee_name,
                    "email": self.email,
                    "pdf_path": self.pdf_path
                }
            else:
                print(f"[ERROR] PDF 파일 없음: {self.pdf_path}")
        return None

class EmployeeManagementTab:
    """직원 관리 탭"""
    
    def __init__(self, parent_notebook, employee_manager):
        self.employee_manager = employee_manager
        self.selected_employee = None
        
        # 직원 관리 탭 생성
        self.frame = ttk.Frame(parent_notebook)
        parent_notebook.add(self.frame, text="직원 관리")
        
        self.setup_ui()
        self.refresh_employee_list()
    
    def setup_ui(self):
        # 메인 컨테이너
        main_container = ttk.Frame(self.frame, padding=10)
        main_container.pack(fill='both', expand=True)
        
        # 상단: 검색 영역
        search_frame = ttk.LabelFrame(main_container, text="직원 검색", padding=5)
        search_frame.pack(fill='x', pady=(0, 10))
        
        self.search_var = tk.StringVar()
        ttk.Label(search_frame, text="검색:").pack(side='left')
        search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=20)
        search_entry.pack(side='left', padx=5)
        search_entry.bind('<KeyRelease>', self.on_search)
        
        ttk.Button(search_frame, text="전체보기", 
                  command=self.show_all).pack(side='left', padx=5)
        
        # 중앙: 좌우 분할 영역
        paned_window = ttk.PanedWindow(main_container, orient='horizontal')
        paned_window.pack(fill='both', expand=True)
        
        # 왼쪽: 직원 목록
        left_frame = ttk.LabelFrame(paned_window, text="직원 목록", padding=5)
        paned_window.add(left_frame, weight=2)
        
        # 직원 목록 (TreeView 사용)
        columns = ('name', 'email')
        self.tree = ttk.Treeview(left_frame, columns=columns, show='headings', height=15)
        self.tree.heading('name', text='이름')
        self.tree.heading('email', text='이메일')
        self.tree.column('name', width=100)
        self.tree.column('email', width=200)
        
        # 스크롤바
        scrollbar = ttk.Scrollbar(left_frame, orient='vertical', command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        self.tree.pack(side='left', fill='both', expand=True)
        scrollbar.pack(side='right', fill='y')
        
        # 트리 선택 이벤트
        self.tree.bind('<<TreeviewSelect>>', self.on_tree_select)
        
        # 목록 하단 버튼들
        list_button_frame = ttk.Frame(left_frame)
        list_button_frame.pack(fill='x', pady=5)
        
        ttk.Button(list_button_frame, text="선택삭제", 
                  command=self.delete_selected).pack(side='left', padx=2)
        
        # 오른쪽: 편집 영역
        right_frame = ttk.LabelFrame(paned_window, text="직원 정보 편집", padding=5)
        paned_window.add(right_frame, weight=1)
        
        # 편집 폼
        form_frame = ttk.Frame(right_frame)
        form_frame.pack(fill='x', pady=5)
        
        ttk.Label(form_frame, text="이름:").grid(row=0, column=0, sticky='w', pady=2)
        self.name_var = tk.StringVar()
        self.name_entry = ttk.Entry(form_frame, textvariable=self.name_var, width=20)
        self.name_entry.grid(row=0, column=1, padx=5, pady=2)
        
        ttk.Label(form_frame, text="이메일:").grid(row=1, column=0, sticky='w', pady=2)
        self.email_var = tk.StringVar()
        self.email_entry = ttk.Entry(form_frame, textvariable=self.email_var, width=30)
        self.email_entry.grid(row=1, column=1, padx=5, pady=2)
        
        # 편집 버튼들
        edit_button_frame = ttk.Frame(right_frame)
        edit_button_frame.pack(fill='x', pady=10)
        
        ttk.Button(edit_button_frame, text="새로 추가", 
                  command=self.add_employee).pack(fill='x', pady=2)
        ttk.Button(edit_button_frame, text="수정", 
                  command=self.update_employee).pack(fill='x', pady=2)
        ttk.Button(edit_button_frame, text="삭제", 
                  command=self.delete_employee).pack(fill='x', pady=2)
        
        # 직원 관리 옵션
        option_frame = ttk.LabelFrame(right_frame, text="관리 옵션", padding=5)
        option_frame.pack(fill='x', pady=10)
        
        ttk.Button(option_frame, text="전체 선택", 
                  command=self.select_all_employees).pack(fill='x', pady=1)
        ttk.Button(option_frame, text="선택 해제", 
                  command=self.deselect_all_employees).pack(fill='x', pady=1)
        
        # 하단: 빠른 추가
        quick_frame = ttk.LabelFrame(main_container, text="빠른 추가", padding=5)
        quick_frame.pack(fill='x', pady=10)
        
        quick_container = ttk.Frame(quick_frame)
        quick_container.pack()
        
        ttk.Label(quick_container, text="이름:").pack(side='left')
        self.quick_name_var = tk.StringVar()
        quick_name_entry = ttk.Entry(quick_container, textvariable=self.quick_name_var, width=15)
        quick_name_entry.pack(side='left', padx=5)
        
        ttk.Label(quick_container, text="이메일:").pack(side='left', padx=(10, 0))
        self.quick_email_var = tk.StringVar()
        quick_email_entry = ttk.Entry(quick_container, textvariable=self.quick_email_var, width=25)
        quick_email_entry.pack(side='left', padx=5)
        
        ttk.Button(quick_container, text="추가", 
                  command=self.quick_add_employee).pack(side='left', padx=5)
        
        # 엔터키 바인딩
        quick_name_entry.bind('<Return>', lambda e: self.quick_add_employee())
        quick_email_entry.bind('<Return>', lambda e: self.quick_add_employee())
    
    def refresh_employee_list(self, filter_text=""):
        """직원 목록 새로고침"""
        # 기존 항목 제거
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 직원 목록 추가
        if filter_text:
            employees = self.employee_manager.search_employees(filter_text)
        else:
            employees = self.employee_manager.get_all_employees()
            
        for name, email in sorted(employees.items()):
            self.tree.insert('', 'end', values=(name, email))
    
    def on_search(self, event=None):
        """검색 필터링"""
        self.refresh_employee_list(self.search_var.get())
    
    def show_all(self):
        """전체 목록 보기"""
        self.search_var.set("")
        self.refresh_employee_list()
    
    def on_tree_select(self, event):
        """트리에서 항목 선택시"""
        selection = self.tree.selection()
        if selection:
            item = self.tree.item(selection[0])
            values = item['values']
            self.name_var.set(values[0])
            self.email_var.set(values[1])
            self.selected_employee = values[0]
    
    def add_employee(self):
        """직원 추가"""
        name = self.name_var.get().strip()
        email = self.email_var.get().strip()
        
        if not name or not email:
            messagebox.showwarning("경고", "이름과 이메일을 모두 입력해주세요.")
            return
        
        if self.employee_manager.add_employee(name, email):
            messagebox.showinfo("성공", f"'{name}' 직원을 추가했습니다.")
            self.refresh_employee_list()
            self.clear_form()
        else:
            messagebox.showerror("오류", "이미 존재하는 직원입니다.")
    
    def update_employee(self):
        """직원 정보 수정"""
        if not self.selected_employee:
            messagebox.showwarning("경고", "수정할 직원을 선택해주세요.")
            return
        
        new_name = self.name_var.get().strip()
        new_email = self.email_var.get().strip()
        
        if not new_name or not new_email:
            messagebox.showwarning("경고", "이름과 이메일을 모두 입력해주세요.")
            return
        
        if self.employee_manager.update_employee(self.selected_employee, new_name, new_email):
            messagebox.showinfo("성공", f"'{new_name}' 직원 정보를 수정했습니다.")
            self.refresh_employee_list()
            self.selected_employee = new_name
        else:
            messagebox.showerror("오류", "직원 정보 수정에 실패했습니다.")
    
    def delete_employee(self):
        """직원 삭제"""
        if not self.selected_employee:
            messagebox.showwarning("경고", "삭제할 직원을 선택해주세요.")
            return
        
        result = messagebox.askyesno("확인", f"'{self.selected_employee}' 직원을 삭제하시겠습니까?")
        if result:
            if self.employee_manager.delete_employee(self.selected_employee):
                messagebox.showinfo("성공", f"'{self.selected_employee}' 직원을 삭제했습니다.")
                self.refresh_employee_list()
                self.clear_form()
            else:
                messagebox.showerror("오류", "직원 삭제에 실패했습니다.")
    
    def delete_selected(self):
        """선택된 직원들 삭제"""
        selected_items = self.tree.selection()
        if not selected_items:
            messagebox.showwarning("경고", "삭제할 직원을 선택해주세요.")
            return
        
        names = [self.tree.item(item)['values'][0] for item in selected_items]
        
        result = messagebox.askyesno("확인", f"{len(names)}명의 직원을 삭제하시겠습니까?")
        if result:
            success_count = 0
            for name in names:
                if self.employee_manager.delete_employee(name):
                    success_count += 1
            
            messagebox.showinfo("완료", f"{success_count}명의 직원을 삭제했습니다.")
            self.refresh_employee_list()
            self.clear_form()
    
    def quick_add_employee(self):
        """빠른 추가"""
        name = self.quick_name_var.get().strip()
        email = self.quick_email_var.get().strip()
        
        if not name or not email:
            messagebox.showwarning("경고", "이름과 이메일을 모두 입력해주세요.")
            return
        
        if self.employee_manager.add_employee(name, email):
            messagebox.showinfo("성공", f"'{name}' 직원을 추가했습니다.")
            self.refresh_employee_list()
            self.quick_name_var.set("")
            self.quick_email_var.set("")
        else:
            messagebox.showerror("오류", "이미 존재하는 직원입니다.")
    
    def select_all_employees(self):
        """모든 직원 선택"""
        for item in self.employee_tree.get_children():
            self.employee_tree.set(item, 'selected', True)
        self.employee_tree.selection_set(self.employee_tree.get_children())
    
    def deselect_all_employees(self):
        """모든 직원 선택 해제"""
        for item in self.employee_tree.get_children():
            self.employee_tree.set(item, 'selected', False)
        self.employee_tree.selection_set(())
    
    def clear_form(self):
        """폼 초기화"""
        self.name_var.set("")
        self.email_var.set("")
        self.selected_employee = None

class PayslipSplitterGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("급여명세서 분할기 v3 - 이메일 자동발송 (드래그앤드롭 지원)")
        self.root.geometry("900x700")
        
        # 한글 폰트 설정
        try:
            default_font = font.nametofont("TkDefaultFont")
            default_font.configure(family="맑은 고딕", size=9)
            self.root.option_add("*Font", default_font)
        except:
            pass
        
        # 관리자 초기화
        self.employee_manager = EmployeeManager()
        self.email_sender = PayslipEmailSender()
        self.preview_manager = PDFPreviewManager()
        
        # 분할된 파일 정보
        self.split_files = []  # [{"name": "이름", "pdf_path": "경로"}]
        self.file_items = []   # PayslipFileItem 객체들
        
        # 드래그앤드롭 설정
        self.root.drop_target_register(DND_FILES)
        self.root.dnd_bind('<<Drop>>', self.on_drop)
        
        self.setup_ui()
    
    def setup_ui(self):
        # 노트북 (탭) 컨테이너
        self.notebook = ttk.Notebook(self.root)
        self.notebook.pack(fill='both', expand=True, padx=10, pady=10)
        
        # 탭 1: PDF 분할
        self.setup_split_tab()
        
        # 탭 2: 이메일 발송
        self.setup_email_tab()
        
        # 탭 3: 직원 관리
        self.employee_tab = EmployeeManagementTab(self.notebook, self.employee_manager)
    
    def setup_split_tab(self):
        """PDF 분할 탭 설정"""
        split_frame = ttk.Frame(self.notebook)
        self.notebook.add(split_frame, text="PDF 분할")
        
        main_frame = ttk.Frame(split_frame, padding="10")
        main_frame.pack(fill='both', expand=True)
        
        # 파일 선택 섹션
        file_frame = ttk.LabelFrame(main_frame, text="파일 선택", padding="5")
        file_frame.pack(fill='x', pady=(0, 10))
        
        self.file_path_var = tk.StringVar()
        ttk.Label(file_frame, text="PDF 파일: (PDF 파일을 드래그해서 놓거나 찾아보기 버튼 사용)").pack(anchor='w')
        
        file_entry_frame = ttk.Frame(file_frame)
        file_entry_frame.pack(fill='x', pady=5)
        
        self.file_entry = ttk.Entry(file_entry_frame, textvariable=self.file_path_var)
        self.file_entry.pack(side='left', fill='x', expand=True, padx=(0, 5))
        self.file_entry.drop_target_register(DND_FILES)
        self.file_entry.dnd_bind('<<Drop>>', self.on_drop)
        
        ttk.Button(file_entry_frame, text="찾아보기", command=self.browse_file).pack(side='right')
        
        # 옵션 섹션
        options_frame = ttk.LabelFrame(main_frame, text="옵션", padding="5")
        options_frame.pack(fill='x', pady=(0, 10))
        
        self.use_password_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(options_frame, text="생년월일을 비밀번호로 설정", 
                       variable=self.use_password_var).pack(anchor='w', pady=2)
        
        self.overwrite_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(options_frame, text="기존 파일 덮어쓰기", 
                       variable=self.overwrite_var).pack(anchor='w', pady=2)
        
        self.auto_email_var = tk.BooleanVar(value=False)
        ttk.Checkbutton(options_frame, text="분할 완료 후 이메일 자동 발송", 
                       variable=self.auto_email_var).pack(anchor='w', pady=2)
        
        # 처리 버튼
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(pady=(0, 10))
        
        self.process_button = ttk.Button(button_frame, text="급여명세서 분할 시작", 
                                        command=self.start_processing)
        self.process_button.pack()
        
        # 진행 상황
        progress_frame = ttk.LabelFrame(main_frame, text="진행 상황", padding="5")
        progress_frame.pack(fill='x', pady=(0, 10))
        
        self.progress_var = tk.StringVar(value="대기 중...")
        ttk.Label(progress_frame, textvariable=self.progress_var).pack(anchor='w')
        
        self.progress_bar = ttk.Progressbar(progress_frame, mode='indeterminate')
        self.progress_bar.pack(fill='x', pady=(5, 0))
        
        # 결과 로그
        log_frame = ttk.LabelFrame(main_frame, text="처리 결과", padding="5")
        log_frame.pack(fill='both', expand=True)
        
        self.log_text = scrolledtext.ScrolledText(log_frame, height=10, state='disabled')
        self.log_text.pack(fill='both', expand=True)
    
    def setup_email_tab(self):
        """이메일 발송 탭 설정"""
        email_frame = ttk.Frame(self.notebook)
        self.notebook.add(email_frame, text="이메일 발송")
        
        main_frame = ttk.Frame(email_frame, padding="10")
        main_frame.pack(fill='both', expand=True)
        
        # 이메일 설정 섹션
        config_frame = ttk.LabelFrame(main_frame, text="이메일 설정", padding="5")
        config_frame.pack(fill='x', pady=(0, 10))
        
        config_grid = ttk.Frame(config_frame)
        config_grid.pack(fill='x')
        
        # 기본 이메일 설정 (수정 불가)
        ttk.Label(config_grid, text="사용자명:", font=('맑은 고딕', 9, 'bold')).grid(row=0, column=0, sticky='w', padx=(0, 5))
        self.email_user_var = tk.StringVar(value="noreply@munjaon.co.kr")
        user_entry = ttk.Entry(config_grid, textvariable=self.email_user_var, width=30, state='readonly')
        user_entry.grid(row=0, column=1, padx=5)
        
        ttk.Label(config_grid, text="비밀번호:", font=('맑은 고딕', 9, 'bold')).grid(row=1, column=0, sticky='w', padx=(0, 5), pady=2)
        self.email_pass_var = tk.StringVar(value="iEWkihhyZipl")
        pass_entry = ttk.Entry(config_grid, textvariable=self.email_pass_var, width=30, show="*", state='readonly')
        pass_entry.grid(row=1, column=1, padx=5, pady=2)
        
        # 연결 테스트 버튼
        test_button = ttk.Button(config_grid, text="🔌 연결 테스트", command=self.test_email_connection)
        test_button.grid(row=0, column=2, padx=10, rowspan=2)
        
        # 설정 안내 라벨
        info_label = ttk.Label(config_grid, text="ℹ️ 기본 이메일 설정이 적용되어 있습니다.", 
                              font=('맑은 고딕', 8), foreground='gray')
        info_label.grid(row=2, column=0, columnspan=3, pady=(5, 0))
        
        # 파일 매칭 섹션
        self.files_frame = ttk.LabelFrame(main_frame, text="분할된 파일 및 발송 대상", padding="5")
        self.files_frame.pack(fill='both', expand=True, pady=(0, 10))
        
        # 스크롤 가능한 프레임
        self.files_canvas = tk.Canvas(self.files_frame, height=300)
        files_scrollbar = ttk.Scrollbar(self.files_frame, orient="vertical", command=self.files_canvas.yview)
        self.files_scrollable_frame = ttk.Frame(self.files_canvas)
        
        self.files_scrollable_frame.bind(
            "<Configure>",
            lambda e: self.files_canvas.configure(scrollregion=self.files_canvas.bbox("all"))
        )
        
        self.files_canvas.create_window((0, 0), window=self.files_scrollable_frame, anchor="nw")
        self.files_canvas.configure(yscrollcommand=files_scrollbar.set)
        
        self.files_canvas.pack(side="left", fill="both", expand=True)
        files_scrollbar.pack(side="right", fill="y")
        
        # 발송 버튼 및 상태
        send_frame = ttk.Frame(main_frame)
        send_frame.pack(fill='x', pady=(0, 10))
        
        left_buttons = ttk.Frame(send_frame)
        left_buttons.pack(side='left')
        
        ttk.Button(left_buttons, text="전체 선택", command=self.select_all_files).pack(side='left', padx=(0, 5))
        ttk.Button(left_buttons, text="전체 해제", command=self.deselect_all_files).pack(side='left', padx=5)
        ttk.Button(left_buttons, text="매칭 새로고침", command=self.refresh_file_matching).pack(side='left', padx=5)
        
        self.send_button = ttk.Button(send_frame, text="선택된 직원에게 이메일 발송", 
                                     command=self.start_email_sending)
        self.send_button.pack(side='right')
        
        # 발송 상태
        self.email_status_var = tk.StringVar(value="이메일 발송 대기")
        ttk.Label(main_frame, textvariable=self.email_status_var).pack()
    
    def on_drop(self, event):
        """드래그앤드롭으로 파일을 받았을 때 처리"""
        files = self.root.tk.splitlist(event.data)
        if files:
            file_path = files[0]
            if file_path.lower().endswith('.pdf'):
                self.file_path_var.set(file_path)
                self.log_message(f"파일이 드롭되었습니다: {os.path.basename(file_path)}")
            else:
                messagebox.showwarning("경고", "PDF 파일만 지원됩니다.")
    
    def browse_file(self):
        filename = filedialog.askopenfilename(
            title="급여명세서 PDF 파일 선택",
            filetypes=[("PDF files", "*.pdf"), ("All files", "*.*")]
        )
        if filename:
            self.file_path_var.set(filename)
    
    def log_message(self, message):
        """로그 텍스트에 메시지 추가"""
        self.log_text.config(state='normal')
        self.log_text.insert(tk.END, message + '\n')
        self.log_text.config(state='disabled')
        self.log_text.see(tk.END)
        self.root.update()
    
    def clear_log(self):
        """로그 텍스트 클리어"""
        self.log_text.config(state='normal')
        self.log_text.delete(1.0, tk.END)
        self.log_text.config(state='disabled')
    
    def start_processing(self):
        """처리 시작 (별도 스레드에서)"""
        if not self.file_path_var.get():
            messagebox.showerror("오류", "PDF 파일을 선택해주세요.")
            return
        
        if not os.path.exists(self.file_path_var.get()):
            messagebox.showerror("오류", "선택한 파일이 존재하지 않습니다.")
            return
        
        # UI 상태 변경
        self.process_button.config(state='disabled')
        self.progress_bar.start()
        self.progress_var.set("처리 중...")
        self.clear_log()
        
        # 별도 스레드에서 처리
        thread = threading.Thread(target=self.process_pdf)
        thread.daemon = True
        thread.start()
    
    def process_pdf(self):
        """PDF 처리 메인 로직"""
        try:
            input_pdf = self.file_path_var.get()
            use_password = self.use_password_var.get()
            overwrite = self.overwrite_var.get()
            
            self.log_message(f"파일 처리 시작: {os.path.basename(input_pdf)}")
            self.log_message(f"비밀번호 설정: {'사용' if use_password else '사용 안 함'}")
            self.log_message("=" * 50)
            
            base_name = os.path.splitext(os.path.basename(input_pdf))[0]
            doc = fitz.open(input_pdf)
            
            if not doc.page_count:
                self.log_message("오류: PDF에 페이지가 없습니다.")
                return
            
            self.log_message(f"총 {doc.page_count}페이지 처리를 시작합니다...")
            
            success_count = 0
            fail_count = 0
            self.split_files = []
            
            for i, page in enumerate(doc):
                page_num = i + 1
                text = page.get_text()
                
                name_match = re.search(r"사원명:\s*(\S+)", text)
                
                if name_match:
                    name = name_match.group(1)
                    output_filename = f"{base_name}_{name}.pdf"
                    
                    if os.path.exists(output_filename) and not overwrite:
                        self.log_message(f"- {page_num}페이지: '{name}'님 파일이 이미 존재합니다. (건너뜀)")
                        continue
                    
                    new_doc = fitz.open()
                    new_doc.insert_pdf(doc, from_page=i, to_page=i)
                    
                    if use_password:
                        birth_date_password = extract_birth_date_numbers(text)
                        
                        if birth_date_password:
                            try:
                                new_doc.save(output_filename,
                                           encryption=fitz.PDF_ENCRYPT_AES_256,
                                           user_pw=birth_date_password,
                                           owner_pw=birth_date_password)
                                self.log_message(f"- {page_num}페이지: '{name}'님 (비밀번호: {birth_date_password}) ✓")
                                success_count += 1
                            except Exception as e:
                                new_doc.save(output_filename)
                                self.log_message(f"- {page_num}페이지: '{name}'님 (비밀번호 설정 실패, 일반 파일로 저장) ⚠️")
                                success_count += 1
                        else:
                            new_doc.save(output_filename)
                            self.log_message(f"- {page_num}페이지: '{name}'님 (생년월일 없음, 일반 파일로 저장) ⚠️")
                            success_count += 1
                    else:
                        new_doc.save(output_filename)
                        self.log_message(f"- {page_num}페이지: '{name}'님 (일반 파일로 저장) ✓")
                        success_count += 1
                    
                    # 분할된 파일 정보 저장
                    self.split_files.append({
                        "name": name,
                        "pdf_path": output_filename
                    })
                    
                    new_doc.close()
                else:
                    self.log_message(f"- {page_num}페이지: 사원명을 찾지 못했습니다. ❌")
                    fail_count += 1
            
            doc.close()
            
            self.log_message("=" * 50)
            self.log_message(f"처리 완료! 성공: {success_count}개, 실패: {fail_count}개")
            
            if success_count > 0:
                # 이메일 탭의 파일 목록 업데이트
                self.root.after(0, self.refresh_file_matching)
                
                # 자동 이메일 발송 확인
                if self.auto_email_var.get():
                    self.root.after(0, self.auto_send_emails)
                
                messagebox.showinfo("완료", f"급여명세서 분할이 완료되었습니다.\n성공: {success_count}개, 실패: {fail_count}개")
            else:
                messagebox.showwarning("경고", "처리된 파일이 없습니다. PDF 형식을 확인해주세요.")
        
        except Exception as e:
            error_msg = f"오류가 발생했습니다: {str(e)}"
            self.log_message(error_msg)
            messagebox.showerror("오류", error_msg)
        
        finally:
            self.root.after(0, self.finish_processing)
    
    def finish_processing(self):
        """처리 완료 후 UI 상태 복원"""
        self.progress_bar.stop()
        self.progress_var.set("완료")
        self.process_button.config(state='normal')
    
    def refresh_file_matching(self):
        """파일 매칭 새로고침"""
        # 기존 아이템들 제거
        for item in self.file_items:
            if hasattr(item, 'main_frame'):
                item.main_frame.destroy()
        self.file_items.clear()
        
        # 직원 목록 가져오기
        employees = self.employee_manager.get_all_employees()
        
        # 분할된 파일들에 대해 매칭
        for file_info in self.split_files:
            name = file_info["name"]
            pdf_path = file_info["pdf_path"]
            email = employees.get(name, "")
            
            # 파일 아이템 생성
            file_item = PayslipFileItem(
                self.files_scrollable_frame, 
                name, email, pdf_path, 
                self.preview_manager,
                self.update_send_status
            )
            self.file_items.append(file_item)
        
        self.update_send_status()
    
    def update_send_status(self):
        """발송 상태 업데이트"""
        total_count = len(self.file_items)
        send_count = sum(1 for item in self.file_items if item.send_var.get() and item.email)
        matched_count = sum(1 for item in self.file_items if item.email)
        
        status = f"전체: {total_count}명, 매칭됨: {matched_count}명, 발송대상: {send_count}명"
        self.email_status_var.set(status)
    
    def select_all_files(self):
        """전체 파일 선택"""
        for item in self.file_items:
            if item.email:  # 이메일이 있는 경우만
                item.send_var.set(True)
                item.on_send_status_change()
    
    def deselect_all_files(self):
        """전체 파일 해제"""
        for item in self.file_items:
            item.send_var.set(False)
            item.on_send_status_change()
    
    def test_email_connection(self):
        """이메일 연결 테스트"""
        username = self.email_user_var.get().strip()
        password = self.email_pass_var.get().strip()
        
        # 연결 테스트 시작 알림
        self.email_status_var.set("🔌 이메일 서버 연결 테스트 중...")
        self.root.update()
        
        self.email_sender.set_credentials(username, password)
        success, message = self.email_sender.test_connection()
        
        if success:
            self.email_status_var.set("✅ 연결 성공! 이메일 발송 준비 완료")
            messagebox.showinfo("🎉 연결 성공", f"✅ SMTP 서버에 성공적으로 연결되었습니다!\n\n📧 이제 급여명세서를 이메일로 발송할 수 있습니다.\n\n설정: {username}")
        else:
            self.email_status_var.set("❌ 연결 실패 - 설정을 확인해주세요")
            messagebox.showerror("⚠️ 연결 실패", f"❌ SMTP 서버 연결에 실패했습니다.\n\n🔍 오류 내용:\n{message}\n\n📞 문제가 지속되면 IT팀에 문의해주세요.")
    
    def start_email_sending(self):
        """이메일 발송 시작"""
        # 발송할 데이터 수집
        send_data = []
        for item in self.file_items:
            data = item.get_send_data()
            if data:
                send_data.append(data)
        
        print(f"[DEBUG] 총 {len(send_data)}개의 이메일 발송 대상")
        
        if not send_data:
            messagebox.showwarning("경고", "발송할 파일이 없습니다.\n매칭된 직원을 선택해주세요.")
            return
        
        # 인증 정보 확인
        username = self.email_user_var.get().strip()
        password = self.email_pass_var.get().strip()
        
        if not username or not password:
            messagebox.showwarning("경고", "이메일 사용자명과 비밀번호를 입력해주세요.")
            return
        
        # 발송 확인
        result = messagebox.askyesno("확인", f"{len(send_data)}명에게 이메일을 발송하시겠습니까?")
        if not result:
            return
        
        # UI 비활성화
        self.send_button.config(state='disabled')
        
        # 별도 스레드에서 발송
        self.email_sender.set_credentials(username, password)
        thread = threading.Thread(target=self.send_emails, args=(send_data,))
        thread.daemon = True
        thread.start()
    
    def send_emails(self, send_data):
        """이메일 발송 (별도 스레드)"""
        def progress_callback(current, total, name):
            self.root.after(0, lambda: self.email_status_var.set(f"발송 중... {current}/{total} ({name})"))
        
        try:
            results = self.email_sender.send_bulk_emails(send_data, progress_callback)
            
            success_count = len(results["success"])
            failed_count = len(results["failed"])
            
            # 발송 성공한 항목들의 UI 업데이트
            for success_item in results["success"]:
                success_name = success_item.get("name")
                # 해당 직원의 파일 아이템 찾기
                for file_item in self.file_items:
                    if file_item.employee_name == success_name:
                        self.root.after(0, lambda item=file_item: item.mark_as_sent())
                        break
            
            # 결과 메시지
            message = f"이메일 발송 완료!\n\n성공: {success_count}명\n실패: {failed_count}명"
            
            if results["failed"]:
                message += "\n\n실패 목록:"
                for failed in results["failed"][:3]:  # 최대 3개만 표시
                    message += f"\n- {failed['name']}: {failed['error'][:50]}..."
                
                if len(results["failed"]) > 3:
                    message += f"\n... 및 {len(results['failed']) - 3}건 더"
            
            self.root.after(0, lambda: messagebox.showinfo("발송 완료", message))
            self.root.after(0, lambda: self.email_status_var.set(f"발송 완료: 성공 {success_count}명, 실패 {failed_count}명"))
            
        except Exception as e:
            error_msg = f"이메일 발송 중 오류: {str(e)}"
            self.root.after(0, lambda: messagebox.showerror("발송 오류", error_msg))
            self.root.after(0, lambda: self.email_status_var.set("발송 실패"))
        
        finally:
            self.root.after(0, lambda: self.send_button.config(state='normal'))
    
    def auto_send_emails(self):
        """자동 이메일 발송"""
        # 인증 정보가 있는지 확인
        username = self.email_user_var.get().strip()
        password = self.email_pass_var.get().strip()
        
        if not username or not password:
            messagebox.showwarning("자동 발송 실패", "이메일 인증 정보가 설정되지 않았습니다.")
            return
        
        # 이메일 탭으로 전환
        self.notebook.select(1)
        
        # 잠시 후 발송 시작
        self.root.after(1000, self.start_email_sending)

if __name__ == "__main__":
    root = TkinterDnD.Tk()
    app = PayslipSplitterGUI(root)
    root.mainloop()