from datetime import datetime, timezone

from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from .dto import AccountCreate, AccountUpdate
from .models import Account


def get_accounts(
    db: Session,
    tenant_id: int,
    company_id: int,
    search: str | None = None,
    account_status: str | None = None,
    record_type: str | None = None,
) -> list[Account]:
    query = db.query(Account).filter(
        Account.tenant_id == tenant_id,
        Account.company_id == company_id,
        Account.deleted_at.is_(None),
    )
    if search:
        pattern = f"%{search}%"
        query = query.filter(
            Account.name.ilike(pattern)
            | Account.trade_name.ilike(pattern)
            | Account.rfc.ilike(pattern)
        )
    if account_status:
        query = query.filter(Account.status == account_status)
    if record_type:
        query = query.filter(Account.record_type == record_type)
    return query.order_by(Account.name.asc()).all()


def get_account(db: Session, account_id: int, tenant_id: int, company_id: int) -> Account:
    account = (
        db.query(Account)
        .filter(
            Account.id == account_id,
            Account.tenant_id == tenant_id,
            Account.company_id == company_id,
            Account.deleted_at.is_(None),
        )
        .first()
    )
    if not account:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Cliente no encontrado")
    return account


def create_account(
    db: Session, payload: AccountCreate, tenant_id: int, company_id: int, user_id: str | None = None
) -> Account:
    account = Account(
        **payload.model_dump(),
        tenant_id=tenant_id,
        company_id=company_id,
        created_by=user_id,
        updated_by=user_id,
    )
    db.add(account)
    db.commit()
    db.refresh(account)
    return account


def update_account(
    db: Session,
    account_id: int,
    payload: AccountUpdate,
    tenant_id: int,
    company_id: int,
    user_id: str | None = None,
) -> Account:
    account = get_account(db, account_id, tenant_id, company_id)
    for field, value in payload.model_dump(exclude_unset=True).items():
        setattr(account, field, value)
    account.updated_by = user_id
    db.commit()
    db.refresh(account)
    return account


def delete_account(db: Session, account_id: int, tenant_id: int, company_id: int) -> None:
    account = get_account(db, account_id, tenant_id, company_id)
    # Soft delete: conserva el histórico comercial del cliente
    account.deleted_at = datetime.now(timezone.utc)
    db.commit()
