"""
系統階段轉換 API
處理三階段狀態轉換：Initialization → Operational ↔ Transition
"""
import os
import json
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from datetime import datetime

from app.api import deps

router = APIRouter()


@router.post("/complete-initialization")
async def complete_initialization(db: Session = Depends(deps.get_db)):
    """
    完成初始化，將系統狀態從 Initialization 轉換到 Operational

    條件檢查：
    1. 必須已完成 Redis, Database, Keycloak 設定
    2. 必須已建立公司資訊
    3. 必須已建立管理員帳號

    執行操作：
    1. 更新 installation_system_status
    2. 將 current_phase 從 'initialization' 改為 'operational'
    3. 設定 initialization_completed = True
    4. 記錄 initialized_at, operational_since
    """
    from app.models.installation import InstallationSystemStatus, InstallationEnvironmentConfig, InstallationTenantInfo

    try:
        # 1. 取得系統狀態
        system_status = db.query(InstallationSystemStatus).first()

        if not system_status:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="系統狀態記錄不存在"
            )

        if system_status.current_phase != "initialization":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"系統當前階段為 {system_status.current_phase}，無法執行此操作"
            )

        # 2. 檢查必要配置是否完成
        required_categories = ["redis", "database", "keycloak"]
        configured_categories = db.query(InstallationEnvironmentConfig.config_category).filter(
            InstallationEnvironmentConfig.is_configured == True
        ).distinct().all()
        configured_categories = [cat[0] for cat in configured_categories]

        missing = [cat for cat in required_categories if cat not in configured_categories]
        if missing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"尚未完成環境配置: {', '.join(missing)}"
            )

        # 3. 檢查是否已建立租戶資訊
        tenant_info = db.query(InstallationTenantInfo).first()
        if not tenant_info or not tenant_info.is_completed:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="尚未完成公司資訊設定"
            )

        # 4. 更新系統狀態
        now = datetime.now()
        system_status.previous_phase = system_status.current_phase
        system_status.current_phase = "operational"
        system_status.phase_changed_at = now
        system_status.phase_change_reason = "初始化完成，進入營運階段"
        system_status.initialization_completed = True
        system_status.initialized_at = now
        system_status.operational_since = now
        system_status.updated_at = now

        db.commit()
        db.refresh(system_status)

        return {
            "success": True,
            "message": "系統初始化完成，已進入營運階段",
            "current_phase": system_status.current_phase,
            "operational_since": system_status.operational_since.isoformat(),
            "next_action": "redirect_to_login"
        }

    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"完成初始化失敗: {str(e)}"
        )


@router.post("/switch-phase")
async def switch_phase(
    target_phase: str,
    reason: str = None,
    db: Session = Depends(deps.get_db)
):
    """
    切換系統階段（Operational ↔ Transition）

    Args:
        target_phase: operational | transition
        reason: 切換原因

    Rules:
        - operational → transition: 需進行系統遷移時
        - transition → operational: 完成遷移並通過一致性檢查後
    """
    from app.models.installation import InstallationSystemStatus

    if target_phase not in ["operational", "transition"]:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="target_phase 必須為 'operational' 或 'transition'"
        )

    try:
        system_status = db.query(InstallationSystemStatus).first()

        if not system_status:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="系統狀態記錄不存在"
            )

        # 不允許從 initialization 直接切換
        if system_status.current_phase == "initialization":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="初始化階段無法直接切換，請先完成初始化"
            )

        # 檢查是否已是目標階段
        if system_status.current_phase == target_phase:
            return {
                "success": True,
                "message": f"系統已處於 {target_phase} 階段",
                "current_phase": target_phase
            }

        # 特殊檢查：從 transition 回到 operational 必須通過一致性檢查
        if system_status.current_phase == "transition" and target_phase == "operational":
            if not system_status.env_db_consistent:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="環境與資料庫不一致，無法切換回營運階段"
                )

        # 執行切換
        now = datetime.now()
        system_status.previous_phase = system_status.current_phase
        system_status.current_phase = target_phase
        system_status.phase_changed_at = now
        system_status.phase_change_reason = reason or f"手動切換至 {target_phase} 階段"

        # 根據目標階段更新相關欄位
        if target_phase == "transition":
            system_status.transition_started_at = now
            system_status.env_db_consistent = None  # 重置一致性狀態
            system_status.inconsistencies = None
        elif target_phase == "operational":
            system_status.operational_since = now

        system_status.updated_at = now

        db.commit()
        db.refresh(system_status)

        return {
            "success": True,
            "message": f"已切換至 {target_phase} 階段",
            "current_phase": system_status.current_phase,
            "previous_phase": system_status.previous_phase,
            "phase_changed_at": system_status.phase_changed_at.isoformat()
        }

    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"階段切換失敗: {str(e)}"
        )


@router.post("/check-consistency")
async def check_env_db_consistency(db: Session = Depends(deps.get_db)):
    """
    檢查 .env 檔案與資料庫配置的一致性（Transition 階段使用）

    比對項目：
    - REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB
    - DATABASE_URL, DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER
    - KEYCLOAK_URL, KEYCLOAK_REALM, KEYCLOAK_ADMIN_USERNAME

    Returns:
        is_consistent: True/False
        inconsistencies: 不一致項目列表
    """
    from app.models.installation import InstallationSystemStatus, InstallationEnvironmentConfig

    try:
        system_status = db.query(InstallationSystemStatus).first()

        if not system_status:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="系統狀態記錄不存在"
            )

        # 從資料庫讀取配置
        db_configs = {}
        config_records = db.query(InstallationEnvironmentConfig).filter(
            InstallationEnvironmentConfig.is_configured == True
        ).all()

        for record in config_records:
            db_configs[record.config_key] = record.config_value

        # 從 .env 讀取配置
        env_configs = {}
        env_file_path = os.path.join(os.getcwd(), '.env')

        if os.path.exists(env_file_path):
            with open(env_file_path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith('#') and '=' in line:
                        key, value = line.split('=', 1)
                        env_configs[key.strip()] = value.strip()

        # 比對差異（排除敏感資訊的顯示）
        inconsistencies = []
        checked_keys = set(db_configs.keys()) | set(env_configs.keys())

        for key in checked_keys:
            db_value = db_configs.get(key, "[NOT SET]")
            env_value = env_configs.get(key, "[NOT SET]")

            if db_value != env_value:
                # 檢查是否為敏感資訊
                is_sensitive = any(sensitive in key.lower() for sensitive in ['password', 'secret', 'key'])

                inconsistencies.append({
                    "config_key": key,
                    "db_value": "[HIDDEN]" if is_sensitive else db_value,
                    "env_value": "[HIDDEN]" if is_sensitive else env_value,
                    "is_sensitive": is_sensitive
                })

        is_consistent = len(inconsistencies) == 0

        # 更新系統狀態
        now = datetime.now()
        system_status.env_db_consistent = is_consistent
        system_status.consistency_checked_at = now
        system_status.inconsistencies = json.dumps(inconsistencies, ensure_ascii=False) if inconsistencies else None
        system_status.updated_at = now

        db.commit()

        return {
            "is_consistent": is_consistent,
            "checked_at": now.isoformat(),
            "total_configs": len(checked_keys),
            "inconsistency_count": len(inconsistencies),
            "inconsistencies": inconsistencies,
            "message": "環境配置一致" if is_consistent else f"發現 {len(inconsistencies)} 項不一致"
        }

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"一致性檢查失敗: {str(e)}"
        )
