"""
インタラクティブ伝票ビューア
Flutter参考プロジェクトの構造を適用
"""

import flet as ft
import sqlite3
import signal
import sys
import logging
from datetime import datetime
from components.pinch_handler import PinchHandler
from models.invoice_models import DocumentType, Invoice, create_sample_invoices

# カラーテーマ定義
DARK_THEME = {
    'background': ft.Colors.GREY_900,
    'card_bg': ft.Colors.GREY_800,
    'text_primary': ft.Colors.WHITE,
    'text_secondary': ft.Colors.GREY_300,
    'accent': ft.Colors.BLUE_400
}

LIGHT_THEME = {
    'background': ft.Colors.BLUE_50,
    'card_bg': ft.Colors.WHITE,
    'text_primary': ft.Colors.BLACK,
    'text_secondary': ft.Colors.GREY_700,
    'accent': ft.Colors.BLUE_600
}

class InteractiveSlipViewer:
    def __init__(self, page: ft.Page):
        self.page = page
        
        # 状態管理を先に初期化
        self.slip_data = []
        self.test_mode = False  # テストモード
        self.test_logs = []  # 操作ログ
        self.is_dark_theme = False  # テーマ設定
        
        # ページ設定
        self.setup_page()
        
        # データベース設定
        self.setup_database()
        
        # ピンチハンドラー初期化
        self.pinch_handler = PinchHandler(page)
        self.pinch_handler.set_callbacks(
            on_zoom_change=self.on_zoom_change,
            on_tap=self.on_slip_tap,
            on_double_tap=self.on_slip_double_tap,
            on_long_press=self.on_slip_long_press
        )
        
        # UI初期化
        self.setup_ui()
        
    def setup_page(self):
        self.page.title = "インタラクティブ伝票ビューア"
        self.page.window.width = 420
        self.page.window.height = 900
        self.page.window.resizable = False
        self.page.window_center = True
        
        # キーボードイベントハンドラー
        self.page.on_keyboard_event = self.on_keyboard_event
        
    def setup_database(self):
        try:
            self.conn = sqlite3.connect('sales_assist.db')
            self.cursor = self.conn.cursor()
            
            # 伝票テーブル作成
            self.cursor.execute('''
                CREATE TABLE IF NOT EXISTS slips (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    slip_type TEXT,
                    customer_name TEXT,
                    amount REAL,
                    date TEXT,
                    status TEXT,
                    description TEXT,
                    created_at TEXT DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # サンプルデータ
            self.create_sample_data()
            
        except Exception as e:
            logging.error(f"DBエラー: {e}")
            self.conn = None
    
    def create_sample_data(self):
        """サンプル伝票データ作成"""
        try:
            # Flutterモデルからサンプルデータを生成
            sample_invoices = create_sample_invoices()
            
            for invoice in sample_invoices:
                self.cursor.execute('''
                    INSERT OR REPLACE INTO slips 
                    (slip_type, customer_name, amount, date, status, description)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', (
                    invoice.document_type.value,
                    invoice.customer.formal_name,
                    invoice.total_amount,
                    invoice.date.strftime('%Y-%m-%d'),
                    '完了',
                    invoice.notes
                ))
            
            self.conn.commit()
        except Exception as e:
            logging.error(f"サンプルデータ作成エラー: {e}")
    
    def setup_ui(self):
        # テーマ設定
        theme = DARK_THEME if self.is_dark_theme else LIGHT_THEME
        
        # ヘッダー
        header = ft.Container(
            content=ft.Row([
                ft.Text("📋 インタラクティブ伝票", size=18, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.Container(expand=True),
                ft.IconButton(ft.Icons.SEARCH, icon_size=16, icon_color=theme['text_primary']),
                ft.Button(
                    "テスト", 
                    bgcolor=theme['accent'], 
                    color=theme['text_primary'],
                    on_click=self.toggle_test_mode
                )
            ]),
            padding=15,
            bgcolor=theme['accent'],
            border_radius=15,
            margin=ft.Margin.only(bottom=10)
        )
        
        # 伝票グリッド
        self.slip_grid = ft.GridView(
            runs_count=2,
            spacing=10,
            run_spacing=10,
            child_aspect_ratio=1.2,
            padding=ft.Padding.symmetric(horizontal=15, vertical=10)
        )
        
        # 詳細パネル
        self.detail_panel = ft.Container(
            content=ft.Text("詳細パネル"),
            visible=False,
            padding=15,
            bgcolor=theme['card_bg'],
            border_radius=10,
            shadow=ft.BoxShadow(
                spread_radius=1,
                blur_radius=5,
                color=ft.Colors.with_opacity(0.2, ft.Colors.BLACK),
                offset=ft.Offset(0, 2)
            )
        )
        
        # テストモードパネル
        self.test_panel = ft.Container(
            content=ft.Column([
                ft.Text("🧪 テストモード", size=14, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.Divider(height=1),
                ft.Text("キーボード操作:", size=12, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.Text("+ : ズームイン", size=10, color=theme['text_secondary']),
                ft.Text("- : ズームアウト", size=10, color=theme['text_secondary']),
                ft.Text("R : ズームリセット", size=10, color=theme['text_secondary']),
                ft.Text(f"現在のズーム: {int(self.pinch_handler.zoom_level * 100)}%", size=10, color=theme['text_primary']),
                ft.Text("操作履歴:", size=12, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.Column([], spacing=2)
            ], spacing=5),
            visible=False,
            padding=10,
            bgcolor=theme['card_bg'],
            border_radius=10,
            margin=ft.Margin.only(bottom=10)
        )
        
        # メインコンテナ
        main_container = ft.Column([
            self.slip_grid,
            self.test_panel,
            self.detail_panel
        ], scroll=ft.ScrollMode.AUTO)
        
        # ページに追加
        self.page.add(
            ft.Column([
                header,
                ft.Container(
                    content=main_container,
                    expand=True,
                    bgcolor=theme['background']
                )
            ])
        )
        
        # 初期データ読み込み
        self.load_slips()
    
    def load_slips(self):
        """伝票データ読み込み"""
        if not self.conn:
            logging.error("データベース接続がありません")
            return
        
        try:
            self.cursor.execute("SELECT * FROM slips ORDER BY date DESC")
            rows = self.cursor.fetchall()
            
            # タプルからInvoiceオブジェクトに変換
            self.slip_data = []
            for row in rows:
                # 簡単なInvoiceオブジェクトを作成（復元用）
                from models.invoice_models import Customer, InvoiceItem, DocumentType
                customer = Customer(1, row[2], row[2])  # id, name, formal_name
                items = [InvoiceItem("サンプル明細", 1, int(row[3]))]  # description, quantity, unit_price
                
                # DocumentTypeの文字列からEnumに変換
                doc_type_str = row[1]
                doc_type = next((dt for dt in DocumentType if dt.value == doc_type_str), DocumentType.INVOICE)
                
                invoice = Invoice(
                    customer=customer,
                    date=datetime.strptime(row[4], '%Y-%m-%d'),
                    items=items,
                    document_type=doc_type
                )
                self.slip_data.append(invoice)
            
            self.update_slip_grid()
        except Exception as e:
            logging.error(f"伝票読み込みエラー: {e}")
            self.slip_data = []
    
    def update_slip_grid(self):
        """伝票グリッド更新"""
        self.slip_grid.controls.clear()
        
        for slip in self.slip_data:
            slip_card = self.create_slip_card(slip)
            self.slip_grid.controls.append(slip_card)
        
        self.page.update()
    
    def create_slip_card(self, invoice: Invoice) -> ft.Container:
        """伝票カード作成"""
        # テーマ取得
        theme = DARK_THEME if self.is_dark_theme else LIGHT_THEME
        
        # ドキュメントタイプに応じたアイコンと色
        type_config = {
            DocumentType.SALES: {"icon": "💰", "color": ft.Colors.GREEN},
            DocumentType.ESTIMATE: {"icon": "📄", "color": ft.Colors.BLUE},
            DocumentType.DELIVERY: {"icon": "📦", "color": ft.Colors.PURPLE},
            DocumentType.INVOICE: {"icon": "📋", "color": ft.Colors.ORANGE},
            DocumentType.RECEIPT: {"icon": "🧾", "color": ft.Colors.RED}
        }
        
        config = type_config.get(invoice.document_type, {"icon": "📝", "color": ft.Colors.GREY})
        
        # 通常のカード作成
        card = ft.Container(
            content=ft.Column([
                ft.Container(
                    content=ft.Text(config["icon"], size=24),
                    width=40,
                    height=40,
                    bgcolor=config["color"],
                    border_radius=20,
                    alignment=ft.alignment.Alignment(0, 0)
                ),
                ft.Text(invoice.document_type.value, size=12, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.Text(f"{invoice.customer.formal_name} ¥{invoice.total_amount:,}", size=10, color=theme['text_secondary']),
            ], spacing=5, horizontal_alignment=ft.CrossAxisAlignment.CENTER),
            padding=10,
            bgcolor=theme['card_bg'],
            border_radius=10,
            shadow=ft.BoxShadow(
                spread_radius=1,
                blur_radius=5,
                color=ft.Colors.with_opacity(0.2, ft.Colors.BLACK),
                offset=ft.Offset(0, 2)
            )
        )
        
        return ft.GestureDetector(
            content=card,
            on_tap=lambda _: self.on_slip_tap(invoice)
        )
    
    def on_zoom_change(self, zoom_level: float):
        """ズームレベル変更時"""
        # ズーム機能は一時的に無効化
        pass
    
    def on_slip_tap(self, invoice: Invoice):
        """伝票タップ"""
        self.show_slip_detail(invoice)
    
    def on_slip_double_tap(self, invoice: Invoice):
        """伝票ダブルタップ"""
        self.show_slip_detail(invoice)
    
    def on_slip_long_press(self, invoice: Invoice):
        """伝票ロングプレス"""
        self.show_slip_detail(invoice)
    
    def show_slip_detail(self, invoice: Invoice):
        """伝票詳細表示"""
        # テーマ取得
        theme = DARK_THEME if self.is_dark_theme else LIGHT_THEME
        
        self.detail_panel.content = ft.Column([
            ft.Row([
                ft.Text("伝票詳細", size=16, weight=ft.FontWeight.BOLD, color=theme['text_primary']),
                ft.IconButton(ft.Icons.CLOSE, on_click=self.hide_detail, icon_color=theme['text_primary'])
            ]),
            ft.Divider(),
            ft.Text(f"種類: {invoice.document_type.value}", size=14, color=theme['text_primary']),
            ft.Text(f"顧客: {invoice.customer.formal_name}", size=14, color=theme['text_primary']),
            ft.Text(f"金額: ¥{invoice.total_amount:,}", size=14, color=theme['text_primary']),
            ft.Text(f"日付: {invoice.date.strftime('%Y/%m/%d')}", size=14, color=theme['text_primary']),
            ft.Text(f"請求書番号: {invoice.invoice_number}", size=14, color=theme['text_primary']),
            ft.Text(f"説明: {invoice.notes or 'なし'}", size=12, color=theme['text_secondary']),
            ft.Row([
                ft.Button("編集", bgcolor=theme['accent'], color=theme['text_primary']),
                ft.Button("削除", bgcolor=ft.Colors.RED, color=theme['text_primary']),
            ], spacing=10)
        ], spacing=10)
        
        self.detail_panel.visible = True
        self.page.update()
    
    def on_keyboard_event(self, e: ft.KeyboardEvent):
        """キーボードイベント処理"""
        if self.test_mode:
            if e.key == "+":
                self.pinch_handler.zoom_in()
                self.add_test_log("キーボード: + (ズームイン)")
            elif e.key == "-":
                self.pinch_handler.zoom_out()
                self.add_test_log("キーボード: - (ズームアウト)")
            elif e.key == "r":
                self.pinch_handler.reset_zoom()
                self.add_test_log("キーボード: R (ズームリセット)")
            elif e.key == " ":  # Spaceキー
                self.add_test_log("キーボード: Space (ダブルタップ代替)")
            elif e.key == "t":  # Tキー
                self.toggle_test_mode()
    
    def on_mouse_event(self, e):
        """マウスイベント処理"""
        if self.test_mode:
            if hasattr(e, 'button'):
                if e.button == "right":
                    self.pinch_handler.zoom_in()
                    self.add_test_log(f"マウス: 右クリック (ズームイン)")
                elif e.button == "middle":
                    self.pinch_handler.zoom_out()
                    self.add_test_log(f"マウス: 中クリック (ズームアウト)")
    
    def toggle_test_mode(self):
        """テストモード切替"""
        self.test_mode = not self.test_mode
        self.test_panel.visible = self.test_mode
        self.page.update()
    
    def add_test_log(self, message: str):
        """テストログ追加"""
        if hasattr(self, 'test_logs'):
            self.test_logs.append(message)
        else:
            self.test_logs = [message]
        
        # ログ表示更新
        if len(self.test_logs) > 10:  # 最新10件のみ表示
            self.test_logs = self.test_logs[-10:]
        
        # テーマ取得
        theme = DARK_THEME if self.is_dark_theme else LIGHT_THEME
        
        log_container = ft.Column([
            ft.Text(log, size=8, color=theme['text_secondary'])
            for log in self.test_logs
        ])
        
        self.test_panel.content.controls[-1].controls = [log_container]
        self.page.update()
    
    def hide_detail(self, e=None):
        """詳細パネル非表示"""
        self.detail_panel.visible = False
        self.page.update()

def main(page: ft.Page):
    try:
        viewer = InteractiveSlipViewer(page)
        logging.info("インタラクティブ伝票ビューア起動")
    except Exception as e:
        logging.error(f"起動エラー: {e}")

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