"""Nomenclature API endpoints."""

from typing import Optional, List, Annotated
from fastapi import APIRouter, Depends, HTTPException, Header
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic import BaseModel

from backend.modules.data_entry.db.database import get_session
from backend.modules.data_entry.services.sync_service import SyncService

# Import auth dependencies
import sys
from pathlib import Path
# Path setup handled by main.py - this is redundant
# project_root = Path(__file__).parent.parent.parent.parent.parent
# sys.path.insert(0, str(project_root / "shared"))

from shared.auth.dependencies import get_current_user
from shared.auth.models import CurrentUser

router = APIRouter()


# ============ Selected Company Dependency ============

async def get_selected_company(
    current_user: CurrentUser = Depends(get_current_user),
    x_selected_company: Annotated[Optional[str], Header()] = None
) -> int:
    """
    Get selected company from X-Selected-Company header.
    Validates user access. Falls back to first company if no header.
    """
    if x_selected_company:
        try:
            company_id = int(x_selected_company)
        except ValueError:
            raise HTTPException(400, f"Invalid company ID: {x_selected_company}")

        if str(company_id) in current_user.companies:
            return company_id
        raise HTTPException(403, f"Nu aveți acces la firma {company_id}")

    if current_user.companies:
        try:
            return int(current_user.companies[0])
        except (ValueError, IndexError):
            pass

    raise HTTPException(400, "Nu aveți nicio firmă asignată")


SelectedCompany = Annotated[int, Depends(get_selected_company)]


# Request/Response Models
class SupplierSearchResult(BaseModel):
    found: bool
    supplier: Optional[dict] = None
    source: str  # 'synced', 'local', 'not_found'


class LocalSupplierCreate(BaseModel):
    name: str
    fiscal_code: Optional[str] = None
    address: Optional[str] = None


class LocalSupplierResponse(BaseModel):
    id: int
    name: str
    fiscal_code: Optional[str]
    address: Optional[str]
    is_local: bool = True


class SyncResult(BaseModel):
    synced: int
    errors: int
    message: str


class SupplierOption(BaseModel):
    id: int
    oracle_id: Optional[int] = None
    name: str
    fiscal_code: Optional[str]
    source: str  # 'synced' or 'local'


class CashRegisterOption(BaseModel):
    id: int
    oracle_id: int
    name: str
    account_code: str
    register_type: str


# Endpoints
@router.get("/suppliers/search", response_model=SupplierSearchResult)
async def search_supplier(
    fiscal_code: Optional[str] = None,
    name: Optional[str] = None,
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Search for supplier by fiscal code or name."""
    if not fiscal_code and not name:
        raise HTTPException(status_code=400, detail="Provide fiscal_code or name")

    cid = company_id or selected_company

    found, supplier, source = await SyncService.search_supplier(
        session, cid, fiscal_code, name
    )

    return SupplierSearchResult(found=found, supplier=supplier, source=source)


@router.get("/suppliers", response_model=List[SupplierOption])
async def get_suppliers(
    search: Optional[str] = None,
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Get all suppliers (synced + local) for dropdown/autocomplete."""
    cid = company_id or selected_company

    suppliers = await SyncService.get_all_suppliers(session, cid, search)

    return [
        SupplierOption(
            id=s["id"],
            oracle_id=s.get("oracle_id"),
            name=s["name"],
            fiscal_code=s.get("fiscal_code"),
            source=s["source"]
        )
        for s in suppliers
    ]


@router.post("/suppliers/local", response_model=LocalSupplierResponse)
async def create_local_supplier(
    data: LocalSupplierCreate,
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
    current_user: CurrentUser = Depends(get_current_user),
):
    """Create a local supplier from OCR data."""
    cid = company_id or selected_company

    supplier = await SyncService.create_local_supplier(
        session, cid, data.name, data.fiscal_code, data.address, current_user.username
    )

    return LocalSupplierResponse(
        id=supplier.id,
        name=supplier.name,
        fiscal_code=supplier.fiscal_code,
        address=supplier.address,
    )


@router.get("/cash-registers", response_model=List[CashRegisterOption])
async def get_cash_registers(
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Get all cash registers for a company."""
    cid = company_id or selected_company

    registers = await SyncService.get_all_cash_registers(session, cid)

    return [
        CashRegisterOption(
            id=r["id"],
            oracle_id=r["oracle_id"],
            name=r["name"],
            account_code=r["account_code"],
            register_type=r["register_type"]
        )
        for r in registers
    ]


@router.post("/sync/suppliers", response_model=SyncResult)
async def sync_suppliers(
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Manually trigger supplier sync from Oracle."""
    cid = company_id or selected_company

    synced, errors = await SyncService.sync_suppliers(session, cid)

    return SyncResult(
        synced=synced,
        errors=errors,
        message=f"Synced {synced} suppliers with {errors} errors"
    )


@router.post("/sync/cash-registers", response_model=SyncResult)
async def sync_cash_registers(
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Manually trigger cash register sync from Oracle."""
    cid = company_id or selected_company

    synced, errors = await SyncService.sync_cash_registers(session, cid)

    return SyncResult(
        synced=synced,
        errors=errors,
        message=f"Synced {synced} cash registers with {errors} errors"
    )


@router.post("/sync/all", response_model=dict)
async def sync_all_nomenclatures(
    company_id: Optional[int] = None,
    session: AsyncSession = Depends(get_session),
    selected_company: SelectedCompany = None,
):
    """Sync all nomenclatures (suppliers + cash registers) from Oracle."""
    cid = company_id or selected_company

    # Sync suppliers
    suppliers_synced, suppliers_errors = await SyncService.sync_suppliers(session, cid)

    # Sync cash registers
    registers_synced, registers_errors = await SyncService.sync_cash_registers(session, cid)

    return {
        "suppliers": {
            "synced": suppliers_synced,
            "errors": suppliers_errors
        },
        "cash_registers": {
            "synced": registers_synced,
            "errors": registers_errors
        },
        "total_synced": suppliers_synced + registers_synced,
        "total_errors": suppliers_errors + registers_errors,
        "message": f"Synced {suppliers_synced} suppliers and {registers_synced} cash registers"
    }
