import flet as ft
import sqlite3
import signal
import sys
import logging
import random
from datetime import datetime
from typing import List, Dict, Optional

class ErrorHandler:
    """グローバルエラーハンドラ"""
    
    @staticmethod
    def handle_error(error: Exception, context: str = ""):
        """エラーを一元処理"""
        error_msg = f"{context}: {str(error)}"
        logging.error(error_msg)
        print(f"❌ {error_msg}")
        
        try:
            if hasattr(ErrorHandler, 'current_page'):
                ErrorHandler.show_snackbar(ErrorHandler.current_page, error_msg, ft.Colors.RED)
        except:
            pass
    
    @staticmethod
    def show_snackbar(page, message: str, color: ft.Colors = ft.Colors.RED):
        """SnackBarを表示"""
        try:
            page.snack_bar = ft.SnackBar(
                content=ft.Text(message),
                bgcolor=color
            )
            page.snack_bar.open = True
            page.update()
        except:
            pass

class TextEditor:
    """テキストエディタ"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        
        # UI部品
        self.title = ft.Text("下書きエディタ", size=24, weight=ft.FontWeight.BOLD, color=ft.Colors.BLUE_900)
        
        # テキストエリア
        self.text_area = ft.TextField(
            label="下書き内容",
            multiline=True,
            min_lines=10,
            max_lines=50,
            value="",
            autofocus=True,
            width=600,
            height=400
        )
        
        # ボタン群
        self.save_btn = ft.Button(
            "保存",
            on_click=self.save_draft,
            bgcolor=ft.Colors.GREEN,
            color=ft.Colors.WHITE
        )
        
        self.clear_btn = ft.Button(
            "クリア",
            on_click=self.clear_text,
            bgcolor=ft.Colors.ORANGE,
            color=ft.Colors.WHITE
        )
        
        self.load_btn = ft.Button(
            "読込",
            on_click=self.load_draft,
            bgcolor=ft.Colors.BLUE,
            color=ft.Colors.WHITE
        )
        
        self.delete_btn = ft.Button(
            "削除",
            on_click=self.delete_draft,
            bgcolor=ft.Colors.RED,
            color=ft.Colors.WHITE
        )
        
        # 下書きリスト
        self.draft_list = ft.Column([], scroll=ft.ScrollMode.AUTO, height=200)
        
        # 操作説明
        self.instructions = ft.Text(
            "操作方法: TABでフォーカス移動、SPACE/ENTERで保存、マウスクリックでもボタン操作可能",
            size=12,
            color=ft.Colors.GREY_600
        )
        
        # データ読み込み
        self.load_drafts()
    
    def build(self):
        """UIを構築して返す"""
        return ft.Column([
            self.title,
            ft.Divider(),
            ft.Row([self.save_btn, self.clear_btn, self.load_btn, self.delete_btn], spacing=10),
            ft.Divider(),
            self.text_area,
            ft.Divider(),
            ft.Text("下書きリスト", size=18, weight=ft.FontWeight.BOLD),
            self.instructions,
            self.draft_list
        ], expand=True, spacing=15)
    
    def save_draft(self, e):
        """下書きを保存"""
        if self.text_area.value.strip():
            try:
                conn = sqlite3.connect('sales.db')
                cursor = conn.cursor()
                
                cursor.execute('''
                    CREATE TABLE IF NOT EXISTS drafts (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        title TEXT NOT NULL,
                        content TEXT NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                ''')
                
                cursor.execute('''
                    INSERT INTO drafts (title, content)
                    VALUES (?, ?)
                ''', (f"下書き_{datetime.now().strftime('%Y%m%d_%H%M%S')}", self.text_area.value))
                
                conn.commit()
                conn.close()
                
                # 成功メッセージ
                ErrorHandler.show_snackbar(self.page, "下書きを保存しました", ft.Colors.GREEN)
                logging.info(f"下書き保存: {len(self.text_area.value)} 文字")
                
                # リスト更新
                self.load_drafts()
                
            except Exception as ex:
                ErrorHandler.handle_error(ex, "下書き保存エラー")
    
    def clear_text(self, e):
        """テキストをクリア"""
        self.text_area.value = ""
        self.page.update()
        logging.info("テキストをクリア")
    
    def load_draft(self, e):
        """下書きを読み込み"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS drafts (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        title TEXT NOT NULL,
                        content TEXT NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                ''')
            
            cursor.execute('''
                SELECT id, title, content, created_at 
                FROM drafts 
                ORDER BY created_at DESC 
                LIMIT 10
            ''')
            drafts = cursor.fetchall()
            conn.close()
            
            if drafts:
                # テキストエリアに設定
                self.text_area.value = drafts[0][2]  # content
                
                # リスト更新
                self.draft_list.controls.clear()
                for draft in drafts:
                    draft_id, title, content, created_at = draft
                    
                    # 下書きカード
                    draft_card = ft.Card(
                        content=ft.Container(
                            content=ft.Column([
                                ft.Row([
                                    ft.Text(f"ID: {draft_id}", size=12, color=ft.Colors.GREY_600),
                                    ft.Text(f"作成: {created_at}", size=12, color=ft.Colors.GREY_600)
                                ], spacing=5),
                                ft.Text(title, weight=ft.FontWeight.BOLD, size=14),
                                ft.Text(content[:100] + "..." if len(content) > 100 else content, size=12),
                            ]),
                            padding=10,
                            width=400
                        ),
                        margin=ft.margin.only(bottom=5)
                    )
                    
                    # 読込ボタン
                    load_btn = ft.Button(
                        "読込",
                        on_click=lambda _, did=draft_id: self.load_specific_draft(draft_id),
                        bgcolor=ft.Colors.BLUE,
                        color=ft.Colors.WHITE,
                        width=80
                    )
                    
                    self.draft_list.controls.append(
                        ft.Row([draft_card, load_btn], alignment=ft.MainAxisAlignment.SPACE_BETWEEN)
                    )
                
                self.page.update()
                logging.info(f"下書き読込完了: {len(drafts)} 件")
                
            else:
                ErrorHandler.show_snackbar(self.page, "下書きがありません", ft.Colors.ORANGE)
            
        except Exception as ex:
            ErrorHandler.handle_error(ex, "下書き読込エラー")
    
    def load_specific_draft(self, draft_id):
        """特定の下書きを読み込む"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            cursor.execute('''
                SELECT content 
                FROM drafts 
                WHERE id = ?
            ''', (draft_id,))
            
            result = cursor.fetchone()
            conn.close()
            
            if result:
                self.text_area.value = result[0]
                ErrorHandler.show_snackbar(self.page, f"下書き #{draft_id} を読み込みました", ft.Colors.GREEN)
                logging.info(f"下書き読込: ID={draft_id}")
            else:
                ErrorHandler.show_snackbar(self.page, "下書きが見つかりません", ft.Colors.RED)
                
        except Exception as ex:
            ErrorHandler.handle_error(ex, "下書き読込エラー")
    
    def delete_draft(self, e):
        """下書きを削除"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            cursor.execute('''
                DELETE FROM drafts 
                WHERE id = (SELECT id FROM drafts ORDER BY created_at DESC LIMIT 1)
            ''')
            
            conn.commit()
            conn.close()
            
            # リスト更新
            self.load_drafts()
            
            ErrorHandler.show_snackbar(self.page, "下書きを削除しました", ft.Colors.GREEN)
            logging.info("下書き削除完了")
            
        except Exception as ex:
            ErrorHandler.handle_error(ex, "下書き削除エラー")
    
    def load_drafts(self):
        """下書きリストを読み込む"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS drafts (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        title TEXT NOT NULL,
                        content TEXT NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                ''')
            
            cursor.execute('''
                SELECT id, title, content, created_at 
                FROM drafts 
                ORDER BY created_at DESC 
                LIMIT 10
            ''')
            drafts = cursor.fetchall()
            conn.close()
            
            # リストを更新
            self.draft_list.controls.clear()
            for draft in drafts:
                draft_id, title, content, created_at = draft
                
                # 下書きカード
                draft_card = ft.Card(
                    content=ft.Container(
                        content=ft.Column([
                            ft.Row([
                                ft.Text(f"ID: {draft_id}", size=12, color=ft.Colors.GREY_600),
                                ft.Text(f"作成: {created_at}", size=12, color=ft.Colors.GREY_600)
                            ], spacing=5),
                            ft.Text(title, weight=ft.FontWeight.BOLD, size=14),
                            ft.Text(content[:100] + "..." if len(content) > 100 else content, size=12),
                        ]),
                        padding=10,
                        width=400
                    ),
                    margin=ft.margin.only(bottom=5)
                )
                
                # 読込ボタン
                load_btn = ft.Button(
                    "読込",
                    on_click=lambda _, did=draft_id: self.load_specific_draft(draft_id),
                    bgcolor=ft.Colors.BLUE,
                    color=ft.Colors.WHITE,
                    width=80
                )
                
                self.draft_list.controls.append(
                    ft.Row([draft_card, load_btn], alignment=ft.MainAxisAlignment.SPACE_BETWEEN)
                )
                
            self.page.update()
            
        except Exception as e:
            ErrorHandler.handle_error(e, "下書きリスト読込エラー")

class SimpleApp:
    """シンプルなアプリケーション"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        ErrorHandler.current_page = page
        
        # ログ設定
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('app.log'),
                logging.StreamHandler()
            ]
        )
        
        # シグナルハンドラ設定
        def signal_handler(signum, frame):
            print(f"\nシグナル {signum} を受信しました")
            print("✅ 正常終了処理完了")
            logging.info("アプリケーション正常終了")
            sys.exit(0)
        
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
        
        # データベース初期化
        self._init_database()
        
        # テキストエディタ作成
        self.text_editor = TextEditor(page)
        
        # ページ構築
        page.add(
            self.text_editor.build()
        )
        
        logging.info("テキストエディタ起動完了")
        print("🚀 テキストエディタ起動完了")
    
    def _init_database(self):
        """データベース初期化"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            # 下書きテーブル作成
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS drafts (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        title TEXT NOT NULL,
                        content TEXT NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                ''')
            
            conn.commit()
            conn.close()
            logging.info("データベース初期化完了")
            
        except Exception as e:
            ErrorHandler.handle_error(e, "データベース初期化エラー")

def main(page: ft.Page):
    """メイン関数"""
    try:
        # ウィンドウ設定
        page.title = "テキストエディタ"
        page.window_width = 800
        page.window_height = 600
        page.theme_mode = ft.ThemeMode.LIGHT
        
        # ウィンドウクローズイベント
        page.on_window_close = lambda _: SimpleApp(page)._cleanup_resources()
        
        # アプリケーション起動
        app = SimpleApp(page)
        
    except Exception as e:
        ErrorHandler.handle_error(e, "アプリケーション起動エラー")

if __name__ == "__main__":
    ft.run(main)
