"""Sales Accounting Integration API — Phase 5.6."""
from __future__ import annotations

from decimal import Decimal
from uuid import UUID

from fastapi import APIRouter, Depends, status
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, require_tenant
from app.core.security import get_current_user
from app.models.sales_accounting import SalesPostingProfile
from app.models.types import SalesDocumentType
from app.repositories.base import TenantBaseRepository
from app.services.sales_accounting_service import SalesAccountingService
from shared.security import CurrentUser

router = APIRouter()


class SalesPostingProfileCreate(BaseModel):
    name: str
    document_type: SalesDocumentType
    revenue_account_id: UUID | None = None
    receivable_account_id: UUID | None = None
    cash_account_id: UUID | None = None
    discount_account_id: UUID | None = None
    tax_account_id: UUID | None = None
    is_default: bool = False


class SalesPostingProfileRead(BaseModel):
    id: UUID
    tenant_id: UUID
    name: str
    document_type: SalesDocumentType
    is_default: bool
    is_active: bool

    model_config = {"from_attributes": True}


class SalesPreviewRequest(BaseModel):
    document_type: SalesDocumentType = SalesDocumentType.INVOICE
    total_amount: Decimal
    discount_amount: Decimal = Decimal("0")
    tax_amount: Decimal = Decimal("0")
    profile_id: UUID | None = None


class SalesPostRequest(BaseModel):
    document_type: SalesDocumentType = SalesDocumentType.INVOICE
    source_document_id: str
    total_amount: Decimal
    discount_amount: Decimal = Decimal("0")
    tax_amount: Decimal = Decimal("0")
    profile_id: UUID | None = None


class SalesProfileRepo(TenantBaseRepository[SalesPostingProfile]):
    model = SalesPostingProfile


@router.post("/posting-profiles", response_model=SalesPostingProfileRead, status_code=status.HTTP_201_CREATED)
async def create_posting_profile(
    body: SalesPostingProfileCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    repo = SalesProfileRepo(db)
    entity = SalesPostingProfile(tenant_id=tenant_id, **body.model_dump())
    await repo.add(entity)
    await db.commit()
    await db.refresh(entity)
    return entity


@router.get("/posting-profiles", response_model=list[SalesPostingProfileRead])
async def list_posting_profiles(
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    repo = SalesProfileRepo(db)
    return await repo.list_by_tenant(tenant_id, limit=100)


@router.post("/preview")
async def preview_accounting(
    body: SalesPreviewRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    svc = SalesAccountingService(db)
    preview = await svc.preview_sales_invoice(
        tenant_id,
        document_type=body.document_type,
        total_amount=body.total_amount,
        discount_amount=body.discount_amount,
        tax_amount=body.tax_amount,
        profile_id=body.profile_id,
    )
    await db.commit()
    return {
        "is_balanced": preview.is_balanced,
        "total_debit": str(preview.total_debit),
        "total_credit": str(preview.total_credit),
        "preview_data": preview.preview_data,
    }


@router.post("/post")
async def post_sales_accounting(
    body: SalesPostRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    svc = SalesAccountingService(db)
    voucher = await svc.post_sales_invoice(
        tenant_id,
        document_type=body.document_type,
        source_document_id=body.source_document_id,
        total_amount=body.total_amount,
        discount_amount=body.discount_amount,
        tax_amount=body.tax_amount,
        profile_id=body.profile_id,
        actor_user_id=user.user_id,
    )
    await db.commit()
    return {"voucher_id": str(voucher.id), "voucher_number": voucher.voucher_number, "status": voucher.status.value}
