"""
郵件帳號管理 API
符合 WebMail 設計規範 - 員工只能使用 HR Portal 授權的郵件帳號
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status, Request
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import or_

from app.db.session import get_db
from app.models.employee import Employee
from app.models.email_account import EmailAccount
from app.schemas.email_account import (
    EmailAccountCreate,
    EmailAccountUpdate,
    EmailAccountResponse,
    EmailAccountListItem,
    EmailAccountQuotaUpdate,
)
from app.schemas.base import PaginationParams, PaginatedResponse
from app.schemas.response import SuccessResponse, MessageResponse
from app.api.deps import get_pagination_params
from app.services.audit_service import audit_service

router = APIRouter()


def get_current_tenant_id() -> int:
    """取得當前租戶 ID (暫時寫死為 1, 未來從 JWT token 取得)"""
    return 1


@router.get("/", response_model=PaginatedResponse)
def get_email_accounts(
    db: Session = Depends(get_db),
    pagination: PaginationParams = Depends(get_pagination_params),
    employee_id: Optional[int] = Query(None, description="員工 ID 篩選"),
    is_active: Optional[bool] = Query(None, description="狀態篩選"),
    search: Optional[str] = Query(None, description="搜尋郵件地址"),
):
    """
    獲取郵件帳號列表

    支援:
    - 分頁
    - 員工篩選
    - 狀態篩選
    - 郵件地址搜尋
    """
    tenant_id = get_current_tenant_id()
    query = db.query(EmailAccount).filter(EmailAccount.tenant_id == tenant_id)

    # 員工篩選
    if employee_id:
        query = query.filter(EmailAccount.employee_id == employee_id)

    # 狀態篩選
    if is_active is not None:
        query = query.filter(EmailAccount.is_active == is_active)

    # 搜尋
    if search:
        search_pattern = f"%{search}%"
        query = query.filter(EmailAccount.email_address.ilike(search_pattern))

    # 總數
    total = query.count()

    # 分頁
    offset = (pagination.page - 1) * pagination.page_size
    email_accounts = (
        query.options(joinedload(EmailAccount.employee))
        .offset(offset)
        .limit(pagination.page_size)
        .all()
    )

    # 計算總頁數
    total_pages = (total + pagination.page_size - 1) // pagination.page_size

    # 組裝回應資料
    items = []
    for account in email_accounts:
        item = EmailAccountListItem.model_validate(account)
        item.employee_name = account.employee.legal_name if account.employee else None
        item.employee_number = account.employee.employee_id if account.employee else None
        items.append(item)

    return PaginatedResponse(
        total=total,
        page=pagination.page,
        page_size=pagination.page_size,
        total_pages=total_pages,
        items=items,
    )


@router.get("/{email_account_id}", response_model=EmailAccountResponse)
def get_email_account(
    email_account_id: int,
    db: Session = Depends(get_db),
):
    """
    獲取郵件帳號詳情
    """
    tenant_id = get_current_tenant_id()
    account = (
        db.query(EmailAccount)
        .options(joinedload(EmailAccount.employee))
        .filter(
            EmailAccount.id == email_account_id,
            EmailAccount.tenant_id == tenant_id,
        )
        .first()
    )

    if not account:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Email account with id {email_account_id} not found",
        )

    # 組裝回應資料
    response = EmailAccountResponse.model_validate(account)
    response.employee_name = account.employee.legal_name if account.employee else None
    response.employee_number = account.employee.employee_id if account.employee else None

    return response


@router.post("/", response_model=EmailAccountResponse, status_code=status.HTTP_201_CREATED)
def create_email_account(
    account_data: EmailAccountCreate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    創建郵件帳號

    注意:
    - 郵件地址必須唯一
    - 員工必須存在
    - 配額範圍: 1GB - 100GB
    """
    tenant_id = get_current_tenant_id()

    # 檢查員工是否存在
    employee = db.query(Employee).filter(
        Employee.id == account_data.employee_id,
        Employee.tenant_id == tenant_id,
    ).first()

    if not employee:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Employee with id {account_data.employee_id} not found",
        )

    # 檢查郵件地址是否已存在
    existing = db.query(EmailAccount).filter(
        EmailAccount.email_address == account_data.email_address
    ).first()

    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Email address '{account_data.email_address}' already exists",
        )

    # 創建郵件帳號
    account = EmailAccount(
        tenant_id=tenant_id,
        employee_id=account_data.employee_id,
        email_address=account_data.email_address,
        quota_mb=account_data.quota_mb,
        forward_to=account_data.forward_to,
        auto_reply=account_data.auto_reply,
        is_active=account_data.is_active,
    )

    db.add(account)
    db.commit()
    db.refresh(account)

    # 記錄審計日誌
    audit_service.log_action(
        request=request,
        db=db,
        action="create_email_account",
        resource_type="email_account",
        resource_id=account.id,
        details={
            "email_address": account.email_address,
            "employee_id": account.employee_id,
            "quota_mb": account.quota_mb,
        },
    )

    # 組裝回應資料
    response = EmailAccountResponse.model_validate(account)
    response.employee_name = employee.legal_name
    response.employee_number = employee.employee_id

    return response


@router.put("/{email_account_id}", response_model=EmailAccountResponse)
def update_email_account(
    email_account_id: int,
    account_data: EmailAccountUpdate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    更新郵件帳號

    可更新:
    - 配額
    - 轉寄地址
    - 自動回覆
    - 啟用狀態
    """
    tenant_id = get_current_tenant_id()
    account = (
        db.query(EmailAccount)
        .options(joinedload(EmailAccount.employee))
        .filter(
            EmailAccount.id == email_account_id,
            EmailAccount.tenant_id == tenant_id,
        )
        .first()
    )

    if not account:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Email account with id {email_account_id} not found",
        )

    # 記錄變更前的值
    changes = {}

    # 更新欄位
    update_data = account_data.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        old_value = getattr(account, field)
        if old_value != value:
            changes[field] = {"from": old_value, "to": value}
            setattr(account, field, value)

    if changes:
        db.commit()
        db.refresh(account)

        # 記錄審計日誌
        audit_service.log_action(
            request=request,
            db=db,
            action="update_email_account",
            resource_type="email_account",
            resource_id=account.id,
            details={
                "email_address": account.email_address,
                "changes": changes,
            },
        )

    # 組裝回應資料
    response = EmailAccountResponse.model_validate(account)
    response.employee_name = account.employee.legal_name if account.employee else None
    response.employee_number = account.employee.employee_id if account.employee else None

    return response


@router.patch("/{email_account_id}/quota", response_model=EmailAccountResponse)
def update_email_quota(
    email_account_id: int,
    quota_data: EmailAccountQuotaUpdate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    更新郵件配額

    快速更新配額的端點
    """
    tenant_id = get_current_tenant_id()
    account = (
        db.query(EmailAccount)
        .options(joinedload(EmailAccount.employee))
        .filter(
            EmailAccount.id == email_account_id,
            EmailAccount.tenant_id == tenant_id,
        )
        .first()
    )

    if not account:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Email account with id {email_account_id} not found",
        )

    old_quota = account.quota_mb
    account.quota_mb = quota_data.quota_mb

    db.commit()
    db.refresh(account)

    # 記錄審計日誌
    audit_service.log_action(
        request=request,
        db=db,
        action="update_email_quota",
        resource_type="email_account",
        resource_id=account.id,
        details={
            "email_address": account.email_address,
            "old_quota_mb": old_quota,
            "new_quota_mb": quota_data.quota_mb,
        },
    )

    # 組裝回應資料
    response = EmailAccountResponse.model_validate(account)
    response.employee_name = account.employee.legal_name if account.employee else None
    response.employee_number = account.employee.employee_id if account.employee else None

    return response


@router.delete("/{email_account_id}", response_model=MessageResponse)
def delete_email_account(
    email_account_id: int,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    刪除郵件帳號

    注意:
    - 軟刪除: 設為停用
    - 需要記錄審計日誌
    """
    tenant_id = get_current_tenant_id()
    account = db.query(EmailAccount).filter(
        EmailAccount.id == email_account_id,
        EmailAccount.tenant_id == tenant_id,
    ).first()

    if not account:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Email account with id {email_account_id} not found",
        )

    # 軟刪除: 設為停用
    account.is_active = False
    db.commit()

    # 記錄審計日誌
    audit_service.log_action(
        request=request,
        db=db,
        action="delete_email_account",
        resource_type="email_account",
        resource_id=account.id,
        details={
            "email_address": account.email_address,
            "employee_id": account.employee_id,
        },
    )

    return MessageResponse(
        message=f"Email account {account.email_address} has been deactivated"
    )


@router.get("/employees/{employee_id}/email-accounts")
def get_employee_email_accounts(
    employee_id: int,
    db: Session = Depends(get_db),
):
    """
    取得員工授權的郵件帳號列表

    符合 WebMail 設計規範 (HR Portal設計文件 §2):
    - 員工不可自行新增郵件帳號
    - 只能使用 HR Portal 授予的帳號
    - 支援多帳號切換 (ISO 帳號管理流程)

    回傳格式:
    {
        "user_id": "porsche.chen",
        "email_accounts": [
            {
                "email": "porsche.chen@porscheworld.tw",
                "quota_mb": 5120,
                "status": "active",
                ...
            }
        ]
    }
    """
    tenant_id = get_current_tenant_id()

    # 檢查員工是否存在
    employee = db.query(Employee).filter(
        Employee.id == employee_id,
        Employee.tenant_id == tenant_id,
    ).first()

    if not employee:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Employee with id {employee_id} not found",
        )

    # 查詢員工的所有啟用郵件帳號
    accounts = (
        db.query(EmailAccount)
        .filter(
            EmailAccount.employee_id == employee_id,
            EmailAccount.tenant_id == tenant_id,
            EmailAccount.is_active == True,
        )
        .all()
    )

    # 組裝符合 WebMail 設計規範的回應格式
    email_accounts = []
    for account in accounts:
        email_accounts.append({
            "email": account.email_address,
            "quota_mb": account.quota_mb,
            "status": "active" if account.is_active else "inactive",
            "forward_to": account.forward_to,
            "auto_reply": account.auto_reply,
        })

    return {
        "user_id": employee.username_base,
        "email_accounts": email_accounts,
    }
