"""啟動時資料庫 schema 自動修復。

從 app.py 抽出的 repair_database_schema()。
歷史背景：早期 V9.53 起為了讓部署不必執行 migration，在啟動時動態檢查欄位並
ALTER TABLE 補上。長期應改走 Alembic / Migration script，但這個 fallback 還活著。

呼叫端：app.py 啟動末段呼叫一次。
"""
from utils.logger_manager import SystemLogger

_log = SystemLogger("SchemaRepair").get_logger()


def _ensure_column(engine, text_fn, table, column, ddl, post_sql=None):
    """補上單一欄位 helper：若不存在則 ALTER TABLE。"""
    from sqlalchemy import inspect
    inspector = inspect(engine)
    if table not in inspector.get_table_names():
        return False
    columns = [c['name'] for c in inspector.get_columns(table)]
    if column in columns:
        return False
    _log.warning(f"[Database] [Schema] ⚠️ 偵測到 {table} 表缺少 {column} 欄位 | 正在自動修復...")
    with engine.connect() as conn:
        conn.execute(text_fn(ddl))
        if post_sql:
            conn.execute(text_fn(post_sql))
        conn.commit()
    _log.info(f"[Database] [Schema] ✅ {table}.{column} 欄位修復完成")
    return True


def repair_database_schema():
    """啟動時資料庫結構自動修復（V9.53）。"""
    from database.manager import DatabaseManager
    from sqlalchemy import inspect, text
    from config import DATABASE_TYPE

    db = DatabaseManager()
    engine = db.engine

    try:
        # V9.96: SQLite WAL 模式（解決 database is locked）
        if DATABASE_TYPE == 'sqlite':
            with engine.connect() as conn:
                conn.execute(text("PRAGMA journal_mode=WAL"))
                conn.commit()
            _log.info("[Database] [WAL] ✅ SQLite WAL 模式已啟用 | 提升並發寫入效能")
        else:
            _log.info(f"[Database] ✅ 使用 {DATABASE_TYPE.upper()} 資料庫")

        inspector = inspect(engine)

        # V9.70: products 表
        _ensure_column(engine, text, 'products', 'image_url',
                       "ALTER TABLE products ADD COLUMN image_url TEXT")
        _ensure_column(engine, text, 'products', 'created_at',
                       "ALTER TABLE products ADD COLUMN created_at DATETIME",
                       post_sql="UPDATE products SET created_at = updated_at WHERE created_at IS NULL")

        # promo_products 表
        promo_columns = [
            ('url', "ALTER TABLE promo_products ADD COLUMN url TEXT"),
            ('image_url', "ALTER TABLE promo_products ADD COLUMN image_url TEXT"),
            ('previous_price', "ALTER TABLE promo_products ADD COLUMN previous_price INTEGER"),
            ('session_time_text', "ALTER TABLE promo_products ADD COLUMN session_time_text TEXT"),
            ('remain_qty', "ALTER TABLE promo_products ADD COLUMN remain_qty INTEGER"),
            ('discount_text', "ALTER TABLE promo_products ADD COLUMN discount_text TEXT"),
            ('page_type', "ALTER TABLE promo_products ADD COLUMN page_type TEXT DEFAULT 'edm'"),
        ]
        for col_name, ddl in promo_columns:
            _ensure_column(engine, text, 'promo_products', col_name, ddl)

        # V10.328: PChome/MOMO 比價診斷欄位。正式價差與待審嘗試都需可回溯
        # URL、圖片、庫存與 matcher 結構化原因，避免「待比對」無法被人工處理。
        json_type = 'JSONB' if DATABASE_TYPE == 'postgresql' else 'TEXT'
        competitor_price_columns = [
            ('competitor_product_url', "ALTER TABLE competitor_prices ADD COLUMN competitor_product_url TEXT"),
            ('competitor_image_url', "ALTER TABLE competitor_prices ADD COLUMN competitor_image_url TEXT"),
            ('competitor_stock', "ALTER TABLE competitor_prices ADD COLUMN competitor_stock INTEGER"),
            ('match_diagnostic_json', f"ALTER TABLE competitor_prices ADD COLUMN match_diagnostic_json {json_type}"),
            ('comparison_mode', "ALTER TABLE competitor_prices ADD COLUMN comparison_mode VARCHAR(40)"),
            ('hard_veto', "ALTER TABLE competitor_prices ADD COLUMN hard_veto BOOLEAN"),
            ('diagnostic_codes', f"ALTER TABLE competitor_prices ADD COLUMN diagnostic_codes {json_type}"),
        ]
        competitor_history_columns = [
            ('competitor_product_url', "ALTER TABLE competitor_price_history ADD COLUMN competitor_product_url TEXT"),
            ('competitor_image_url', "ALTER TABLE competitor_price_history ADD COLUMN competitor_image_url TEXT"),
            ('competitor_stock', "ALTER TABLE competitor_price_history ADD COLUMN competitor_stock INTEGER"),
            ('match_diagnostic_json', f"ALTER TABLE competitor_price_history ADD COLUMN match_diagnostic_json {json_type}"),
            ('comparison_mode', "ALTER TABLE competitor_price_history ADD COLUMN comparison_mode VARCHAR(40)"),
            ('hard_veto', "ALTER TABLE competitor_price_history ADD COLUMN hard_veto BOOLEAN"),
            ('diagnostic_codes', f"ALTER TABLE competitor_price_history ADD COLUMN diagnostic_codes {json_type}"),
        ]
        competitor_attempt_columns = [
            ('competitor_product_url', "ALTER TABLE competitor_match_attempts ADD COLUMN competitor_product_url TEXT"),
            ('competitor_image_url', "ALTER TABLE competitor_match_attempts ADD COLUMN competitor_image_url TEXT"),
            ('competitor_stock', "ALTER TABLE competitor_match_attempts ADD COLUMN competitor_stock INTEGER"),
            ('match_diagnostic_json', f"ALTER TABLE competitor_match_attempts ADD COLUMN match_diagnostic_json {json_type}"),
            ('comparison_mode', "ALTER TABLE competitor_match_attempts ADD COLUMN comparison_mode VARCHAR(40)"),
            ('hard_veto', "ALTER TABLE competitor_match_attempts ADD COLUMN hard_veto BOOLEAN"),
            ('diagnostic_codes', f"ALTER TABLE competitor_match_attempts ADD COLUMN diagnostic_codes {json_type}"),
        ]
        for table_columns in (competitor_price_columns, competitor_history_columns, competitor_attempt_columns):
            for col_name, ddl in table_columns:
                table_name = ddl.split()[2]
                _ensure_column(engine, text, table_name, col_name, ddl)

    except Exception as e:
        _log.error(f"[Database] [Schema] ❌ 資料庫修復失敗 | Error: {e}")
