"""
Shared Companies Router Factory for ROA2WEB Applications

Creates a FastAPI router for /api/companies endpoints that can be used
by both the unified monolith backend.

Usage:
    from shared.routes.companies import create_companies_router

    companies_router = create_companies_router(oracle_pool, cache_decorator=cached)
    app.include_router(companies_router, prefix="/api/companies")
"""

import logging
from typing import Optional, Callable, List

from fastapi import APIRouter, Depends, HTTPException, Request

from auth.dependencies import get_current_user
from auth.models import CurrentUser
from models.company import Company, CompanyListResponse

logger = logging.getLogger(__name__)


def create_companies_router(
    oracle_pool,
    cache_decorator: Optional[Callable] = None,
    tags: Optional[List[str]] = None
) -> APIRouter:
    """
    Factory function to create a companies router.

    Args:
        oracle_pool: The Oracle connection pool instance
        cache_decorator: Optional caching decorator (e.g., @cached)
        tags: OpenAPI tags for the router

    Returns:
        Configured FastAPI router for company endpoints
    """
    router = APIRouter(
        redirect_slashes=False,
        tags=tags or ["companies"]
    )

    # Helper function to get companies - can be cached
    async def _get_user_companies_data(username: str) -> List[Company]:
        """
        Get list of companies for a user from Oracle.
        """
        companies = []

        async with oracle_pool.get_connection() as connection:
            with connection.cursor() as cursor:
                try:
                    # Get user ID
                    cursor.execute("""
                        SELECT ID_UTIL, UTILIZATOR
                        FROM UTILIZATORI
                        WHERE UPPER(UTILIZATOR) = :username
                    """, {'username': username.upper()})

                    user_row = cursor.fetchone()
                    if not user_row:
                        logger.warning(f"User {username} not found in UTILIZATORI")
                        return []

                    user_id = user_row[0]

                    # Get companies for user (program 2 = data entry/reports)
                    cursor.execute("""
                        SELECT A.ID_FIRMA, A.FIRMA, A.SCHEMA, A.COD_FISCAL
                        FROM V_NOM_FIRME A
                        WHERE A.ID_FIRMA IN (
                            SELECT ID_FIRMA
                            FROM VDEF_UTIL_FIRME
                            WHERE ID_PROGRAM = 2 AND ID_UTIL = :user_id
                        )
                        ORDER BY A.FIRMA
                    """, {'user_id': user_id})

                    for row in cursor.fetchall():
                        companies.append(Company(
                            id_firma=row[0],
                            name=row[1],
                            schema_name=row[2],
                            fiscal_code=row[3],
                            is_active=True
                        ))

                    logger.info(f"Found {len(companies)} companies for user {username}")

                except Exception as e:
                    logger.error(f"Error fetching companies: {e}")

        return companies

    # Apply cache decorator if provided
    if cache_decorator:
        _get_user_companies_data = cache_decorator(
            cache_type='companies',
            key_params=['username']
        )(_get_user_companies_data)

    @router.get("", response_model=CompanyListResponse)
    @router.get("/", response_model=CompanyListResponse)
    async def get_user_companies(
        request: Request,
        current_user: CurrentUser = Depends(get_current_user)
    ):
        """Get list of companies the user has access to."""
        try:
            companies = await _get_user_companies_data(current_user.username)

            return CompanyListResponse(
                companies=companies,
                total_count=len(companies)
            )
        except Exception as e:
            logger.error(f"Error in get_user_companies: {e}")
            raise HTTPException(500, f"Eroare la obținerea listei de firme: {str(e)}")

    @router.get("/{company_id}", response_model=Company)
    async def get_company_details(
        company_id: str,
        current_user: CurrentUser = Depends(get_current_user)
    ):
        """Get details of a specific company."""
        # Validate access
        if company_id not in current_user.companies:
            raise HTTPException(403, f"Nu aveți acces la firma {company_id}")

        try:
            async with oracle_pool.get_connection() as connection:
                with connection.cursor() as cursor:
                    cursor.execute("""
                        SELECT ID_FIRMA, FIRMA, SCHEMA, COD_FISCAL
                        FROM V_NOM_FIRME
                        WHERE ID_FIRMA = :company_id
                    """, {'company_id': int(company_id)})
                    row = cursor.fetchone()

                    if not row:
                        raise HTTPException(404, f"Firma {company_id} nu a fost găsită")

                    return Company(
                        id_firma=row[0],
                        name=row[1],
                        schema_name=row[2],
                        fiscal_code=row[3] or "",
                        is_active=True
                    )

        except HTTPException:
            raise
        except Exception as e:
            raise HTTPException(500, f"Eroare la obținerea detaliilor firmei: {str(e)}")

    @router.get("/{company_id}/validate")
    async def validate_company_access(
        company_id: str,
        current_user: CurrentUser = Depends(get_current_user)
    ):
        """Validate if user has access to a company."""
        has_access = company_id in current_user.companies

        return {
            "company_id": company_id,
            "has_access": has_access,
            "user": current_user.username,
            "message": "Acces validat" if has_access else "Acces refuzat"
        }

    return router
