"""
テーマ対応マスタ管理アプリケーション
UI統一 + SQLiteテーマ管理
"""

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

class ThemeManager:
    """テーマ管理クラス"""
    
    def __init__(self):
        self.themes = {}
        self.current_theme = None
        self._load_themes()
    
    def _load_themes(self):
        """テーマ情報をSQLiteから読み込む"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            # テーマテーブル作成
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS themes (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL UNIQUE,
                    title TEXT NOT NULL,
                    table_name TEXT NOT NULL,
                    fields TEXT NOT NULL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # デフォルトテーマを挿入
            default_themes = [
                {
                    'name': 'customers',
                    'title': '顧客マスタ',
                    'table_name': 'customers',
                    'fields': '[{"name": "name", "label": "顧客名", "width": 200, "required": true}, {"name": "phone", "label": "電話番号", "width": 200}, {"name": "email", "label": "メールアドレス", "width": 250}, {"name": "address", "label": "住所", "width": 300}]'
                },
                {
                    'name': 'products',
                    'title': '商品マスタ',
                    'table_name': 'products',
                    'fields': '[{"name": "name", "label": "商品名", "width": 200, "required": true}, {"name": "category", "label": "カテゴリ", "width": 150}, {"name": "price", "label": "価格", "width": 100, "keyboard_type": "number", "required": true}, {"name": "stock", "label": "在庫数", "width": 100, "keyboard_type": "number"}]'
                },
                {
                    'name': 'sales_slips',
                    'title': '伝票マスタ',
                    'table_name': 'sales_slips',
                    'fields': '[{"name": "title", "label": "伝票タイトル", "width": 300, "required": true}, {"name": "customer_name", "label": "顧客名", "width": 200, "required": true}, {"name": "items", "label": "明細", "width": 400, "keyboard_type": "multiline", "required": true}, {"name": "total_amount", "label": "合計金額", "width": 150, "keyboard_type": "number", "required": true}]'
                }
            ]
            
            # デフォルトテーマがなければ挿入
            cursor.execute("SELECT COUNT(*) FROM themes")
            if cursor.fetchone()[0] == 0:
                for theme in default_themes:
                    cursor.execute('''
                        INSERT INTO themes (name, title, table_name, fields)
                        VALUES (?, ?, ?, ?)
                    ''', (theme['name'], theme['title'], theme['table_name'], theme['fields']))
                conn.commit()
            
            # テーマを読み込み
            cursor.execute("SELECT * FROM themes ORDER BY id")
            themes_data = cursor.fetchall()
            
            for theme_data in themes_data:
                theme_id, name, title, table_name, fields_json, created_at = theme_data
                self.themes[name] = {
                    'id': theme_id,
                    'title': title,
                    'table_name': table_name,
                    'fields': eval(fields_json)  # JSONをPythonオブジェクトに変換
                }
            
            conn.close()
            logging.info(f"テーマ読込完了: {len(self.themes)}個")
            
        except Exception as e:
            logging.error(f"テーマ読込エラー: {e}")
    
    def get_theme_names(self) -> List[str]:
        """テーマ名リストを取得"""
        return list(self.themes.keys())
    
    def get_theme(self, name: str) -> Dict:
        """指定されたテーマを取得"""
        return self.themes.get(name, {})

class UniversalMasterEditor:
    """汎用マスタ編集コンポーネント"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        self.theme_manager = ThemeManager()
        
        # 現在のテーマ
        self.current_theme_name = 'customers'
        self.current_theme = self.theme_manager.get_theme(self.current_theme_name)
        self.current_data = []
        self.editing_id = None
        
        # UI部品
        self.title = ft.Text("", size=24, weight=ft.FontWeight.BOLD, color=ft.Colors.BLUE_900)
        self.theme_dropdown = ft.Dropdown(
            label="マスタ選択",
            options=[],
            value="customers",
            on_change=self.change_theme
        )
        
        # フォーム
        self.form_fields = ft.Column([], spacing=10)
        
        # ボタン群
        self.add_btn = ft.Button("追加", on_click=self.add_new, bgcolor=ft.Colors.BLUE, color=ft.Colors.WHITE)
        self.save_btn = ft.Button("保存", on_click=self.save_data, bgcolor=ft.Colors.GREEN, color=ft.Colors.WHITE)
        self.delete_btn = ft.Button("削除", on_click=self.delete_selected, bgcolor=ft.Colors.RED, color=ft.Colors.WHITE)
        self.clear_btn = ft.Button("クリア", on_click=self.clear_form, bgcolor=ft.Colors.ORANGE, color=ft.Colors.WHITE)
        
        # データリスト
        self.data_list = ft.Column([], scroll=ft.ScrollMode.AUTO, height=300)
        
        # 操作説明
        self.instructions = ft.Text(
            "操作方法: マスタを選択してデータを編集・追加・削除",
            size=12,
            color=ft.Colors.GREY_600
        )
        
        # 初期化
        self._update_theme_dropdown()
        self._build_form()
        self._load_data()
    
    def _update_theme_dropdown(self):
        """テーマドロップダウンを更新"""
        theme_names = self.theme_manager.get_theme_names()
        self.theme_dropdown.options = [
            ft.dropdown.Option(theme['title'], name) 
            for name, theme in self.theme_manager.themes.items()
        ]
        self.page.update()
    
    def change_theme(self, e):
        """テーマを切り替え"""
        self.current_theme_name = e.control.value
        self.current_theme = self.theme_manager.get_theme(self.current_theme_name)
        self.editing_id = None
        self.title.value = self.current_theme['title']
        self._build_form()
        self._load_data()
        self.page.update()
    
    def _build_form(self):
        """入力フォームを構築"""
        self.form_fields.controls.clear()
        
        for field in self.current_theme['fields']:
            keyboard_type = ft.KeyboardType.TEXT
            if field.get('keyboard_type') == 'number':
                keyboard_type = ft.KeyboardType.NUMBER
            elif field.get('keyboard_type') == 'multiline':
                keyboard_type = ft.KeyboardType.MULTILINE
            
            field_control = ft.TextField(
                label=field['label'],
                value='',
                width=field['width'],
                keyboard_type=keyboard_type
            )
            self.form_fields.controls.append(field_control)
        
        self.page.update()
    
    def _load_data(self):
        """データを読み込む"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            table_name = self.current_theme['table_name']
            cursor.execute(f'''
                SELECT * FROM {table_name}
                ORDER BY id
            ''')
            
            self.current_data = cursor.fetchall()
            conn.close()
            
            # データリストを更新
            self.data_list.controls.clear()
            for item in self.current_data:
                item_id = item[0]
                item_data = dict(zip([col[0] for col in cursor.description], item))
                
                # データ行
                row_controls = []
                for field in self.current_theme['fields']:
                    field_name = field['name']
                    value = item_data.get(field_name, '')
                    
                    row_controls.append(
                        ft.Text(f"{field['label']}: {value}", size=12)
                    )
                
                # 操作ボタン
                row_controls.extend([
                    ft.Button(
                        "編集",
                        on_click=lambda _, did=item_id: self.edit_item(item_id),
                        bgcolor=ft.Colors.ORANGE,
                        color=ft.Colors.WHITE,
                        width=60
                    ),
                    ft.Button(
                        "削除",
                        on_click=lambda _, did=item_id: self.delete_item(item_id),
                        bgcolor=ft.Colors.RED,
                        color=ft.Colors.WHITE,
                        width=60
                    )
                ])
                
                # データカード
                data_card = ft.Card(
                    content=ft.Container(
                        content=ft.Column(row_controls),
                        padding=10
                    ),
                    margin=ft.margin.only(bottom=5)
                )
                
                self.data_list.controls.append(data_card)
            
            self.page.update()
            
        except Exception as e:
            logging.error(f"{self.current_theme_name}データ読込エラー: {e}")
    
    def save_data(self, e):
        """データを保存"""
        try:
            # フォームデータを収集
            form_data = {}
            for i, field in enumerate(self.current_theme['fields']):
                field_control = self.form_fields.controls[i]
                form_data[field['name']] = field_control.value
                
                # 必須項目チェック
                if field.get('required', False) and not field_control.value.strip():
                    self._show_snackbar(f"{field['label']}は必須項目です", ft.Colors.RED)
                    return
            
            # データベースに保存
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            table_name = self.current_theme['table_name']
            
            if self.editing_id:
                # 更新
                columns = ', '.join([f"{key} = ?" for key in form_data.keys()])
                cursor.execute(f'''
                    UPDATE {table_name}
                    SET {columns}
                    WHERE id = ?
                ''', tuple(form_data.values()) + (self.editing_id,))
                
                self._show_snackbar("データを更新しました", ft.Colors.GREEN)
                logging.info(f"{table_name}データ更新完了: ID={self.editing_id}")
            else:
                # 新規追加
                columns = ', '.join([field['name'] for field in self.current_theme['fields']])
                placeholders = ', '.join(['?' for _ in self.current_theme['fields']])
                
                cursor.execute(f'''
                    INSERT INTO {table_name} ({columns})
                    VALUES ({placeholders})
                ''', tuple(form_data.values()))
                
                self._show_snackbar("データを追加しました", ft.Colors.GREEN)
                logging.info(f"{table_name}データ追加完了")
            
            conn.commit()
            conn.close()
            
            # フォームをクリア
            self.clear_form(None)
            
            # データ再読み込み
            self._load_data()
            
        except Exception as e:
            logging.error(f"{self.current_theme_name}データ保存エラー: {e}")
            self._show_snackbar("保存エラー", ft.Colors.RED)
    
    def add_new(self, e):
        """新規データを追加"""
        self.editing_id = None
        self.clear_form(None)
        self.form_fields.controls[0].focus()
        logging.info(f"{self.current_theme_name}新規追加モード")
    
    def edit_item(self, item_id):
        """データを編集"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            table_name = self.current_theme['table_name']
            cursor.execute(f'''
                SELECT * FROM {table_name}
                WHERE id = ?
            ''', (item_id,))
            
            result = cursor.fetchone()
            conn.close()
            
            if result:
                self.editing_id = item_id
                
                # フォームにデータを設定
                for i, field in enumerate(self.current_theme['fields']):
                    field_control = self.form_fields.controls[i]
                    field_control.value = result[i+1] if i+1 < len(result) else ''
                
                self.page.update()
                logging.info(f"{table_name}編集モード: ID={item_id}")
            
        except Exception as e:
            logging.error(f"{self.current_theme_name}編集エラー: {e}")
    
    def delete_item(self, item_id):
        """データを削除"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            table_name = self.current_theme['table_name']
            cursor.execute(f'''
                DELETE FROM {table_name}
                WHERE id = ?
            ''', (item_id,))
            
            conn.commit()
            conn.close()
            
            # データ再読み込み
            self._load_data()
            
            self._show_snackbar("データを削除しました", ft.Colors.GREEN)
            logging.info(f"{table_name}削除完了: ID={item_id}")
            
        except Exception as e:
            logging.error(f"{self.current_theme_name}削除エラー: {e}")
            self._show_snackbar("削除エラー", ft.Colors.RED)
    
    def delete_selected(self, e):
        """選択中のデータを削除"""
        if self.editing_id:
            self.delete_item(self.editing_id)
        else:
            self._show_snackbar("削除対象が選択されていません", ft.Colors.ORANGE)
    
    def clear_form(self, e):
        """フォームをクリア"""
        for field_control in self.form_fields.controls:
            field_control.value = ''
        
        self.editing_id = None
        self.page.update()
        logging.info("フォームをクリア")
    
    def _show_snackbar(self, message: str, color: ft.Colors):
        """SnackBarを表示"""
        try:
            self.page.snack_bar = ft.SnackBar(
                content=ft.Text(message),
                bgcolor=color
            )
            self.page.snack_bar.open = True
            self.page.update()
        except:
            pass
    
    def build(self):
        """UIを構築して返す"""
        return ft.Column([
            ft.Row([
                self.title,
                self.theme_dropdown
            ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN),
            ft.Divider(),
            ft.Text("入力フォーム", size=18, weight=ft.FontWeight.BOLD),
            self.form_fields,
            ft.Row([self.add_btn, self.save_btn, self.delete_btn, self.clear_btn], spacing=10),
            ft.Divider(),
            ft.Text(f"{self.current_theme['title']}一覧", size=18, weight=ft.FontWeight.BOLD),
            self.instructions,
            self.data_list
        ], expand=True, spacing=15)

class ThemeMasterApp:
    """テーマ対応マスタ管理アプリケーション"""
    
    def __init__(self, page: ft.Page):
        self.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()
        
        # ウィンドウ設定
        page.title = "テーマ対応マスタ管理システム"
        page.window_width = 1000
        page.window_height = 700
        page.theme_mode = ft.ThemeMode.LIGHT
        
        # ウィンドウクローズイベント
        page.on_window_close = lambda _: signal_handler(0, None)
        
        # テーマ対応マスタエディタ作成
        self.theme_editor = UniversalMasterEditor(page)
        
        # ページ構築
        page.add(
            self.theme_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 customers (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    phone TEXT,
                    email TEXT,
                    address TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS products (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    category TEXT,
                    price REAL NOT NULL,
                    stock INTEGER DEFAULT 0,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS sales_slips (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    title TEXT NOT NULL,
                    customer_name TEXT NOT NULL,
                    items TEXT NOT NULL,
                    total_amount REAL NOT NULL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            conn.commit()
            conn.close()
            logging.info("マスタデータベース初期化完了")
            
        except Exception as e:
            logging.error(f"データベース初期化エラー: {e}")

def main(page: ft.Page):
    """メイン関数"""
    try:
        app = ThemeMasterApp(page)
        
    except Exception as e:
        logging.error(f"アプリケーション起動エラー: {e}")

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