<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;

use Illuminate\Bus\Batchable;  // <-- agregar este use
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Services\CloudflareR2Service;
use App\Models\Document;
use App\Models\TraceDocument;
use App\Models\SealDoc;
use setasign\Fpdi\Tcpdf\Fpdi;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Carbon\Carbon;

class FirmarDocumentoPDF implements ShouldQueue
{
    use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $timeout = 120;
    public $tries   = 2;

    protected $idDocument;
    protected $uuid;
    protected $fkUser;
    protected $fkFlow;
    protected $certData; // ['cert' => ..., 'pkey' => ...]
    protected $ipAddress;   // ← agregar
    protected $userAgent;   // ← agregar
    protected $browser;     // ← agregar
    protected $platform;    // ← agregar

    public function __construct($idDocument, $uuid, $fkUser, $fkFlow, $certData, $ipAddress = null, $userAgent = null, $browser = null, $platform = null)
    {
        $this->idDocument = $idDocument;
        $this->uuid       = $uuid;
        $this->fkUser     = $fkUser;
        $this->fkFlow     = $fkFlow;
        $this->certData   = $certData;
    $this->ipAddress  = $ipAddress;   // ← agregar
    $this->userAgent  = $userAgent;   // ← agregar
    $this->browser    = $browser;     // ← agregar
    $this->platform   = $platform;
    }

    public function handle()
    {
        $r2Service  = new CloudflareR2Service();
        $tempInput  = storage_path('app/temp/' . $this->uuid . '.pdf');
        $outputFile = storage_path('app/temp/' . $this->uuid . '_firmado.pdf');

        if (!file_exists(storage_path('app/temp'))) {
            mkdir(storage_path('app/temp'), 0755, true);
        }

        try {
            // 1. DESCARGAR de R2
            $r2Service->descargarArchivo(
                'documentorigin/' . $this->uuid . '.pdf',
                $tempInput
            );

            $code     = Str::random(12);
            $codelink = Str::random(40);
            $date     = Carbon::now()->format('d/m/Y H:i:s');
            $date2    = Carbon::now()->format('Y-m-d H:i:s');

            // Crear cert y key temporales
            $tempCert = storage_path('app/temp/cert_' . uniqid() . '.crt');
            $tempKey  = storage_path('app/temp/key_'  . uniqid() . '.key');
            file_put_contents($tempCert, $this->certData['cert']);
            file_put_contents($tempKey,  $this->certData['pkey']);

            // 2. FIRMAR segun el flujo
            if ($this->fkFlow == 2 || $this->fkFlow == 5) {
                $this->firmarFlujo2($tempInput, $outputFile, $tempCert, $tempKey, $code, $codelink, $date, $date2);
            } else {
                $this->firmarFlujoDefault($tempInput, $outputFile, $tempCert, $tempKey, $code, $codelink, $date, $date2);
            }

            // 3. SUBIR firmado a R2
           $r2Result = $r2Service->subirArchivoLocal(
                'documentsign/' . $this->uuid . '.pdf',
                $outputFile
            );

            // 4. ACTUALIZAR base de datos
           // $publicUrl = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
            $document = Document::find($this->idDocument);
            $document->fk_progres = 2;
            $document->code_print = $code;
            $document->code_link  = $codelink;
            $document->pathpdf    = $r2Result['url'];
            $document->save();

            TraceDocument::create([
                'fk_tracetype' => 4,
                'fk_document'  => $this->idDocument,
                'fk_user'      => $this->fkUser,
                'date_create'  => $date2,
                    'ip_address'   => $this->ipAddress,   // ← agregar
             'user_agent'   => $this->userAgent,   // ← agregar
          'browser'      => $this->browser,     // ← agregar
           'platform'     => $this->platform,
            ]);

            // 5. LIMPIAR temporales
            @unlink($tempInput);
            @unlink($outputFile);
            @unlink($tempCert);
            @unlink($tempKey);

            Log::info("Documento firmado y subido a R2", [
                'id'   => $this->idDocument,
                'uuid' => $this->uuid
            ]);

        } catch (\Exception $e) {
            @unlink($tempInput);
            @unlink($outputFile);
            Log::error("Error firmando documento", [
                'id'    => $this->idDocument,
                'uuid'  => $this->uuid,
                'error' => $e->getMessage()
            ]);
            throw $e;
        }
    }

    // FLUJO 2: sellos personalizados  
    private function firmarFlujo2($file, $outputFile, $tempCert, $tempKey, $code, $codelink, $date, $date2)
    {
     //   $fpdi  = new Fpdi();
         $fpdi = new Fpdi('P', 'pt'); 
        $count = $fpdi->setSourceFile($file);

        $style = $this->getQrStyle();

        for ($i = 1; $i <= $count; $i++) {
            $template = $fpdi->importPage($i);
            $size     = $fpdi->getTemplateSize($template);
            $fpdi->SetPrintHeader(false);
            $fpdi->SetPrintFooter(false);
            $fpdi->AddPage($size['orientation'], [$size['width'], $size['height']]);
            $fpdi->useTemplate($template);
            $fpdi->SetAutoPageBreak(true, 0);

            $sealDocs = SealDoc::where('fk_iddoc', $this->idDocument)->get();

            foreach ($sealDocs as $sealDoc) {
                // Imagen con texto
                if ($sealDoc->type == 3) {
                    $pathimg = Storage::disk('public')->path('/pdfadd/' . $sealDoc->path . '.png');
                    $fpdi->Image($pathimg, $sealDoc->ejeX, $sealDoc->ejeY, $sealDoc->witch, $sealDoc->height, 'PNG', '', '', false,false, '', false, false, 0, false, false, false);
                    $fpdi->SetFont("Times", "", 9);
                    $fpdi->SetTextColor(95, 127, 236);
                    $fpdi->Text(intval($sealDoc->ejeX + 50), intval($sealDoc->ejeY + 6),  $count);
                    $fpdi->Text(intval($sealDoc->ejeX + 30), intval($sealDoc->ejeY + 14), $date2);
                }

                // Sello imagen
                if ($sealDoc->type == 2) {
                    $pathimg = Storage::disk('public')->path('/pdfadd/' . $sealDoc->path . '.png');
                    $w =  $sealDoc->witch;
                    $h = $sealDoc->height;
    
                    $fpdi->Image($pathimg, $sealDoc->ejeX, $sealDoc->ejeY, $w, $h, 'PNG', '', '', false, false, '', false, false, 0, false, false, false);
                }

                // QR
                  if ($sealDoc->type == 1) {
                 $qrW = $sealDoc->witch ?? 60;
                 $qrH = $sealDoc->height ?? 60;
    
                  // El QR ocupa ~70% del alto total
                 // $qrSize = $qrW * 0.70;
                    $qrSize=50;
    
              $fpdi->write2DBarcode(
                        'https://document.fasttek.com.pe/verify/#/' . $codelink, 
                     'QRCODE,H', 
                 $sealDoc->ejeX, 
                 $sealDoc->ejeY, 
                     $qrSize,
                     $qrSize,
                  $style, 
                  'N'
                  );
     // Todo basado en $qrSize para que sea proporcional
    $fontSize = max(4, intval($qrSize * 0.10));
    $lineH    = $qrSize * 0.12;
    $textStartY = $sealDoc->ejeY + $qrSize + 1;
    
    $fpdi->SetFont("Times", "", $fontSize);
    $fpdi->SetTextColor(0, 0, 0);
    
    $fpdi->Text($sealDoc->ejeX, $textStartY,              'document.fasttek.com.pe/verify');
    $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH,     'codigo: ' . $code);
    $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 2, 'FIRMADO DIGITALMENTE POR');
    
    if ($this->fkUser == 24) {
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 3, 'Asterio Francisco Carbajal Rojas');
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 4, 'abogado CIP: 64028');
    } elseif ($this->fkUser == 35) {
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 3, 'RICARDO FERNANDINI PINTO');
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 4, 'COMPOSTELA E.I.R.L');
    } else {
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 3, 'RICARDO FERNANDINI BARREDA');
        $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 4, 'NOTARIO DE LIMA');
    }
    $fpdi->Text($sealDoc->ejeX, $textStartY + $lineH * 5, $date);
}}
        }

        $fpdi->setSignature('file://' . $tempCert, 'file://' . $tempKey, '', '', 2, '', 'A');
        $fpdi->setSignatureAppearance(10, 245, 35, 35);
        $fpdi->Output($outputFile, 'F');
    }

    // FLUJO DEFAULT (1, 3, 4 y usuarios especiales)  
    private function firmarFlujoDefault($file, $outputFile, $tempCert, $tempKey, $code, $codelink, $date, $date2)
    {
        $fpdi  = new Fpdi();
        $count = $fpdi->setSourceFile($file);

        for ($i = 1; $i <= $count; $i++) {
            $template = $fpdi->importPage($i);
            $size     = $fpdi->getTemplateSize($template);
            $fpdi->SetPrintHeader(false);
            $fpdi->SetPrintFooter(false);
            $fpdi->AddPage($size['orientation'], [$size['width'], $size['height']]);
            $fpdi->useTemplate($template);
        }

        // Seleccionar plantilla segun flujo y usuario
        $file2 = $this->getPlantilla();
        $count = $fpdi->setSourceFile($file2);

        $style = $this->getQrStyle();
        $date  = Carbon::now()->format('d/m/Y H:i');

        for ($i = 1; $i <= $count; $i++) {
            $template = $fpdi->importPage($i);
            $size     = $fpdi->getTemplateSize($template);
            $fpdi->SetPrintHeader(false);
            $fpdi->SetPrintFooter(false);
            $fpdi->AddPage($size['orientation'], [$size['width'], $size['height']]);
            $fpdi->useTemplate($template);
            $fpdi->SetAutoPageBreak(true, 0);

            $left = 45;
            $top  = ($this->fkUser == 47 || $this->fkUser == 49) ? 142 : 105;

            $fpdi->SetFont("Times", "", 12);
            $fpdi->SetTextColor(0, 0, 0);
            $fpdi->Text($left, $top, $date);

            $fpdi->write2DBarcode('https://document.fasttek.com.pe/verify/#/' . $codelink, 'QRCODE,H', 10, 242, 35, 35, $style, 'N');
            $fpdi->SetFont("dejavusans", "", 8);
            $fpdi->Text(11, 276, 'document.fasttek.com.pe/verify');
            $fpdi->Text(11, 280, 'FIRMADO DIGITALMENTE');
            $fpdi->Text(11, 283, 'codigo: ' . $code);

            $fpdi->setSignature('file://' . $tempCert, 'file://' . $tempKey, '', '', 2, '', 'A');
            $fpdi->setSignatureAppearance(10, 245, 35, 35);
        }

        $fpdi->Output($outputFile, 'F');
    }

    
    private function getPlantilla()
    {
        $map = [
            47 => 'rosalia_nuevo',
            49 => 'mariaperez',
            63 => 'edgardo',
        ];

        if (isset($map[$this->fkUser])) {
            return Storage::disk('public')->path('/pdfadd/' . $map[$this->fkUser] . '.pdf');
        }

        $flowMap = [
            1 => 'bancos',
            3 => 'clientecalle',
            4 => 'testimonio_rrpp',
        ];

        $nombre = $flowMap[$this->fkFlow] ?? 'bancos';
        return Storage::disk('public')->path('/pdfadd/' . $nombre . '.pdf');
    }

    private function getQrStyle()
    {
        return [
            'border'        => false,
            'vpadding'      => 'auto',
            'hpadding'      => 'auto',
            'fgcolor'       => [0, 0, 0],
            'bgcolor'       => false,
            'module_width'  => 1,
            'module_height' => 1,
        ];
    }
}