import logging

from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel, Field

from app.modules.partners.application.partner_service import PartnerService

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/v1/erp/partners", tags=["Partners & Customers"])

partner_service = PartnerService()


class PartnerUpdatePayload(BaseModel):
    short_name: str | None = Field(None, description="Tên viết tắt / tên thương mại")
    phone: str | None = Field(None, description="Số điện thoại liên hệ")
    email: str | None = Field(None, description="Email giao dịch")
    representative_name: str | None = Field(
        None, description="Người đại diện theo pháp luật / liên hệ"
    )
    is_partner: bool | None = Field(
        None, description="Đánh dấu đối tác hợp tác / liên danh / thầu phụ"
    )
    status: str | None = Field(
        None, description="Trạng thái (active, inactive, archived)"
    )
    notes: str | None = Field(None, description="Ghi chú nội bộ")


@router.get("")
def list_partners(
    search: str | None = Query(
        None, description="Tìm kiếm theo MST, Tên công ty, Địa chỉ, Đại diện"
    ),
    role: str = Query(
        "all", description="Bộ lọc vai trò: 'all', 'customer', 'partner', 'vendor'"
    ),
    category: str = Query(
        "all", description="Bộ lọc loại: 'all', 'organization', 'individual'"
    ),
    has_history: bool | None = Query(
        None, description="Chỉ lấy các đơn vị có lịch sử đổi tên/địa chỉ"
    ),
    page: int = Query(1, ge=1, description="Trang số"),
    limit: int = Query(50, ge=1, le=200, description="Số lượng bản ghi trên một trang"),
):
    """
    Lấy danh sách Đối Tác, Khách Hàng & Nhà Cung Cấp.
    Hỗ trợ tìm kiếm nhanh, lọc theo vai trò và phân loại pháp nhân/cá nhân.
    """
    try:
        return partner_service.get_partners(
            search=search,
            role_filter=role,
            category_filter=category,
            has_history=has_history,
            page=page,
            limit=limit,
        )
    except Exception as e:
        logger.error(f"Error fetching partners list: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/{partner_id}")
def get_partner_detail(partner_id: str):
    """
    Lấy thông tin chi tiết một đối tác/khách hàng, kèm:
    - Toàn bộ dòng thời gian lịch sử thay đổi tên và địa chỉ
    - Danh sách hóa đơn liên quan (đầu vào & đầu ra)
    - Danh sách dự án xây lắp liên kết
    """
    try:
        data = partner_service.get_partner_detail(partner_id)
        if not data:
            raise HTTPException(
                status_code=404, detail="Không tìm thấy thông tin đối tác/khách hàng"
            )
        return data
    except HTTPException:
        raise
    except Exception as e:
        logger.error(
            f"Error fetching partner detail for {partner_id}: {e}", exc_info=True
        )
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/extract-from-invoices")
def trigger_extract_from_invoices():
    """
    Kích hoạt quét và đồng bộ lại danh mục đối tác từ 100% hóa đơn điện tử thực tế.
    """
    try:
        res = partner_service.extract_and_sync_all_partners_from_invoices()
        return res
    except Exception as e:
        logger.error(f"Error extracting partners from invoices: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.patch("/{partner_id}")
def update_partner(partner_id: str, payload: PartnerUpdatePayload):
    """
    Cập nhật thông tin bổ sung đối tác (SĐT, Email, Người đại diện, Ghi chú, Đánh dấu đối tác hợp tác).
    """
    try:
        updates = payload.model_dump(exclude_unset=True)
        res = partner_service.update_partner(partner_id, updates)
        if not res:
            raise HTTPException(
                status_code=404, detail="Không tìm thấy thông tin đối tác"
            )
        return res
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error updating partner {partner_id}: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))
