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}")
        
        # SnackBarでユーザーに通知
        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 DummyDataGenerator:
    """テスト用ダミーデータ生成"""
    
    @staticmethod
    def generate_customers(count: int = 100) -> List[Dict]:
        """ダミー顧客データ生成"""
        first_names = ["田中", "佐藤", "鈴木", "高橋", "伊藤", "渡辺", "山本", "中村", "小林", "加藤"]
        last_names = ["太郎", "次郎", "三郎", "花子", "美子", "健一", "恵子", "大輔", "由美", "翔太"]
        
        customers = []
        for i in range(count):
            name = f"{random.choice(first_names)} {random.choice(last_names)}"
            customers.append({
                'id': i + 1,
                'name': name,
                'phone': f"090-{random.randint(1000, 9999)}-{random.randint(1000, 9999)}",
                'email': f"customer{i+1}@example.com",
                'address': f"東京都{random.choice(['渋谷区', '新宿区', '港区', '千代田区'])}{random.randint(1, 50)}-{random.randint(1, 10)}"
            })
        return customers
    
    @staticmethod
    def generate_products(count: int = 50) -> List[Dict]:
        """ダミー商品データ生成"""
        categories = ["電子機器", "衣料品", "食品", "書籍", "家具"]
        products = []
        
        for i in range(count):
            category = random.choice(categories)
            products.append({
                'id': i + 1,
                'name': f"{category}{i+1}",
                'category': category,
                'price': random.randint(100, 50000),
                'stock': random.randint(0, 100)
            })
        return products
    
    @staticmethod
    def generate_sales(count: int = 200) -> List[Dict]:
        """ダミー売上データ生成"""
        customers = DummyDataGenerator.generate_customers(20)
        products = DummyDataGenerator.generate_products(30)
        
        sales = []
        for i in range(count):
            customer = random.choice(customers)
            product = random.choice(products)
            quantity = random.randint(1, 10)
            
            sales.append({
                'id': i + 1,
                'customer_id': customer['id'],
                'customer_name': customer['name'],
                'product_id': product['id'],
                'product_name': product['name'],
                'quantity': quantity,
                'unit_price': product['price'],
                'total_price': quantity * product['price'],
                'date': datetime.now().strftime("%Y-%m-%d"),
                'created_at': datetime.now().isoformat()
            })
        return sales

class NavigationHistory:
    """ナビゲーション履歴管理"""
    
    def __init__(self):
        self.history: List[Dict] = []
        self.max_history = 10
    
    def add_to_history(self, page_name: str, page_data: Dict = None):
        """履歴に追加"""
        history_item = {
            'page': page_name,
            'data': page_data,
            'timestamp': datetime.now().isoformat()
        }
        
        # 重複を避ける
        self.history = [item for item in self.history if item['page'] != page_name]
        self.history.insert(0, history_item)
        
        # 履歴数を制限
        if len(self.history) > self.max_history:
            self.history = self.history[:self.max_history]
    
    def get_last_page(self) -> Optional[Dict]:
        """最後のページを取得"""
        return self.history[0] if self.history else None
    
    def get_history(self) -> List[Dict]:
        """履歴を取得"""
        return self.history

class SafePageManager:
    """安全なページマネージャー"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        self.current_page = None
        self.navigation_history = NavigationHistory()
        ErrorHandler.current_page = page  # グローバル参照用
    
    def safe_navigate(self, page_name: str, page_builder):
        """安全なページ遷移"""
        try:
            # 現在のページ情報を保存
            current_data = {}
            if self.current_page:
                current_data = self._get_page_data()
            
            self.navigation_history.add_to_history(page_name, current_data)
            
            # 新しいページを構築
            page_instance = page_builder(self)
            new_page = page_instance.build()
            
            # 安全なページ切り替え
            self._safe_page_transition(new_page, page_name)
            
        except Exception as e:
            ErrorHandler.handle_error(e, f"ページ遷移エラー ({page_name})")
    
    def _get_page_data(self) -> Dict:
        """現在のページデータを取得"""
        try:
            if hasattr(self.current_page, 'get_data'):
                return self.current_page.get_data()
            return {}
        except:
            return {}
    
    def _safe_page_transition(self, new_page, page_name: str):
        """安全なページ切り替え"""
        try:
            # 古いコンテンツをクリア
            self.page.controls.clear()
            
            # 新しいコンテンツを追加
            self.page.add(new_page)
            
            # 現在のページを更新
            self.current_page = new_page
            
            # ページを更新
            self.page.update()
            
            logging.info(f"ページ遷移成功: {page_name}")
            
        except Exception as e:
            ErrorHandler.handle_error(e, f"ページ表示エラー ({page_name})")
    
    def go_back(self):
        """前のページに戻る"""
        try:
            history = self.navigation_history.get_history()
            if len(history) > 1:
                # 前のページに戻る
                previous_page = history[1]
                
                # ページビルダーを呼び出し
                if previous_page['page'] == 'dashboard':
                    self.safe_navigate('dashboard', DashboardPage)
                elif previous_page['page'] == 'sales':
                    self.safe_navigate('sales', SalesPage)
                elif previous_page['page'] == 'customers':
                    self.safe_navigate('customers', CustomerPage)
                elif previous_page['page'] == 'products':
                    self.safe_navigate('products', ProductPage)
                
                # 履歴を更新
                self.navigation_history.history.pop(0)  # 現在の履歴を削除
                
        except Exception as e:
            ErrorHandler.handle_error(e, "戻る処理エラー")

class DashboardPage:
    """ダッシュボードページ"""
    
    def __init__(self, page_manager):
        self.page_manager = page_manager
    
    def build(self):
        """ダッシュボードUI構築"""
        try:
            # 統計データ取得
            stats = self._get_statistics()
            
            return ft.Container(
                content=ft.Column([
                    ft.Text("ダッシュボード", size=24, weight=ft.FontWeight.BOLD),
                    ft.Divider(),
                    ft.Row([
                        self._stat_card("総顧客数", stats['customers'], ft.Colors.BLUE),
                        self._stat_card("総商品数", stats['products'], ft.Colors.GREEN),
                    ], spacing=10),
                    ft.Row([
                        self._stat_card("総売上件数", stats['sales'], ft.Colors.ORANGE),
                        self._stat_card("総売上高", f"¥{stats['total_sales']:,.0f}", ft.Colors.PURPLE),
                    ], spacing=10),
                ]),
                padding=20
            )
        except Exception as e:
            ErrorHandler.handle_error(e, "ダッシュボード構築エラー")
            return ft.Text("ダッシュボード読み込みエラー")
    
    def _stat_card(self, title: str, value: str, color: ft.Colors):
        """統計カード作成"""
        return ft.Card(
            content=ft.Container(
                content=ft.Column([
                    ft.Text(title, size=16, color=color),
                    ft.Text(value, size=20, weight=ft.FontWeight.BOLD),
                ]),
                padding=15
            ),
            width=200
        )
    
    def _get_statistics(self) -> Dict:
        """統計データ取得"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            # 各テーブルの件数取得
            cursor.execute("SELECT COUNT(*) FROM customers")
            customers = cursor.fetchone()[0]
            
            cursor.execute("SELECT COUNT(*) FROM products")
            products = cursor.fetchone()[0]
            
            cursor.execute("SELECT COUNT(*), COALESCE(SUM(total_price), 0) FROM sales")
            sales_result = cursor.fetchone()
            sales_count = sales_result[0]
            total_sales = sales_result[1]
            
            conn.close()
            
            return {
                'customers': customers,
                'products': products,
                'sales': sales_count,
                'total_sales': total_sales
            }
        except Exception as e:
            ErrorHandler.handle_error(e, "統計データ取得エラー")
            return {'customers': 0, 'products': 0, 'sales': 0, 'total_sales': 0}
    
    def get_data(self) -> Dict:
        """ページデータ取得"""
        return {'page': 'dashboard'}

class SalesPage:
    """売上管理ページ"""
    
    def __init__(self, page_manager):
        self.page_manager = page_manager
    
    def build(self):
        """売上管理UI構築"""
        try:
            return ft.Container(
                content=ft.Column([
                    ft.Text("売上管理", size=24, weight=ft.FontWeight.BOLD),
                    ft.Divider(),
                    ft.Row([
                        ft.TextField(label="顧客名", width=200),
                        ft.TextField(label="商品名", width=200),
                        ft.TextField(label="金額", width=150),
                        ft.Button("追加", bgcolor=ft.Colors.BLUE, color=ft.Colors.WHITE),
                    ]),
                    ft.Divider(),
                    ft.Text("売上一覧", size=18),
                    ft.Container(
                        content=ft.Column([], scroll=ft.ScrollMode.AUTO),
                        height=300
                    )
                ]),
                padding=20
            )
        except Exception as e:
            ErrorHandler.handle_error(e, "売上管理ページ構築エラー")
            return ft.Text("売上管理ページ読み込みエラー")
    
    def get_data(self) -> Dict:
        """ページデータ取得"""
        return {'page': 'sales'}

class CustomerPage:
    """顧客管理ページ"""
    
    def __init__(self, page_manager):
        self.page_manager = page_manager
    
    def build(self):
        """顧客管理UI構築"""
        try:
            return ft.Container(
                content=ft.Column([
                    ft.Text("顧客管理", size=24, weight=ft.FontWeight.BOLD),
                    ft.Divider(),
                    ft.Row([
                        ft.Button("新規追加", bgcolor=ft.Colors.GREEN, color=ft.Colors.WHITE),
                        ft.Button("一括インポート", bgcolor=ft.Colors.BLUE, color=ft.Colors.WHITE),
                    ]),
                    ft.Divider(),
                    ft.Text("顧客一覧", size=18),
                    ft.Container(
                        content=ft.Column([], scroll=ft.ScrollMode.AUTO),
                        height=300
                    )
                ]),
                padding=20
            )
        except Exception as e:
            ErrorHandler.handle_error(e, "顧客管理ページ構築エラー")
            return ft.Text("顧客管理ページ読み込みエラー")
    
    def get_data(self) -> Dict:
        """ページデータ取得"""
        return {'page': 'customers'}

class ProductPage:
    """商品管理ページ"""
    
    def __init__(self, page_manager):
        self.page_manager = page_manager
    
    def build(self):
        """商品管理UI構築"""
        try:
            return ft.Container(
                content=ft.Column([
                    ft.Text("商品管理", size=24, weight=ft.FontWeight.BOLD),
                    ft.Divider(),
                    ft.Row([
                        ft.Button("新規追加", bgcolor=ft.Colors.GREEN, color=ft.Colors.WHITE),
                        ft.Button("一括インポート", bgcolor=ft.Colors.BLUE, color=ft.Colors.WHITE),
                    ]),
                    ft.Divider(),
                    ft.Text("商品一覧", size=18),
                    ft.Container(
                        content=ft.Column([], scroll=ft.ScrollMode.AUTO),
                        height=300
                    )
                ]),
                padding=20
            )
        except Exception as e:
            ErrorHandler.handle_error(e, "商品管理ページ構築エラー")
            return ft.Text("商品管理ページ読み込みエラー")
    
    def get_data(self) -> Dict:
        """ページデータ取得"""
        return {'page': 'products'}

class SalesAssistantApp:
    """メインアプリケーション"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        self.page_manager = SafePageManager(page)
        
        # ログ設定
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('app.log'),
                logging.StreamHandler()
            ]
        )
        
        # シグナルハンドラ設定
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)
        
        # データベース初期化
        self._init_database()
        self._generate_dummy_data()
        
        # ナビゲーションバー構築
        self._build_navigation()
        
        # 初期ページ表示
        self.page_manager.safe_navigate('dashboard', DashboardPage)
    
    def _signal_handler(self, signum, frame):
        """シグナルハンドラ"""
        print(f"\nシグナル {signum} を受信しました")
        self._cleanup_resources()
        sys.exit(0)
    
    def _cleanup_resources(self):
        """リソースクリーンアップ"""
        try:
            logging.info("アプリケーション終了処理開始")
            print("✅ 正常終了処理完了")
            logging.info("アプリケーション正常終了")
        except Exception as e:
            logging.error(f"クリーンアップエラー: {e}")
            print(f"❌ クリーンアップエラー: {e}")
    
    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
                )
            ''')
            
            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
                )
            ''')
            
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS sales (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    customer_id INTEGER,
                    customer_name TEXT NOT NULL,
                    product_id INTEGER,
                    product_name TEXT NOT NULL,
                    quantity INTEGER NOT NULL,
                    unit_price REAL NOT NULL,
                    total_price REAL NOT NULL,
                    date TEXT NOT NULL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    FOREIGN KEY (customer_id) REFERENCES customers(id),
                    FOREIGN KEY (product_id) REFERENCES products(id)
                )
            ''')
            
            conn.commit()
            conn.close()
            logging.info("データベース初期化完了")
            
        except Exception as e:
            ErrorHandler.handle_error(e, "データベース初期化エラー")
    
    def _generate_dummy_data(self):
        """ダミーデータ生成"""
        try:
            conn = sqlite3.connect('sales.db')
            cursor = conn.cursor()
            
            # 既存データチェック
            cursor.execute("SELECT COUNT(*) FROM customers")
            if cursor.fetchone()[0] == 0:
                print("📊 ダミーデータを生成中...")
                
                # 顧客データ
                customers = DummyDataGenerator.generate_customers(50)
                for customer in customers:
                    cursor.execute('''
                        INSERT INTO customers (name, phone, email, address)
                        VALUES (?, ?, ?, ?)
                    ''', (customer['name'], customer['phone'], customer['email'], customer['address']))
                
                # 商品データ
                products = DummyDataGenerator.generate_products(30)
                for product in products:
                    cursor.execute('''
                        INSERT INTO products (name, category, price, stock)
                        VALUES (?, ?, ?, ?)
                    ''', (product['name'], product['category'], product['price'], product['stock']))
                
                # 売上データ
                sales = DummyDataGenerator.generate_sales(100)
                for sale in sales:
                    cursor.execute('''
                        INSERT INTO sales (customer_id, customer_name, product_id, product_name, quantity, unit_price, total_price, date)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
                    ''', (sale['customer_id'], sale['customer_name'], sale['product_id'], 
                           sale['product_name'], sale['quantity'], sale['unit_price'], 
                           sale['total_price'], sale['date']))
                
                conn.commit()
                print("✅ ダミーデータ生成完了")
            
            conn.close()
            
        except Exception as e:
            ErrorHandler.handle_error(e, "ダミーデータ生成エラー")
    
    def _build_navigation(self):
        """ナビゲーションバー構築"""
        try:
            # ナビゲーションボタン
            nav_buttons = [
                ft.ElevatedButton(
                    "ダッシュボード",
                    on_click=lambda _: self.page_manager.safe_navigate('dashboard', DashboardPage),
                    bgcolor=ft.Colors.BLUE,
                    color=ft.Colors.WHITE
                ),
                ft.ElevatedButton(
                    "売上管理",
                    on_click=lambda _: self.page_manager.safe_navigate('sales', SalesPage),
                    bgcolor=ft.Colors.GREEN,
                    color=ft.Colors.WHITE
                ),
                ft.ElevatedButton(
                    "顧客管理",
                    on_click=lambda _: self.page_manager.safe_navigate('customers', CustomerPage),
                    bgcolor=ft.Colors.ORANGE,
                    color=ft.Colors.WHITE
                ),
                ft.ElevatedButton(
                    "商品管理",
                    on_click=lambda _: self.page_manager.safe_navigate('products', ProductPage),
                    bgcolor=ft.Colors.PURPLE,
                    color=ft.Colors.WHITE
                ),
                ft.ElevatedButton(
                    "戻る",
                    on_click=lambda _: self.page_manager.go_back(),
                    bgcolor=ft.Colors.RED,
                    color=ft.Colors.WHITE
                )
            ]
            
            # ナビゲーションバー
            self.page.navigation_bar = ft.NavigationBar(
                destinations=[
                    ft.NavigationBarDestination(
                        icon=ft.Icons.DASHBOARD,
                        label="ダッシュボード"
                    ),
                    ft.NavigationBarDestination(
                        icon=ft.Icons.SHOPPING_CART,
                        label="売上"
                    ),
                    ft.NavigationBarDestination(
                        icon=ft.Icons.PEOPLE,
                        label="顧客"
                    ),
                    ft.NavigationBarDestination(
                        icon=ft.Icons.INVENTORY,
                        label="商品"
                    )
                ],
                on_change=self._on_nav_change
            )
            
            # 代替ナビゲーション（NavigationBarが動かない場合）
            self.page.add(
                ft.Container(
                    content=ft.Row([
                        ft.Button(
                            "ダッシュボード",
                            on_click=lambda _: self.page_manager.safe_navigate('dashboard', DashboardPage),
                            bgcolor=ft.Colors.BLUE,
                            color=ft.Colors.WHITE
                        ),
                        ft.Button(
                            "売上管理",
                            on_click=lambda _: self.page_manager.safe_navigate('sales', SalesPage),
                            bgcolor=ft.Colors.GREEN,
                            color=ft.Colors.WHITE
                        ),
                        ft.Button(
                            "顧客管理",
                            on_click=lambda _: self.page_manager.safe_navigate('customers', CustomerPage),
                            bgcolor=ft.Colors.ORANGE,
                            color=ft.Colors.WHITE
                        ),
                        ft.Button(
                            "商品管理",
                            on_click=lambda _: self.page_manager.safe_navigate('products', ProductPage),
                            bgcolor=ft.Colors.PURPLE,
                            color=ft.Colors.WHITE
                        ),
                        ft.Button(
                            "戻る",
                            on_click=lambda _: self.page_manager.go_back(),
                            bgcolor=ft.Colors.RED,
                            color=ft.Colors.WHITE
                        )
                    ], spacing=5),
                    padding=10,
                    bgcolor=ft.Colors.GREY_100
                )
            )
            
        except Exception as e:
            ErrorHandler.handle_error(e, "ナビゲーション構築エラー")
    
    def _on_nav_change(self, e):
        """ナビゲーション変更イベント"""
        try:
            index = e.control.selected_index
            pages = [DashboardPage, SalesPage, CustomerPage, ProductPage]
            page_names = ['dashboard', 'sales', 'customers', 'products']
            
            if 0 <= index < len(pages):
                self.page_manager.safe_navigate(page_names[index], pages[index])
        except Exception as ex:
            ErrorHandler.handle_error(ex, "ナビゲーション変更エラー")

def main(page: ft.Page):
    """メイン関数"""
    try:
        # ウィンドウ設定
        page.title = "販売アシスト1号"
        page.window_width = 800
        page.window_height = 600
        page.theme_mode = ft.ThemeMode.LIGHT
        
        # ウィンドウクローズイベント
        page.on_window_close = lambda _: SalesAssistantApp(page)._cleanup_resources()
        
        # アプリケーション起動
        app = SalesAssistantApp(page)
        logging.info("アプリケーション起動完了")
        print("🚀 頑健な販売アシスト1号起動完了")
        
    except Exception as e:
        ErrorHandler.handle_error(e, "アプリケーション起動エラー")

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