#!/usr/bin/env python3
"""
移行結果統計情報表示スクリプト
Docker Compose環境で実行可能
"""

import os
import sys
import psycopg2
from datetime import datetime, timedelta
import pytz
from collections import defaultdict
import json

def connect_database():
    """データベースに接続"""
    try:
        conn = psycopg2.connect(
            host=os.environ.get('DB_HOST', 'postgres-db'),
            port=os.environ.get('DB_PORT', '5432'),
            database=os.environ.get('POSTGRES_DBNAME', 'rogdb'),
            user=os.environ.get('POSTGRES_USER', 'admin'),
            password=os.environ.get('POSTGRES_PASS', 'admin123456')
        )
        return conn
    except Exception as e:
        print(f"❌ データベース接続エラー: {e}")
        return None

def get_basic_statistics(cursor):
    """基本統計情報を取得"""
    print("\n" + "="*80)
    print("📊 移行データ基本統計情報")
    print("="*80)
    
    # テーブル別レコード数
    tables = [
        ('rog_newevent2', 'イベント'),
        ('rog_team', 'チーム'),
        ('rog_member', 'メンバー'),
        ('rog_entry', 'エントリー'),
        ('rog_gpscheckin', 'GPSチェックイン'),
        ('rog_checkpoint', 'チェックポイント'),
        ('rog_location2025', 'ロケーション2025'),
        ('rog_customuser', 'ユーザー')
    ]
    
    print("\n📋 テーブル別レコード数:")
    print("テーブル名                 日本語名           レコード数")
    print("-" * 65)
    
    total_records = 0
    for table_name, japanese_name in tables:
        try:
            cursor.execute(f"SELECT COUNT(*) FROM {table_name}")
            count = cursor.fetchone()[0]
            total_records += count
            print(f"{table_name:<25} {japanese_name:<15} {count:>10,}件")
        except Exception as e:
            print(f"{table_name:<25} {japanese_name:<15} {'エラー':>10}")
    
    print("-" * 65)
    print(f"{'合計':<41} {total_records:>10,}件")

def get_event_statistics(cursor):
    """イベント別統計情報"""
    print("\n" + "="*80)
    print("🎯 イベント別統計情報")
    print("="*80)
    
    # イベント一覧と基本情報
    cursor.execute("""
        SELECT id, event_name, event_date, created_at
        FROM rog_newevent2
        ORDER BY event_date DESC
    """)
    
    events = cursor.fetchall()
    if not events:
        print("イベントデータがありません")
        return
    
    print(f"\n📅 登録イベント数: {len(events)}件")
    print("\nイベント詳細:")
    print("ID  イベント名           開催日      登録日時")
    print("-" * 60)
    
    for event in events:
        event_id, event_name, event_date, created_at = event
        event_date_str = event_date.strftime("%Y-%m-%d") if event_date else "未設定"
        created_str = created_at.strftime("%Y-%m-%d %H:%M") if created_at else "未設定"
        print(f"{event_id:>2}  {event_name:<15} {event_date_str}  {created_str}")
    
    # イベント別参加統計
    cursor.execute("""
        SELECT 
            e.event_name,
            COUNT(DISTINCT t.id) as team_count,
            COUNT(DISTINCT m.id) as member_count,
            COUNT(DISTINCT en.id) as entry_count
        FROM rog_newevent2 e
        LEFT JOIN rog_team t ON e.id = t.event_id
        LEFT JOIN rog_member m ON t.id = m.team_id
        LEFT JOIN rog_entry en ON t.id = en.team_id
        GROUP BY e.id, e.event_name
        ORDER BY team_count DESC
    """)
    
    participation_stats = cursor.fetchall()
    
    print("\n👥 イベント別参加統計:")
    print("イベント名           チーム数  メンバー数  エントリー数")
    print("-" * 55)
    
    total_teams = 0
    total_members = 0
    total_entries = 0
    
    for stat in participation_stats:
        event_name, team_count, member_count, entry_count = stat
        total_teams += team_count
        total_members += member_count
        total_entries += entry_count
        print(f"{event_name:<15} {team_count:>6}件  {member_count:>8}件  {entry_count:>9}件")
    
    print("-" * 55)
    print(f"{'合計':<15} {total_teams:>6}件  {total_members:>8}件  {total_entries:>9}件")

def get_gps_checkin_statistics(cursor):
    """GPSチェックイン統計"""
    print("\n" + "="*80)
    print("📍 GPSチェックイン統計情報")
    print("="*80)
    
    # 基本統計
    cursor.execute("""
        SELECT 
            COUNT(*) as total_checkins,
            COUNT(DISTINCT zekken) as unique_teams,
            COUNT(DISTINCT cp_number) as unique_checkpoints,
            MIN(checkin_time) as earliest_checkin,
            MAX(checkin_time) as latest_checkin
        FROM rog_gpscheckin
    """)
    
    basic_stats = cursor.fetchone()
    if not basic_stats or basic_stats[0] == 0:
        print("GPSチェックインデータがありません")
        return
    
    total_checkins, unique_teams, unique_checkpoints, earliest, latest = basic_stats
    
    print(f"\n📊 基本統計:")
    print(f"総チェックイン数: {total_checkins:,}件")
    print(f"参加チーム数: {unique_teams:,}チーム")
    print(f"利用CP数: {unique_checkpoints:,}箇所")
    
    if earliest and latest:
        print(f"最早チェックイン: {earliest.strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"最終チェックイン: {latest.strftime('%Y-%m-%d %H:%M:%S')}")
    
    # 時間帯別分析
    cursor.execute("""
        SELECT 
            EXTRACT(hour FROM checkin_time) as hour,
            COUNT(*) as count
        FROM rog_gpscheckin
        GROUP BY EXTRACT(hour FROM checkin_time)
        ORDER BY hour
    """)
    
    hourly_stats = cursor.fetchall()
    
    print(f"\n⏰ 時間帯別チェックイン分布:")
    print("時間  チェックイン数  グラフ")
    print("-" * 40)
    
    max_count = max([count for _, count in hourly_stats]) if hourly_stats else 1
    
    for hour, count in hourly_stats:
        bar_length = int((count / max_count) * 20)
        bar = "█" * bar_length
        print(f"{int(hour):>2}時  {count:>8}件  {bar}")
    
    # CP別利用統計（上位10位）
    cursor.execute("""
        SELECT 
            cp_number,
            COUNT(*) as checkin_count,
            COUNT(DISTINCT zekken) as team_count
        FROM rog_gpscheckin
        GROUP BY cp_number
        ORDER BY checkin_count DESC
        LIMIT 10
    """)
    
    cp_stats = cursor.fetchall()
    
    print(f"\n🏅 CP利用ランキング（上位10位）:")
    print("順位  CP番号  チェックイン数  利用チーム数")
    print("-" * 40)
    
    for i, (cp_number, checkin_count, team_count) in enumerate(cp_stats, 1):
        print(f"{i:>2}位  CP{cp_number:>3}  {checkin_count:>8}件  {team_count:>7}チーム")

def get_team_statistics(cursor):
    """チーム統計"""
    print("\n" + "="*80)
    print("👥 チーム統計情報")
    print("="*80)
    
    # チーム基本統計
    cursor.execute("""
        SELECT 
            COUNT(*) as total_teams,
            COUNT(DISTINCT class_name) as unique_classes,
            AVG(CASE WHEN member_count > 0 THEN member_count END) as avg_members
        FROM (
            SELECT 
                t.id,
                t.class_name,
                COUNT(m.id) as member_count
            FROM rog_team t
            LEFT JOIN rog_member m ON t.id = m.team_id
            GROUP BY t.id, t.class_name
        ) team_stats
    """)
    
    team_basic = cursor.fetchone()
    total_teams, unique_classes, avg_members = team_basic
    
    print(f"\n📊 基本統計:")
    print(f"総チーム数: {total_teams:,}チーム")
    print(f"クラス数: {unique_classes or 0}種類")
    print(f"平均メンバー数: {avg_members:.1f}人/チーム" if avg_members else "平均メンバー数: データなし")
    
    # クラス別統計
    cursor.execute("""
        SELECT 
            COALESCE(class_name, '未分類') as class_name,
            COUNT(*) as team_count,
            COUNT(CASE WHEN member_count > 0 THEN 1 END) as active_teams
        FROM (
            SELECT 
                t.class_name,
                COUNT(m.id) as member_count
            FROM rog_team t
            LEFT JOIN rog_member m ON t.id = m.team_id
            GROUP BY t.id, t.class_name
        ) team_stats
        GROUP BY class_name
        ORDER BY team_count DESC
    """)
    
    class_stats = cursor.fetchall()
    
    if class_stats:
        print(f"\n🏆 クラス別チーム数:")
        print("クラス名           チーム数  アクティブ")
        print("-" * 35)
        
        for class_name, team_count, active_teams in class_stats:
            print(f"{class_name:<15} {team_count:>6}件  {active_teams:>7}件")

def get_data_quality_check(cursor):
    """データ品質チェック"""
    print("\n" + "="*80)
    print("🔍 データ品質チェック")
    print("="*80)
    
    checks = []
    
    # 1. 重複チェック
    cursor.execute("""
        SELECT COUNT(*) FROM (
            SELECT zekken, cp_number, checkin_time, COUNT(*)
            FROM rog_gpscheckin
            GROUP BY zekken, cp_number, checkin_time
            HAVING COUNT(*) > 1
        ) duplicates
    """)
    duplicate_count = cursor.fetchone()[0]
    checks.append(("重複チェックイン", duplicate_count, "件"))
    
    # 2. 異常時刻チェック（0時台）
    cursor.execute("""
        SELECT COUNT(*) FROM rog_gpscheckin 
        WHERE EXTRACT(hour FROM checkin_time) = 0
    """)
    zero_hour_count = cursor.fetchone()[0]
    checks.append(("0時台チェックイン", zero_hour_count, "件"))
    
    # 3. 未来日時チェック
    cursor.execute("""
        SELECT COUNT(*) FROM rog_gpscheckin 
        WHERE checkin_time > NOW()
    """)
    future_count = cursor.fetchone()[0]
    checks.append(("未来日時チェックイン", future_count, "件"))
    
    # 4. メンバー不在チーム
    cursor.execute("""
        SELECT COUNT(*) FROM rog_team t
        LEFT JOIN rog_member m ON t.id = m.team_id
        WHERE m.id IS NULL
    """)
    no_member_teams = cursor.fetchone()[0]
    checks.append(("メンバー不在チーム", no_member_teams, "チーム"))
    
    # 5. エントリー不在チーム
    cursor.execute("""
        SELECT COUNT(*) FROM rog_team t
        LEFT JOIN rog_entry e ON t.id = e.team_id
        WHERE e.id IS NULL
    """)
    no_entry_teams = cursor.fetchone()[0]
    checks.append(("エントリー不在チーム", no_entry_teams, "チーム"))
    
    print("\n🧪 品質チェック結果:")
    print("チェック項目           件数      状態")
    print("-" * 40)
    
    for check_name, count, unit in checks:
        status = "✅ 正常" if count == 0 else "⚠️  要確認"
        print(f"{check_name:<15} {count:>6}{unit}  {status}")

def export_statistics_json(cursor):
    """統計情報をJSONで出力"""
    print("\n" + "="*80)
    print("📄 統計情報JSON出力")
    print("="*80)
    
    statistics = {}
    
    # 基本統計
    cursor.execute("SELECT COUNT(*) FROM rog_gpscheckin")
    statistics['total_checkins'] = cursor.fetchone()[0]
    
    cursor.execute("SELECT COUNT(DISTINCT zekken) FROM rog_gpscheckin")
    statistics['unique_teams'] = cursor.fetchone()[0]
    
    cursor.execute("SELECT COUNT(*) FROM rog_newevent2")
    statistics['total_events'] = cursor.fetchone()[0]
    
    # イベント別統計
    cursor.execute("""
        SELECT event_name, COUNT(*) as checkin_count
        FROM rog_newevent2 e
        LEFT JOIN rog_team t ON e.id = t.event_id
        LEFT JOIN rog_gpscheckin g ON t.zekken = g.zekken
        GROUP BY e.id, event_name
        ORDER BY checkin_count DESC
    """)
    
    event_stats = {}
    for event_name, count in cursor.fetchall():
        event_stats[event_name] = count
    
    statistics['event_checkins'] = event_stats
    statistics['generated_at'] = datetime.now().isoformat()
    
    # ファイル出力
    output_file = f"/app/migration_statistics_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
    
    try:
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(statistics, f, ensure_ascii=False, indent=2)
        print(f"✅ 統計情報をJSONで出力しました: {output_file}")
    except Exception as e:
        print(f"❌ JSON出力エラー: {e}")

def main():
    """メイン処理"""
    print("🚀 移行結果統計情報表示スクリプト開始")
    print(f"実行時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    
    # データベース接続
    conn = connect_database()
    if not conn:
        sys.exit(1)
    
    try:
        cursor = conn.cursor()
        
        # 各統計情報を表示
        get_basic_statistics(cursor)
        get_event_statistics(cursor)
        get_gps_checkin_statistics(cursor)
        get_team_statistics(cursor)
        get_data_quality_check(cursor)
        export_statistics_json(cursor)
        
        print("\n" + "="*80)
        print("✅ 統計情報表示完了")
        print("="*80)
        
    except Exception as e:
        print(f"❌ 統計処理中にエラーが発生しました: {e}")
        import traceback
        traceback.print_exc()
    finally:
        cursor.close()
        conn.close()

if __name__ == "__main__":
    main()
