"""
伝票エクスプローラー
伝票の検索・閲覧・管理を直感的に行う
土地勘を持たせるための視覚的ナビゲーション
"""

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

# ロギング設定
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

class SlipExplorer:
    """伝票エクスプローラー"""
    
    def __init__(self, page: ft.Page):
        self.page = page
        self.setup_page()
        self.setup_database()
        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.theme_mode = ft.ThemeMode.LIGHT
        
        # シグナルハンドラ
        def signal_handler(signum, frame):
            logging.info("伝票エクスプローラー正常終了")
            sys.exit(0)
        
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
        
    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()
            
            logging.info("伝票データベース接続完了")
            
        except Exception as e:
            logging.error(f"データベースエラー: {e}")
            self.conn = None
    
    def create_sample_data(self):
        """サンプルデータ作成"""
        try:
            # サンプル伝票データ
            sample_slips = [
                ("売上伝票", "田中商事", 50000, "2026-02-19", "発行済", "A商品100個"),
                ("見積書", "鈴木商店", 75000, "2026-02-18", "下書き", "B商品50個"),
                ("納品書", "伊藤工業", 120000, "2026-02-17", "発行済", "C製品20台"),
                ("請求書", "高橋建設", 200000, "2026-02-16", "入金済", "工事代金"),
                ("領収書", "渡辺商事", 80000, "2026-02-15", "発行済", "D商品40個"),
            ]
            
            for slip in sample_slips:
                self.cursor.execute('''
                    INSERT OR IGNORE INTO slips 
                    (slip_type, customer_name, amount, date, status, description)
                    VALUES (?, ?, ?, ?, ?, ?)
                ''', slip)
            
            self.conn.commit()
            
        except Exception as e:
            logging.error(f"サンプルデータ作成エラー: {e}")
    
    def setup_ui(self):
        """UI構築"""
        # ヘッダー
        header = ft.Container(
            content=ft.Column([
                ft.Text(
                    "📋 伝票エクスプローラー",
                    size=20,
                    weight=ft.FontWeight.BOLD,
                    color=ft.Colors.WHITE,
                    text_align=ft.TextAlign.CENTER
                ),
                ft.Text(
                    "伝票の検索・閲覧・管理",
                    size=14,
                    color=ft.Colors.WHITE,
                    text_align=ft.TextAlign.CENTER
                )
            ], spacing=5),
            padding=15,
            bgcolor=ft.Colors.BLUE_600,
            border_radius=15,
            margin=ft.Margin.only(bottom=15)
        )
        
        # 検索バー
        search_bar = ft.Container(
            content=ft.Row([
                ft.TextField(
                    hint_text="伝票を検索...",
                    prefix_icon=ft.Icons.SEARCH,
                    filled=True,
                    dense=True,
                    expand=True,
                    on_change=self.on_search_change
                ),
                ft.IconButton(ft.Icons.FILTER_LIST, tooltip="フィルター", icon_size=20),
            ], spacing=5),
            padding=ft.Padding.symmetric(horizontal=15, vertical=5),
            margin=ft.Margin.only(bottom=15)
        )
        
        # フィルターパネル
        filter_panel = ft.Container(
            content=ft.Column([
                ft.Text("🔍 フィルター", size=14, weight=ft.FontWeight.BOLD),
                ft.Divider(height=1),
                
                # 顧客フィルター（チェックボックス）
                ft.Text("顧客", size=12, weight=ft.FontWeight.BOLD),
                ft.Column([
                    self.create_checkbox_filter("田中商事", "customer"),
                    self.create_checkbox_filter("鈴木商店", "customer"),
                    self.create_checkbox_filter("伊藤工業", "customer"),
                    self.create_checkbox_filter("高橋建設", "customer"),
                ], spacing=5),
                
                # 期間フィルター（ラジオボタン）
                ft.Text("期間", size=12, weight=ft.FontWeight.BOLD),
                ft.Column([
                    self.create_radio_filter("今日", "period", True),
                    self.create_radio_filter("今週", "period"),
                    self.create_radio_filter("今月", "period"),
                    self.create_radio_filter("全期間", "period"),
                ], spacing=5),
                
                # 金額帯フィルター（チェックボックス）
                ft.Text("金額帯", size=12, weight=ft.FontWeight.BOLD),
                ft.Column([
                    self.create_checkbox_filter("0-1万円", "amount_0_1"),
                    self.create_checkbox_filter("1-5万円", "amount_1_5"),
                    self.create_checkbox_filter("5万円以上", "amount_5_plus"),
                ], spacing=5),
                
            ], spacing=10),
            padding=15,
            bgcolor=ft.Colors.WHITE,
            border_radius=10,
            margin=ft.Margin.only(bottom=15)
        )
        
        # 伝票一覧
        self.slip_list = ft.Column([], spacing=8, scroll=ft.ScrollMode.AUTO)
        
        # 統計情報
        stats_container = ft.Container(
            content=self.get_stats_info(),
            padding=15,
            bgcolor=ft.Colors.BLUE_50,
            border_radius=10,
            margin=ft.Margin.only(bottom=15)
        )
        
        # メインコンテナ
        self.main_container = ft.Column([
            header,
            search_bar,
            filter_panel,
            stats_container,
            ft.Container(
                content=self.slip_list,
                expand=True,
                padding=ft.Padding.symmetric(horizontal=15)
            )
        ], spacing=5)
        
        # ページに追加
        self.page.add(
            ft.Container(
                content=self.main_container,
                padding=10,
                bgcolor=ft.Colors.GREY_50,
                expand=True
            )
        )
        
        # 初期データ読み込み
        self.load_slips()
    
    def create_checkbox_filter(self, label: str, filter_type: str) -> ft.Row:
        """チェックボックスフィルター作成"""
        checkbox = ft.Checkbox(label=label, value=False, on_change=lambda e: self.apply_filters())
        return ft.Row([checkbox], spacing=0)
    
    def create_radio_filter(self, label: str, filter_type: str, is_default: bool = False) -> ft.Row:
        """ラジオボタンフィルター作成"""
        radio = ft.Radio(
            value=label,
            label=label,
            on_change=lambda e: self.apply_filters()
        )
        return ft.Row([radio], spacing=0)
    
    def apply_filters(self):
        """フィルター適用"""
        # TODO: フィルターロジック実装
        self.load_slips()
    
    def get_stats_info(self) -> ft.Column:
        """統計情報取得"""
        if not self.conn:
            return ft.Column([
                ft.Text("データベース未接続", size=12, color=ft.Colors.RED)
            ])
        
        try:
            # 各種統計
            self.cursor.execute("SELECT COUNT(*) FROM slips")
            total_slips = self.cursor.fetchone()[0]
            
            self.cursor.execute("SELECT COUNT(*) FROM slips WHERE status = '下書き'")
            draft_slips = self.cursor.fetchone()[0]
            
            self.cursor.execute("SELECT COUNT(*) FROM slips WHERE status = '入金済'")
            paid_slips = self.cursor.fetchone()[0]
            
            self.cursor.execute("SELECT SUM(amount) FROM slips WHERE status = '入金済'")
            total_amount = self.cursor.fetchone()[0] or 0
            
            return ft.Column([
                ft.Text("📊 伝票統計", size=14, weight=ft.FontWeight.BOLD),
                ft.Row([
                    ft.Text(f"総数: {total_slips}件", size=12, expand=True),
                    ft.Text(f"下書き: {draft_slips}件", size=12, expand=True),
                ]),
                ft.Row([
                    ft.Text(f"入金済: {paid_slips}件", size=12, expand=True),
                    ft.Text(f"合計: ¥{total_amount:,.0f}", size=12, expand=True),
                ])
            ], spacing=5)
            
        except Exception as e:
            return ft.Column([
                ft.Text("統計取得エラー", size=12, color=ft.Colors.RED)
            ])
    
    def load_slips(self, filter_type: str = "all"):
        """伝票一覧読み込み"""
        if not self.conn:
            return
        
        try:
            query = "SELECT * FROM slips"
            params = []
            
            if filter_type != "all":
                query += " WHERE slip_type = ?"
                params = [filter_type]
            
            query += " ORDER BY date DESC, created_at DESC"
            
            self.cursor.execute(query, params)
            slips = self.cursor.fetchall()
            
            # 一覧をクリアして再構築
            self.slip_list.controls.clear()
            
            for slip in slips:
                slip_item = self.create_slip_item(slip)
                self.slip_list.controls.append(slip_item)
            
            self.page.update()
            
        except Exception as e:
            logging.error(f"伝票読み込みエラー: {e}")
    
    def create_slip_item(self, slip: tuple, is_highlighted: bool = False) -> ft.Container:
        """伝票アイテム作成（ハイライト対応）"""
        slip_id, slip_type, customer_name, amount, date, status, description, created_at = slip
        
        # ステータスに応じた色
        status_colors = {
            "下書き": ft.Colors.ORANGE,
            "発行済": ft.Colors.BLUE,
            "入金済": ft.Colors.GREEN,
            "キャンセル": ft.Colors.RED
        }
        
        # タイプに応じたアイコン
        type_icons = {
            "売上伝票": "💰",
            "見積書": "📄",
            "納品書": "📦",
            "請求書": "📋",
            "領収書": "🧾"
        }
        
        # ハイライト効果
        if is_highlighted:
            bgcolor = ft.Colors.BLUE_50
            border_color = ft.Colors.BLUE_600
            opacity = 1.0
            shadow = ft.BoxShadow(
                spread_radius=2,
                blur_radius=8,
                color=ft.Colors.with_opacity(0.3, ft.Colors.BLUE),
                offset=ft.Offset(0, 4)
            )
        else:
            bgcolor = ft.Colors.WHITE
            border_color = ft.Colors.GREY_200
            opacity = 0.3  # グレーアウト
            shadow = None
        
        return ft.Container(
            content=ft.Row([
                # アイコン
                ft.Container(
                    content=ft.Text(type_icons.get(slip_type, "📝"), size=24),
                    width=50,
                    height=50,
                    bgcolor=ft.Colors.BLUE_50 if is_highlighted else ft.Colors.GREY_100,
                    alignment=ft.alignment.Alignment(0, 0),
                    border_radius=10
                ),
                # メイン情報
                ft.Column([
                    ft.Text(f"{slip_type} - {customer_name}", size=14, weight=ft.FontWeight.BOLD),
                    ft.Text(f"¥{amount:,.0f} - {date}", size=12, color=ft.Colors.GREY_600),
                    ft.Text(description or "", size=10, color=ft.Colors.GREY_500)
                ], expand=True),
                # ステータス
                ft.Container(
                    content=ft.Text(status, size=10, color=ft.Colors.WHITE),
                    padding=ft.Padding.symmetric(horizontal=8, vertical=4),
                    bgcolor=status_colors.get(status, ft.Colors.GREY),
                    border_radius=10
                )
            ], spacing=10),
            padding=12,
            bgcolor=bgcolor,
            border_radius=10,
            border=ft.Border.all(2, border_color),
            opacity=opacity,
            shadow=shadow,
            on_click=lambda _: self.open_slip(slip_id)
        )
    
    def on_search_change(self, e):
        """検索変更時"""
        search_text = e.control.value.lower()
        # TODO: 検索機能実装
        pass
    
    def filter_by_type(self, type_value: str):
        """タイプでフィルター"""
        self.load_slips(type_value)
    
    def open_slip(self, slip_id: int):
        """伝票を開く"""
        self.page.snack_bar = ft.SnackBar(
            content=ft.Text(f"伝票#{slip_id}を開きます"),
            bgcolor=ft.Colors.BLUE
        )
        self.page.snack_bar.open = True
        self.page.update()
        
        # TODO: 伝票詳細画面へ遷移
        pass

def main(page: ft.Page):
    """メイン関数"""
    try:
        explorer = SlipExplorer(page)
        logging.info("伝票エクスプローラー起動完了")
        
    except Exception as e:
        logging.error(f"伝票エクスプローラー起動エラー: {e}")
        page.snack_bar = ft.SnackBar(
            content=ft.Text(f"起動エラー: {e}"),
            bgcolor=ft.Colors.RED
        )
        page.snack_bar.open = True
        page.update()

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