from __future__ import annotations

from typing import Any, Dict
from json import JSONDecodeError
from fastapi import APIRouter, Body, Depends, status, Request, HTTPException

from src.core.deps import get_mercadopago_service
from src.modules.pagamentos.mercadopago_service import (
    MercadoPagoService,
    MercadoPagoPreferenceRequest,
    MercadoPagoPreferenceResponse,
    MercadoPagoSplitPreferenceRequest,
)

router = APIRouter(prefix="/mercadopago", tags=["Mercado Pago"])


MERCADOPAGO_WEBHOOK_EXAMPLE: Dict[str, Any] = {
    "id": 1234567890,
    "live_mode": True,
    "type": "payment",
    "date_created": "2015-03-25T10:04:58.396-04:00",
    "user_id": 44444,
    "api_version": "v1",
    "action": "payment.created",
    "data": {
        "id": "999999999"
    }
}


@router.post(
    "/preference",
    summary="Criar preferência de pagamento",
    description="Cria uma preferência de pagamento no Mercado Pago para processar transações.",
    response_model=MercadoPagoPreferenceResponse,
    status_code=status.HTTP_201_CREATED,
    responses={
        status.HTTP_201_CREATED: {
            "description": "Preferência criada com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "id": "123456789-abcd-efgh-ijkl-123456789012",
                        "init_point": "https://www.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012",
                        "sandbox_init_point": "https://sandbox.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012",
                        "collector_id": 123456789,
                        "client_id": "1234567890123456",
                        "date_created": "2025-01-01T12:00:00.000-04:00",
                        "last_updated": "2025-01-01T12:00:00.000-04:00"
                    }
                }
            },
        },
        status.HTTP_400_BAD_REQUEST: {
            "description": "Dados inválidos para criação da preferência",
            "content": {"application/json": {"example": {"detail": "Items são obrigatórios."}}},
        },
    },
)
async def create_mercadopago_preference(
    preference_data: MercadoPagoPreferenceRequest,
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> MercadoPagoPreferenceResponse:
    """Criar uma preferência de pagamento no Mercado Pago."""
    try:
        preference = await mp_service.create_preference(preference_data)
        return preference
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Erro ao criar preferência: {str(e)}"
        )


@router.post(
    "/split/preference",
    summary="Criar preferência de pagamento com split",
    description=(
        "Cria uma preferência do Mercado Pago pronta para efetuar split de pagamentos "
        "entre múltiplos recebedores."
    ),
    response_model=MercadoPagoPreferenceResponse,
    status_code=status.HTTP_201_CREATED,
)
async def create_mercadopago_split_preference_public(
    preference_data: MercadoPagoSplitPreferenceRequest,
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> MercadoPagoPreferenceResponse:
    """Criar uma preferência de pagamento com regras de split."""
    try:
        preference = await mp_service.create_split_preference(preference_data)
        return preference
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Erro ao criar preferência com split: {str(e)}"
        )


@router.post(
    "/webhook",
    summary="Webhook do Mercado Pago",
    description="Endpoint para receber notificações de pagamento do Mercado Pago.",
    status_code=status.HTTP_200_OK,
    responses={
        status.HTTP_200_OK: {
            "description": "Webhook processado com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "status": "processed",
                        "payment_id": "123456789",
                        "external_reference": "pedido_123"
                    }
                }
            },
        },
        status.HTTP_400_BAD_REQUEST: {
            "description": "Webhook inválido",
            "content": {"application/json": {"example": {"detail": "Dados do webhook inválidos."}}},
        },
    },
)
async def mercadopago_webhook(
    request: Request,
    payload: Dict[str, Any] | None = Body(
        default=None,
        example=MERCADOPAGO_WEBHOOK_EXAMPLE,
        description=(
            "Payload padrão enviado pelo Mercado Pago em notificações webhook. "
            "Consulte a documentação oficial para detalhes completos."
        ),
    ),
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """Processar webhook do Mercado Pago."""
    try:
        webhook_data: Dict[str, Any] = payload or {}

        if not webhook_data:
            try:
                webhook_data = await request.json()
            except JSONDecodeError:
                # Corpo vazio ou inválido – segue para tentar montar a partir dos parâmetros
                webhook_data = {}

        if not webhook_data:
            # Mercado Pago pode enviar dados via query params (topic, type, id)
            query_params = dict(request.query_params)
            if query_params:
                webhook_type = query_params.get("type") or query_params.get("topic")
                data_id = (
                    query_params.get("data.id")
                    or query_params.get("id")
                    or query_params.get("resource")
                )
                if webhook_type or data_id:
                    webhook_data = {
                        "type": webhook_type,
                        "data": {"id": data_id} if data_id else {},
                    }

        if not webhook_data:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Dados do webhook ausentes ou inválidos.",
            )

        # Processar webhook
        result = await mp_service.process_webhook(webhook_data)
        
        return {
            "status": "processed",
            "payment_id": result.get("payment_id"),
            "external_reference": result.get("external_reference")
        }
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Erro ao processar webhook: {str(e)}"
        )


@router.get(
    "/payment/{payment_id}",
    summary="Buscar pagamento no Mercado Pago",
    description="Busca informações detalhadas de um pagamento específico no Mercado Pago.",
    responses={
        status.HTTP_200_OK: {
            "description": "Dados do pagamento",
            "content": {
                "application/json": {
                    "example": {
                        "id": 123456789,
                        "status": "approved",
                        "transaction_amount": 100.0,
                        "payment_method_id": "pix",
                        "external_reference": "pedido_123"
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Pagamento não encontrado",
            "content": {"application/json": {"example": {"detail": "Pagamento não encontrado."}}},
        },
    },
)
async def get_mercadopago_payment(
    payment_id: int,
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """Buscar informações de um pagamento específico no Mercado Pago."""
    try:
        payment = await mp_service.get_payment(payment_id)
        return payment
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Pagamento não encontrado: {str(e)}"
        )


@router.get(
    "/payment/by-reference/{external_reference}",
    summary="Buscar pagamentos por external_reference",
    description="Busca pagamentos no Mercado Pago usando a referência externa. Útil para fazer polling e detectar quando o pagamento PIX é aprovado. Retorna o pagamento mais recente primeiro.",
    responses={
        status.HTTP_200_OK: {
            "description": "Status do pagamento",
            "content": {
                "application/json": {
                    "example": {
                        "has_payment": True,
                        "latest_payment": {
                            "id": 123456789,
                            "status": "approved",
                            "transaction_amount": 100.0,
                            "payment_method_id": "pix",
                            "external_reference": "pedido_123"
                        },
                        "is_approved": True,
                        "count": 1
                    }
                }
            },
        },
    },
)
async def get_mercadopago_payments_by_reference(
    external_reference: str,
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """
    Buscar pagamentos por external_reference. 
    Útil para verificar status do pagamento e fazer polling.
    Retorna o pagamento mais recente e indica se está aprovado.
    """
    try:
        payments = await mp_service.search_payments_by_reference(external_reference)
        
        if not payments:
            return {
                "has_payment": False,
                "latest_payment": None,
                "is_approved": False,
                "count": 0,
                "message": "Nenhum pagamento encontrado para esta referência"
            }
        
        # Pega o pagamento mais recente (já vem ordenado por data)
        latest_payment = payments[0]
        latest_dict = latest_payment.model_dump(exclude_none=True)
        
        return {
            "has_payment": True,
            "latest_payment": latest_dict,
            "is_approved": latest_payment.status == "approved",
            "status": latest_payment.status,
            "count": len(payments),
            "all_payments": [p.model_dump(exclude_none=True) for p in payments] if len(payments) > 1 else None
        }
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Erro ao buscar pagamentos: {str(e)}"
        )


@router.post(
    "/preference/simple",
    summary="Criar preferência simples para teste",
    description="Cria uma preferência de pagamento simples com dados mínimos para teste.",
    responses={
        status.HTTP_200_OK: {
            "description": "Preferência criada com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "status": "success",
                        "preference_id": "123456789-abcd-efgh-ijkl-123456789012",
                        "init_point": "https://www.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012",
                        "sandbox_init_point": "https://sandbox.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012"
                    }
                }
            },
        },
    },
)
async def create_simple_preference(
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """Criar uma preferência simples para teste."""
    try:
        from datetime import datetime
        
        # Dados mínimos para teste
        simple_data = MercadoPagoPreferenceRequest(
            items=[
                {
                    "id": "test_item_1",
                    "title": "Produto de Teste",
                    "quantity": 1,
                    "unit_price": 10.0,
                    "currency_id": "BRL"
                }
            ],
            payer={
                "email": "test_user_123456@testuser.com"  # Email de teste válido
            },
            back_urls={
                "success": "http://localhost:3000/success",
                "failure": "http://localhost:3000/failure", 
                "pending": "http://localhost:3000/pending"
            },
            auto_return="approved",
            external_reference="test_ref_" + str(int(datetime.now().timestamp()))
        )
        
        preference = await mp_service.create_preference(simple_data)
        return {
            "status": "success",
            "preference_id": preference.id,
            "init_point": preference.init_point,
            "sandbox_init_point": preference.sandbox_init_point
        }
    except Exception as e:
        return {
            "status": "error",
            "message": f"Erro ao criar preferência: {str(e)}"
        }


@router.post(
    "/preference/mock",
    summary="Criar preferência simulada",
    description="Cria uma preferência de pagamento simulada para demonstração.",
    responses={
        status.HTTP_200_OK: {
            "description": "Preferência simulada criada com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "status": "success",
                        "preference_id": "123456789-abcd-efgh-ijkl-123456789012",
                        "init_point": "https://www.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012",
                        "sandbox_init_point": "https://sandbox.mercadopago.com.br/checkout/v1/redirect?pref_id=123456789-abcd-efgh-ijkl-123456789012"
                    }
                }
            },
        },
    },
)
async def create_mock_preference() -> Dict[str, Any]:
    """Criar uma preferência simulada para demonstração."""
    try:
        from datetime import datetime
        import uuid
        
        # Simular resposta do Mercado Pago
        mock_preference_id = str(uuid.uuid4())
        
        return {
            "status": "success",
            "message": "Preferência simulada criada com sucesso",
            "preference_id": mock_preference_id,
            "init_point": f"https://www.mercadopago.com.br/checkout/v1/redirect?pref_id={mock_preference_id}",
            "sandbox_init_point": f"https://sandbox.mercadopago.com.br/checkout/v1/redirect?pref_id={mock_preference_id}",
            "collector_id": 123456789,
            "client_id": "test_client_id",
            "date_created": datetime.now().isoformat(),
            "note": "Esta é uma resposta simulada. Para usar o Mercado Pago real, configure credenciais válidas."
        }
    except Exception as e:
        return {
            "status": "error",
            "message": f"Erro ao criar preferência simulada: {str(e)}"
        }


@router.post(
    "/webhook/mock",
    summary="Processar webhook simulado",
    description="Endpoint para processar webhooks simulados do Mercado Pago.",
    responses={
        status.HTTP_200_OK: {
            "description": "Webhook simulado processado com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "status": "success",
                        "message": "Webhook simulado processado com sucesso",
                        "processed_at": "2025-01-01T12:00:00.000000"
                    }
                }
            },
        },
    },
)
async def process_mock_webhook(
    request: Request,
) -> Dict[str, Any]:
    """Processar webhook simulado do Mercado Pago."""
    try:
        from datetime import datetime
        webhook_data = await request.json()
        
        # Simular processamento do webhook
        return {
            "status": "success",
            "message": "Webhook simulado processado com sucesso",
            "received_data": webhook_data,
            "processed_at": datetime.now().isoformat(),
            "note": "Este é um processamento simulado. Para usar webhooks reais, configure credenciais válidas."
        }
    except Exception as e:
        return {
            "status": "error",
            "message": f"Erro ao processar webhook simulado: {str(e)}"
        }


@router.get(
    "/debug",
    summary="Debug das configurações do Mercado Pago",
    description="Endpoint para verificar se as configurações do Mercado Pago estão carregadas corretamente.",
    responses={
        status.HTTP_200_OK: {
            "description": "Informações de debug das configurações",
            "content": {
                "application/json": {
                    "example": {
                        "access_token_configured": True,
                        "access_token_prefix": "APP_USR_12...",
                        "public_key_configured": True,
                        "sandbox_mode": True
                    }
                }
            },
        },
    },
)
async def debug_mercadopago_config(
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """Debug das configurações do Mercado Pago."""
    try:
        from src.core.config import get_settings
        settings = get_settings()
        
        return {
            "access_token_configured": bool(settings.mercado_pago_access_token),
            "access_token_prefix": settings.mercado_pago_access_token[:10] + "..." if settings.mercado_pago_access_token else "None",
            "public_key_configured": bool(settings.mercado_pago_public_key),
            "public_key_prefix": settings.mercado_pago_public_key[:10] + "..." if settings.mercado_pago_public_key else "None",
            "sandbox_mode": getattr(mp_service, 'sandbox', False),
            "service_access_token_prefix": mp_service.access_token[:10] + "..." if mp_service.access_token else "None"
        }
    except Exception as e:
        return {
            "error": f"Erro ao verificar configurações: {str(e)}"
        }


@router.get(
    "/test",
    summary="Testar credenciais do Mercado Pago",
    description="Endpoint para testar se as credenciais do Mercado Pago estão funcionando corretamente.",
    responses={
        status.HTTP_200_OK: {
            "description": "Resultado do teste de credenciais",
            "content": {
                "application/json": {
                    "example": {
                        "status": "success",
                        "message": "Credenciais do Mercado Pago estão funcionando",
                        "sandbox_mode": True
                    }
                }
            },
        },
    },
)
async def test_mercadopago_credentials(
    mp_service: MercadoPagoService = Depends(get_mercadopago_service),
) -> Dict[str, Any]:
    """Testar credenciais do Mercado Pago."""
    try:
        # Teste simples para verificar se as credenciais estão funcionando
        import mercadopago
        
        # Inicializar SDK com as credenciais
        sdk = mercadopago.SDK(mp_service.access_token)
        
        # Fazer uma requisição simples para testar as credenciais
        response = sdk.user().get()
        
        return {
            "status": "success",
            "message": "Credenciais do Mercado Pago estão funcionando",
            "sandbox_mode": getattr(mp_service, 'sandbox', False),
            "response_status": response.get("status", "unknown")
        }
    except Exception as e:
        return {
            "status": "error",
            "message": f"Erro ao testar credenciais: {str(e)}",
            "sandbox_mode": getattr(mp_service, 'sandbox', False)
        }