from typing import Optional
from sqlalchemy import select
from src.core.database import get_db
from src.core.auth import require_front
from src.models.empresas import Empresa
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from src.services.empresas import EmpresaService
from src.core.auth import require_enterprise_or_front
from fastapi import APIRouter, Depends, HTTPException, Query, status
from src.schemas.empresas import (
    EnterpriseCreate,
    EnterpriseUpdate,
    EnterpriseResponse,
)
from src.core.api_responses import (
    build_success_payload,
    to_schema_dict,
    SuccessResponse,
    ErrorResponse
)

router = APIRouter(
    prefix="/empresas",
    tags=["Empresas"],
)


@router.post(
    "/criar",
    summary="Criar empresa",
    description="""
Cria uma nova empresa. Requer token do Front (nível administrativo).

Autenticação: Authorization: Bearer <FRONT_API_TOKEN>.

Exemplo cURL:

```bash
curl -X POST 'https://api.seu-dominio.com/empresas/criar' \
  -H 'Authorization: Bearer <FRONT_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"cnpj":"12.345.678","razaoSocial":"Acme","nomeFantasia":"Acme"}'
```

Alternativa usando cabeçalho X-Enterprise-Token (quando aplicável):

```bash
curl -X POST 'https://api.seu-dominio.com/empresas/criar' \
  -H 'X-Enterprise-Token: <TOKEN_EMPRESA>' \
  -H 'Content-Type: application/json' \
  -d '{"cnpj":"12.345.678","razaoSocial":"Acme","nomeFantasia":"Acme"}'
```
""",
    status_code=status.HTTP_201_CREATED,
    response_model=SuccessResponse,
    responses={
        201: {
            "description": "Empresa criada com sucesso"},
        400: {
            "description": "Violação de constraint ou dados inválidos",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
        500: {
            "description": "Erro interno",
            "model": ErrorResponse},
    },
    openapi_extra={
        "requestBody": {
            "content": {
                "application/json": {
                    "examples": {
                        "cnpj": "12.345.678/0001-90",
                        "razaoSocial": "Acme Ltda",
                        "nomeFantasia": "Acme"}}}},
        "responses": {
            "201": {
                "content": {
                    "application/json": {
                        "examples": {
                            "message": "Empresa criada com sucesso",
                            "data": {
                                "id": "id}",
                                "cnpj": "12.345.678/0001-90",
                                "razaoSocial": "Acme Ltda",
                                "nomeFantasia": "Acme",
                                "token": "<token>"
                            },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            },
            "400": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "VALIDATION_ERROR",
                                "message": "Dados inválidos",
                                "details": {
                                    "cnpj": ["campo obrigatório"]}},
                            "timestamp": "2025-01-01T12:00:00Z"}}}},
            "401": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "AUTH_ERROR",
                                "message": "Credenciais inválidas"},
                            "timestamp": "2025-01-01T12:00:00Z"}}}},
            "500": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "INTERNAL_SERVER_ERROR",
                                "message": "Erro inesperado"},
                            "timestamp": "2025-01-01T12:00:00Z"}}}}}})
async def criar_empresa(
    payload: EnterpriseCreate,
    db: AsyncSession = Depends(get_db),
    _front: None = Depends(require_front),
):
    existing_result = await db.execute(
        select(Empresa).where(
            (Empresa.cnpj == payload.cnpj)
            or (Empresa.nomeFantasia == payload.nomeFantasia)
        )
    )
    existed = existing_result.scalar_one_or_none() is not None

    obj = await EmpresaService.criar(db, payload)
    data = to_schema_dict(EnterpriseResponse, obj)
    if existed:
        message = f"Empresa já existe (ID: {data.get('id')})"
    else:
        message = f"Empresa criada com sucesso (ID: {data.get('id')})"
    return build_success_payload(data=data, message=message)


@router.get(
    "/buscar",
    summary="Listar empresas",
    description="""
Retorna empresas com filtros opcionais.

Parâmetros (query):
    - id (opcional): filtra por ID exato.
        - nomeFantasia (opcional): filtra por nome fantasia (parcial).

Sem filtros, retorna todas as empresas (escopo permitido pelo token).

Exemplo cURL (sem filtros):

```bash
curl -X GET 'https://api.seu-dominio.com/empresas/buscar' \
  -H 'Authorization: Bearer <TOKEN>'
```

Com filtro por nome fantasia:

```bash
curl -X GET 'https://api.seu-dominio.com/empresas/buscar?nomeFantasia=Acme' \
  -H 'Authorization: Bearer <TOKEN>'
```

Usando X-Enterprise-Token:

```bash
curl -X GET 'https://api.seu-dominio.com/empresas/buscar?nomeFantasia=Acme' \
  -H 'X-Enterprise-Token: <TOKEN_EMPRESA>'
```
""",
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Lista de empresas"},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
        500: {
            "description": "Erro interno",
            "model": ErrorResponse},
    },
    openapi_extra={
        "responses": {
            "200": {
                "content": {
                    "application/json": {
                        "examples": {
                            "message": "2 empresas encontradas",
                            "data": [
                                {
                                    "id": "id}",
                                    "cnpj": "12.345.678/0001-90",
                                    "razaoSocial": "Acme Ltda",
                                    "nomeFantasia": "Acme",
                                                    "token": "<token>"},
                                {
                                    "id": "2a8b3c4d-5e6f-7a8b-9c0d",
                                    "cnpj": "98.765.432/0001-10",
                                    "razaoSocial": "Beta S/A",
                                    "nomeFantasia": "Beta",
                                                    "token": "<token>"}],
                            "timestamp": "2025-01-01T12:00:00Z",
                        },
                    },
                },
            },
        },
    },
)
async def listar_empresas(
    token: Optional[str] = Query(
        None,
        description="Filtrar por token da empresa",
        examples="abc123...",
    ),
    nomeFantasia: Optional[str] = Query(
        None,
        description="Filtrar por nome fantasia (parcial)",
        examples="Acme",
    ),
    db: AsyncSession = Depends(get_db),
    ctx: dict = Depends(require_enterprise_or_front),
):
    if ctx["type"] == "enterprise":
        token = str(ctx["empresa"].token)
        nomeFantasia = None

    items = await EmpresaService.listar(
        db,
        enterprise_token=token,
        nomeFantasia=nomeFantasia
    )
    data = [to_schema_dict(EnterpriseResponse, x) for x in items]
    qtd = len(data)
    filtros = []
    if token:
        filtros.append(f"token {token[:8]}...")
    if nomeFantasia:
        filtros.append(f"nome fantasia contendo '{nomeFantasia}'")
    sufixo = f" com filtros: {', '.join(filtros)}" if filtros else ""
    if qtd == 0:
        message = f"Nenhuma empresa encontrada{sufixo}"
    elif qtd == 1:
        message = f"1 empresa encontrada{sufixo}"
    else:
        message = f"{qtd} empresas encontradas{sufixo}"
    return build_success_payload(data=data, message=message)


@router.put(
    "/{empresa_id}",
    summary="Atualizar empresa",
    description="""
Atualiza dados da empresa pelo ID. Requer token válido.

Exemplo cURL:

```bash
curl -X PUT 'https://api.seu-dominio.com/empresas/id}' \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"nomeFantasia":"Acme Tech"}'
```

Alternativa usando X-Enterprise-Token:

```bash
curl -X PUT 'https://api.seu-dominio.com/empresas/id}' \
  -H 'X-Enterprise-Token: <TOKEN_EMPRESA>' \
  -H 'Content-Type: application/json' \
  -d '{"nomeFantasia":"Acme Tech"}'
```
""",
    response_model=SuccessResponse,
    responses={
        200:
            {
                "description": "Empresa atualizada com sucesso"
            },
        400:
            {
                "description": "Violação de constraint ou dados inválidos",
                "model": ErrorResponse
            },
        401:
            {
                "description": "Credenciais inválidas ou ausentes",
                "model": ErrorResponse
            },
        404:
            {
                "description": "Empresa não encontrada",
                "model": ErrorResponse
            },
        500:
            {
                "description": "Erro interno",
                "model": ErrorResponse
            },
    },
    openapi_extra={
        "requestBody": {
            "content": {
                "application/json": {
                    "examples": {"nomeFantasia": "Acme Tech"}
                }
            }
        },
        "responses": {
            "200": {
                "content": {
                    "application/json": {
                        "examples": {
                            "message": "Empresa atualizada com sucesso",
                            "data": {
                                    "id": "id",
                                    "cnpj": "12.345.678/0001-90",
                                    "razaoSocial": "Acme Ltda",
                                    "nomeFantasia": "Acme Tech"
                                },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            },
            "400": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "VALIDATION_ERROR",
                                "message": "Dados inválidos"
                            },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            },
            "401": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "AUTH_ERROR",
                                "message": "Credenciais inválidas"
                            },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            },
            "404": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "NOT_FOUND",
                                "message": "Empresa '...'' não encontrada"
                            },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            },
            "500": {
                "content": {
                    "application/json": {
                        "examples": {
                            "error": {
                                "code": "INTERNAL_SERVER_ERROR",
                                "message": "Erro inesperado"
                            },
                            "timestamp": "2025-01-01T12:00:00Z"
                        }
                    }
                }
            }
        }
    }
)
async def atualizar_empresa(
    empresa_id: str,
    payload: EnterpriseUpdate,
    db: AsyncSession = Depends(get_db),
):
    try:
        obj = await EmpresaService.atualizar(db, empresa_id, payload)
    except IntegrityError as e:
        raise HTTPException(
            status_code=400,
            detail="Violação de constraint ao atualizar empresa"
        ) from e
    if not obj:
        raise HTTPException(
            status_code=404,
            detail=f"Empresa '{empresa_id}' não encontrada"
        )
    data = to_schema_dict(EnterpriseResponse, obj)
    message = f"Empresa atualizada com sucesso (ID: {data.get('id')})"
    return build_success_payload(data=data, message=message)


@router.delete(
    "/{empresa_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Excluir empresa",
    description="""
Remove a empresa informada por ID. Requer token válido.

Exemplo cURL:

```bash
curl -X DELETE 'https://api.seu-dominio.com/empresas/id}' \
  -H 'Authorization: Bearer <TOKEN>'
```

Usando X-Enterprise-Token:

```bash
curl -X DELETE 'https://api.seu-dominio.com/empresas/id}' \
  -H 'X-Enterprise-Token: <TOKEN_EMPRESA>'
```
""",
    responses={
        204: {"description": "Empresa excluída"},
        401: {"description": "Credenciais inválidas", "model": ErrorResponse},
        404: {"description": "Empresa não encontrada", "model": ErrorResponse},
        500: {"description": "Erro interno", "model": ErrorResponse},
    },
    openapi_extra={
        "responses":
            {
                "401": {
                    "content": {
                        "application/json": {
                            "examples": {
                                "error": {
                                    "code": "AUTH_ERROR",
                                    "message": "Credenciais inválidas"
                                },
                                "timestamp": "2025-01-01T12:00:00Z"
                            }
                        }
                    }
                },
                "404": {
                    "content": {
                        "application/json": {
                            "examples": {
                                "error": {
                                    "code": "NOT_FOUND",
                                    "message": "Empresa '...'' não encontrada"
                                },
                                "timestamp": "2025-01-01T12:00:00Z"
                            }
                        }
                    }
                },
                "500": {
                    "content": {
                        "application/json": {
                            "examples": {
                                "error": {
                                    "code": "INTERNAL_SERVER_ERROR",
                                    "message": "Erro inesperado"
                                },
                                "timestamp": "2025-01-01T12:00:00Z"
                            }
                        }
                    }
                }
            }
    }
)
async def excluir_empresa(
    empresa_id: str,
    db: AsyncSession = Depends(get_db),
):
    ok = await EmpresaService.deletar(db, empresa_id)
    if not ok:
        raise HTTPException(
            status_code=404,
            detail=f"Empresa '{empresa_id}' não encontrada"
        )
    return None
