<?php

namespace App\Http\Controllers\Api\Hacienda;

use App\Data\ClaveDto;
use App\Http\Attributes\CurrentBranch;
use App\Http\Attributes\CurrentClient;
use App\Services\DocumentoService;

use Illuminate\Http\JsonResponse;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Documents\AddCliente;
use App\Http\Requests\Documents\AddDocRequest;
use App\Http\Requests\Documents\AddCredentials;
use App\Http\Requests\Documents\CreateSucursal;
use App\Http\Requests\Documents\EliminarSucursal;
use App\Http\Requests\Documents\UpdateSucursal;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\Response;

use function PHPSTORM_META\map;

class DocumentoController extends ApiController
{
    public function __construct(
        protected DocumentoService $service
    ) {}

    public function agregarCliente(AddCliente $request): JsonResponse
    {      
        $addCliente = $this->service->agregarCliente($request->validated());
        return response()->json($addCliente, 201);
    }

    public function actualizarSucursal(UpdateSucursal $request, #[CurrentClient] object $cliente)
    {
        $result = $this->service->updateSucursal(
            $request->validated(), 
            $cliente->id, 
            $request->route('sucursalId')
        );

        return response()->json($result);
    }

    public function agregarSucursal(CreateSucursal $request, #[CurrentClient] object $cliente)
    {
        $result = $this->service->crearSucursal(
            $request->validated(), 
            $cliente->id
        );

        return response()->json($result);
    }

    public function agregarSucursalApiKey(string $sucursalId, #[CurrentClient] object $cliente)
    {
        $result = $this->service->crearSucursalApiKey(
            $cliente->id,
            $sucursalId
        );

        return response()->json($result);
    }

    public function consultarSucursalApiKeys(string $sucursalId, #[CurrentClient] object $cliente)
    {
        return response()->json($this->service->getSucursalApiKeys(
            $cliente->id,
            $sucursalId
        ));
    }

    public function eliminarSucursal(EliminarSucursal $request, #[CurrentClient] object $cliente)
    {
        $result = $this->service->deleteSucursal(
            $request->route('sucursalId'), 
            $cliente->id
        );

        return response()->json($result);
    }

    public function consultarSucursalesCliente(#[CurrentClient] object $cliente) 
    {
        return response()->json($this->service->getSucursalesByClient($cliente->id));
    }

    public function consultarDocumentosCliente(#[CurrentClient] object $cliente)
    {
        return response()->json($this->service->getDocsByClient($cliente->id));
    }

    public function consultarDocumentosPendientes(): JsonResponse    
    {
        $claves = DB::table('documentos')
            ->where('status', 'enviado')
            ->pluck('clave');

        return response()->json([
            'message' => "Verificando estado de {$claves->count()} documentos pendientes", 
        ]);
    }

    public function descargarFirmadoXml(ClaveDto $request)
    {
        $doc = $this->service->getDocumentByClave($request->clave);

        if (!$doc->xml_firmado) {
            throw new NotFoundHttpException(\sprintf('No se ha encontrado un XML de la clave "%s"', $request->clave));
        }

        $disposition = HeaderUtils::makeDisposition(
            HeaderUtils::DISPOSITION_ATTACHMENT,
            "{$doc->clave}.xml"
        );

        $response = new Response(base64_decode($doc->xml_firmado));
        $response->headers->set('Content-Disposition', $disposition);
        $response->headers->set('Content-Type', 'application/xml');

        return $response;
    }

    public function descargarRespuestaXml(ClaveDto $request)
    {
        $doc = $this->service->getDocumentByClave($request->clave);

        if (!$doc->xml_respuesta) {
            throw new NotFoundHttpException(\sprintf('No se ha encontrado un XML Respuesta para la clave "%s"', $request->clave));
        }

        $disposition = HeaderUtils::makeDisposition(
            HeaderUtils::DISPOSITION_ATTACHMENT,
            "{$doc->clave}_respuesta.xml"
        );

        $response = new Response(base64_decode($doc->xml_respuesta));
        $response->headers->set('Content-Disposition', $disposition);
        $response->headers->set('Content-Type', 'application/xml');

        return $response;
    }

    public function consultarEstadoDocumento(ClaveDto $request, #[CurrentBranch] array $mh_credenciales): JsonResponse 
    {
        return response()->json($this->service->getDocumentStatus($request->clave, $mh_credenciales['client_id']));
    }

    public function agregarDocumento(AddDocRequest $request, #[CurrentBranch] array $mh_credenciales): JsonResponse 
    {
        return response()->json($this->service->addDocumento($mh_credenciales, $request->validated()));
    }

    public function agregarCredenciales(AddCredentials $request, #[CurrentClient] object $cliente): JsonResponse  
    {
        $this->service->addCredentials($request->validated(), $cliente->id);
        return response()->json(null, 201);
    }

}