<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\Storage;
use App\Models\Document;
use App\Models\TraceDocument;
use App\Models\UserToken;
use App\Models\Usuario;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Validator;
use App\Jobs\FirmarDocumentoPDF;
use Illuminate\Support\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use DB;
use ZipArchive;
use Illuminate\Support\Fluent;
use Illuminate\Support\Facades\File;
use LSNepomuceno\LaravelA1PdfSign\{ManageCert, SealImage, SignaturePdf};
use LSNepomuceno\LaravelA1PdfSign\ValidatePdfSignature;
//use setasign\Fpdi\Fpdi;
use setasign\Fpdi\Tcpdf\Fpdi;
use Illuminate\Support\Str;
use App\Models\UserCertificate;
use Symfony\Component\Process\Process;
use App\Models\SealDoc;
use App\Helpers\NewQRCode;
use ddn\sapp\PDFDoc;
use App\Services\CloudflareR2Service;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

class DocumentController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }
    
    
      public function getDashboardStatistics(Request $request)
          {
            $startDate = $request->input('start_date', Carbon::now()->subMonths(2)->startOfMonth()->toDateString());
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->toDateString());
     
              // IDs de estado (ajusta según tu tabla fk_progres)
              $STATUS_PENDING = 1;
              $STATUS_SIGNED = 2;
     
             // Base query para el rango de fechas (sin filtrar removed aún para poder contar los rechazados)
             $baseQuery = DB::table('documents')
                ->whereBetween('datetime', [$startDate . ' 00:00:00', $endDate . ' 23:59:59']);
    
             // --- 1. Tarjetas de Resumen ---
             $total = (clone $baseQuery)->count();
             $firmados = (clone $baseQuery)->where('removed', 0)->where('fk_progres', $STATUS_SIGNED)->count();
             $pendientes = (clone $baseQuery)->where('removed', 0)->where('fk_progres', $STATUS_PENDING)->count();
             $rechazados = (clone $baseQuery)->where('removed', 1)->count(); // <--- Aquí usamos removed = 1
    
             // --- 2. Gráfico de Líneas (Evolución por día) ---
             $dailyDataRaw = (clone $baseQuery)
                 ->select(
                     DB::raw('DATE_FORMAT(datetime, "%d") as day'),
                     DB::raw('COUNT(*) as generados'),
                     DB::raw("SUM(CASE WHEN removed = 0 AND fk_status = $STATUS_SIGNED THEN 1 ELSE 0 END) as firmados")
                 )
                 ->groupBy('day')
                 ->orderBy('day', 'asc')
                 ->get();
    
            $lineData = $dailyDataRaw->map(function($item) {
                return [
                    'name' => $item->day,
                     'generados' => (int) $item->generados,
                    'firmados' => (int) $item->firmados,
                ];
});

             // --- 3. Gráfico de Donut (Estado Actual) ---
             $donutData = [
                 ['state' => 'firmados', 'value' => $firmados, 'fill' => 'var(--color-firmados)'],
                 ['state' => 'pendientes', 'value' => $pendientes, 'fill' => 'var(--color-pendientes)'],
                 ['state' => 'rechazados', 'value' => $rechazados, 'fill' => 'var(--color-rechazados)'],
             ];
    
             // --- 4. Efectividad por Usuario ---
            $userEffectivenessRaw = DB::table('documents')
                 ->join('usuarios', 'documents.fk_responsible', '=', 'usuarios.id_user')
                 ->whereBetween('documents.datetime', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
                ->select(
                    'usuarios.name as name',
                     DB::raw('COUNT(*) as enviados'),
                 DB::raw("SUM(CASE WHEN documents.removed = 0 AND documents.fk_progres = $STATUS_SIGNED THEN 1 ELSE 0
      END) as firmados"),
                     DB::raw("SUM(CASE WHEN documents.removed = 0 AND documents.fk_progres = $STATUS_PENDING THEN 1 ELSE
      0 END) as pendientes")
                )
                ->groupBy('usuarios.id_user', 'usuarios.name')
                ->orderBy('enviados', 'desc')
                ->limit(5)
                 ->get();
    
             $userEffectivenessData = $userEffectivenessRaw->map(function($item) {
                 return [
                     'name' => $item->name,
                     'enviados' => (int) $item->enviados,
                     'firmados' => (int) $item->firmados,
                     'pendientes' => (int) $item->pendientes,
                ];
             });
    
             // --- 5. Flujo de Documentos ---
             $flowColors = ['var(--color-firma_digital)', 'var(--color-testimonio_rrpp)',
      'var(--color-testimonio_modulo)', 'var(--color-testimonio_bancos)', 'var(--color-otros)'];
             $flowDataRaw = DB::table('documents')
                 ->join('flows', 'documents.fk_flow', '=', 'flows.id_flow')
                 ->whereBetween('documents.datetime', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
                 ->select('flows.description as flow_name', DB::raw('COUNT(*) as value'))
                 ->groupBy('flows.id_flow', 'flows.description')
                 ->orderBy('value', 'desc')
                 ->get();
    
             $flowDistributionData = $flowDataRaw->map(function($item, $index) use ($flowColors) {
                 return [
                     'flow' => strtolower(str_replace(' ', '_', $item->flow_name)),
                     'label' => $item->flow_name,
                    'value' => (int) $item->value,
                    'fill' => $flowColors[$index % count($flowColors)],
                 ];
             });
    
             // --- 6. Ranking de Áreas ---
             $companyRaw = DB::table('documents')
                 ->join('areadocuments', 'documents.fk_idareadoc', '=', 'areadocuments.id_areadoc')
                 ->whereBetween('documents.datetime', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
                 ->select('areadocuments.description as name', DB::raw('COUNT(*) as value'))
                ->groupBy('areadocuments.id_areadoc', 'areadocuments.description')
                 ->orderBy('value', 'desc')
                 ->limit(5)
                 ->get();
    
             $companyRanking = $companyRaw->map(function($item) {
                return ['name' => $item->name, 'value' => (int) $item->value];
            });
   
          // --- 7. Documentos Pendientes Críticos ---
            $pendingDocsRaw = DB::table('documents')
                ->leftJoin('usuarios', 'documents.fk_responsible', '=', 'usuarios.id_user')
                ->where('documents.removed', 0)
                ->where('documents.fk_progres', $STATUS_PENDING)
                ->orderBy('documents.datetime', 'asc')
                ->limit(5)
                ->select('documents.id_document as id', 'documents.subject as doc', 'usuarios.name as requester',
      'documents.datetime as date')
                ->get();
   
            $pendingDocuments = $pendingDocsRaw->map(function($item) {
                return [
                  'id' => $item->id,
                  'doc' => $item->doc,
                'requester' => $item->requester ?? 'Desconocido',
                  'date' => Carbon::parse($item->date)->format('d/m/Y'),
                  'status' => 'Pendiente'
             ];
            });
            
            
            // --- 8. Tiempo Promedio de Firma ---
// Usamos tracedocument con fk_tracetype = 4 (firmado) como fecha real de firma
$avgSignTimeRaw = DB::table('documents')
    ->join('trace_documents', function($join) {
        $join->on('trace_documents.fk_document', '=', 'documents.id_document')
             ->where('trace_documents.fk_tracetype', '=', 4); // estado = firmado
    })
    ->whereBetween('documents.datetime', [$startDate . ' 00:00:00', $endDate . ' 23:59:59'])
    ->where('documents.removed', 0)
    ->where('documents.fk_progres', $STATUS_SIGNED)
    ->select(
        DB::raw('AVG(TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create)) as avg_hours'),
        DB::raw('MIN(TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create)) as min_hours'),
        DB::raw('MAX(TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create)) as max_hours'),
        DB::raw('COUNT(*) as total_signed'),
        DB::raw("SUM(CASE WHEN TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create) <= 4   THEN 1 ELSE 0 END) as rango_0_4h"),
        DB::raw("SUM(CASE WHEN TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create) BETWEEN 5  AND 24  THEN 1 ELSE 0 END) as rango_5_24h"),
        DB::raw("SUM(CASE WHEN TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create) BETWEEN 25 AND 72  THEN 1 ELSE 0 END) as rango_25_72h"),
        DB::raw("SUM(CASE WHEN TIMESTAMPDIFF(HOUR, documents.datetime, trace_documents.date_create) > 72   THEN 1 ELSE 0 END) as rango_mas_72h")
    )
    ->first();

$avgHours = round((float)($avgSignTimeRaw->avg_hours ?? 0), 1);

$signTimeData = [
    'avgHours'     => $avgHours,
    'avgFormatted' => $avgHours < 24
        ? $avgHours . 'h'
        : round($avgHours / 24, 1) . 'd',
    'minHours'     => (int)($avgSignTimeRaw->min_hours   ?? 0),
    'maxHours'     => (int)($avgSignTimeRaw->max_hours   ?? 0),
    'totalSigned'  => (int)($avgSignTimeRaw->total_signed ?? 0),
    'distribution' => [
        ['range' => '≤ 4h',   'value' => (int)($avgSignTimeRaw->rango_0_4h    ?? 0)],
        ['range' => '4–24h',  'value' => (int)($avgSignTimeRaw->rango_5_24h   ?? 0)],
        ['range' => '1–3d',   'value' => (int)($avgSignTimeRaw->rango_25_72h  ?? 0)],
        ['range' => '> 3d',   'value' => (int)($avgSignTimeRaw->rango_mas_72h ?? 0)],
    ],
];
  
          return response()->json([
              'success' => true,
             'data' => [
                  'summary' => [
                      'total' => $total,
                      'firmados' => $firmados,
                     'pendientes' => $pendientes,
                      'rechazados' => $rechazados,
                  ],
                  'lineData' => $lineData,
                  'donutData' => $donutData,
                  'userEffectivenessData' => $userEffectivenessData,
                  'flowDistributionData' => $flowDistributionData,
                  'companyRanking' => $companyRanking,
                    'pendingDocuments' => $pendingDocuments,
                    'signTimeData' => $signTimeData
              ]
          ]);
          }
     public function savetokenfirebase(Request $request){
        Storage::put('tokenfire.txt', $request->token);
        return  response()->json(['success' => true]);
    }
      public function readtokenfirebase(){
        $content=Storage::get('tokenfire.txt');
        return  response()->json(['success' => true,"token"=>$content]);
    }
    
    public function descargarPDF(Request $request)
    {
    $rules = [
        'uuid'  => 'required',
         
    ];
    $validator = Validator::make($request->all(), $rules);
    if ($validator->fails()) {
        return response()->json(['success' => false, 'error' => $validator->messages()]);
    }
  $usuario = $this->getAuthUser($request);
    //$usuario = UserToken::where('token', $request->token)->first();
    // if (!$usuario) {
    //     return response()->json(['success' => false, 'error' => 'Token no valido']);
    // }

    $document = Document::where('uuidpdf', $request->uuid)->first();
    if (!$document) {
        return response()->json(['success' => false, 'error' => 'Documento no encontrado']);
    }

    $tempPath = storage_path('app/temp/' . $request->uuid . '.pdf');

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

    try {
        $r2Service = new CloudflareR2Service();
        $r2Service->descargarArchivo('documentsign/' . $request->uuid . '.pdf', $tempPath);

        $base64 = base64_encode(file_get_contents($tempPath));
        @unlink($tempPath);
        
          $userAgent = $request->header('User-Agent');
   $clientIp = $request->input('client_ip');
  $ip = ($clientIp && filter_var($clientIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE))
    ? $clientIp
    : getRealIp();

    $browser  = 'Unknown';
    $platform = 'Unknown';

    if (str_contains($userAgent, 'Edg'))           $browser = 'Edge';
    elseif (str_contains($userAgent, 'Chrome'))    $browser = 'Chrome';
    elseif (str_contains($userAgent, 'Firefox'))   $browser = 'Firefox';
    elseif (str_contains($userAgent, 'Safari'))    $browser = 'Safari';

    if (str_contains($userAgent, 'Android'))       $platform = 'Android';
    elseif (str_contains($userAgent, 'iPhone') || str_contains($userAgent, 'iPad'))
                                                   $platform = 'iOS';
    elseif (str_contains($userAgent, 'Windows'))   $platform = 'Windows';
    elseif (str_contains($userAgent, 'Macintosh')) $platform = 'Mac';
    elseif (str_contains($userAgent, 'Linux'))     $platform = 'Linux';
    $date = Carbon::now()->format('Y-m-d H:i:s');    
        // Crear trace del documento
        TraceDocument::create([
            'fk_tracetype' => 3,
            'fk_document' => $document->id_document,
            'fk_user' => $request->iduser,
            'date_create' => $date,
            'ip_address'   => $ip,        // ← nuevo
            'user_agent'   => $userAgent, // ← nuevo
            'browser'      => $browser,   // ← nuevo
            'platform'     => $platform, 
            'latitude' =>$request->lat,
            'longitude' =>$request->long,
            
        ]);
        

        return response()->json([
            'success' => true,
            'pdf'     => $base64,
            'filename' => $request->uuid . '.pdf'
        ]);

    } catch (\Exception $e) {
        @unlink($tempPath);
        return response()->json([
            'success' => false,
            'error'   => 'Error al descargar: ' . $e->getMessage()
        ]);
    }
    }
    
    
    public function descargarPDFMasivo(Request $request)
{
    $rules = [
        'uuids'   => 'required|array|min:1|max:20',
        'uuids.*' => 'required|string',
    ];

    $validator = Validator::make($request->all(), $rules);
    if ($validator->fails()) {
        return response()->json(['success' => false, 'error' => $validator->messages()]);
    }

    $usuario = $this->getAuthUser($request);

    // Validar que todos los documentos existen en BD
    $documentos = Document::whereIn('uuidpdf', $request->uuids)->get()->keyBy('uuidpdf');

    $notFound = array_diff($request->uuids, $documentos->keys()->toArray());
    if (!empty($notFound)) {
        return response()->json([
            'success' => false,
            'error'   => 'Documentos no encontrados: ' . implode(', ', $notFound),
        ]);
    }

    $tempDir = storage_path('app/temp/bulk_' . Str::uuid());

    try {
        $r2Service = new CloudflareR2Service();

        // Construir keys de R2
         $keys = array_map(function($uuid) {
        return 'documentsign/' . $uuid . '.pdf';
         }, $request->uuids);

        // Descargar todos en paralelo
        $rutasLocales = $r2Service->descargarMultiplesArchivos($keys, $tempDir);

        // Comprimir en ZIP
        $zipPath = storage_path('app/temp/docs_' . Str::uuid() . '.zip');
        $zip     = new \ZipArchive();

        if ($zip->open($zipPath, \ZipArchive::CREATE) !== true) {
            throw new Exception("No se pudo crear el archivo ZIP");
        }

        foreach ($rutasLocales as $i => $ruta) {
            $nombreArchivo = $request->uuids[$i] . '.pdf';
            $zip->addFile($ruta, $nombreArchivo);
        }

        $zip->close();

        // Convertir ZIP a base64
        $base64 = base64_encode(file_get_contents($zipPath));

        return response()->json([
            'success'  => true,
            'zip'      => $base64,
            'filename' => 'documentos_' . Carbon::now()->format('Ymd_His') . '.zip',
            'total'    => count($rutasLocales),
        ]);

    } catch (Exception $e) {
        Log::error('Error en descarga masiva', ['error' => $e->getMessage()]);

        return response()->json([
            'success' => false,
            'error'   => $e->getMessage(),
        ]);
    } finally {
        // Limpiar siempre, haya error o no
        if (file_exists($tempDir)) {
            array_map('unlink', glob($tempDir . '/*'));
            rmdir($tempDir);
        }
        if (isset($zipPath) && file_exists($zipPath)) {
            @unlink($zipPath);
        }
    }
}
   
   public function firmarMasivo(Request $request)
{
    // Validar password y obtener certificado UNA sola vez
    $usercertificate = UserCertificate::where('fk_iduser', $request->fkuser)
                        ->orderBy('id_usercertificates', 'desc')
                        ->first();
    $pfxCertPrivado = Storage::disk('public')->path('/certificates/' . $usercertificate->name_certificate);
    $pfxContent     = file_get_contents($pfxCertPrivado . '.p12');
    $res            = [];
    $openSSL        = openssl_pkcs12_read($pfxContent, $res, $request->password);
    if (!$openSSL) {
        return response()->json(['success' => false, 'error' => 'Contraseña del certificado incorrecta']);
    }

    // ── Capturar IP y navegador AQUÍ (en el request, antes del Job) ──
    $userAgent = $request->header('User-Agent');
    $ip        = getRealIp();

    $browser  = 'Unknown';
    $platform = 'Unknown';

    if (str_contains($userAgent, 'Edg'))            $browser = 'Edge';
    elseif (str_contains($userAgent, 'Chrome'))     $browser = 'Chrome';
    elseif (str_contains($userAgent, 'Firefox'))    $browser = 'Firefox';
    elseif (str_contains($userAgent, 'Safari'))     $browser = 'Safari';

    if (str_contains($userAgent, 'Android'))        $platform = 'Android';
    elseif (str_contains($userAgent, 'iPhone') || str_contains($userAgent, 'iPad'))
                                                    $platform = 'iOS';
    elseif (str_contains($userAgent, 'Windows'))    $platform = 'Windows';
    elseif (str_contains($userAgent, 'Macintosh'))  $platform = 'Mac';
    elseif (str_contains($userAgent, 'Linux'))      $platform = 'Linux';
    // ─────────────────────────────────────────────────────────────────

    $documentos = Document::whereIn('id_document', $request->ids)->get();

    $jobs = $documentos->map(function ($doc) use ($request, $res, $ip, $userAgent, $browser, $platform) {
        return new FirmarDocumentoPDF(
            $doc->id_document,
            $doc->uuidpdf,
            $request->fkuser,
            $doc->fk_flow,
            $res,
            $ip,        // ← nuevo
            $userAgent, // ← nuevo
            $browser,   // ← nuevo
            $platform   // ← nuevo
        );
    })->toArray();

    $batch = Bus::batch($jobs)
        ->then(function (Batch $batch) {
            Log::info("Todos los PDFs firmados: {$batch->id}");
        })
        ->catch(function (Batch $batch, \Throwable $e) {
            Log::error("Error en batch: {$e->getMessage()}");
        })
        ->dispatch();

    return response()->json([
        'success'  => true,
        'batch_id' => $batch->id,
        'total'    => count($jobs)
    ]);

} 
    
//     public function firmarMasivo(Request $request)
// {
//     // Validar password y obtener certificado UNA sola vez
//     $usercertificate = UserCertificate::where('fk_iduser', $request->fkuser)
//                         ->orderBy('id_usercertificates', 'desc')
//                         ->first();

//     $pfxCertPrivado = Storage::disk('public')->path('/certificates/' . $usercertificate->name_certificate);
//     $pfxContent     = file_get_contents($pfxCertPrivado . '.p12');
//     $res            = [];
//     $openSSL        = openssl_pkcs12_read($pfxContent, $res, $request->password);

//     if (!$openSSL) {
//         return response()->json(['success' => false, 'error' => 'Contraseña del certificado incorrecta']);
//     }

//     $documentos = Document::whereIn('id_document', $request->ids)->get();

//     $jobs = $documentos->map(function ($doc) use ($request, $res) {
//         return new FirmarDocumentoPDF(
//             $doc->id_document,
//             $doc->uuidpdf,
//             $request->fkuser,
//             $doc->fk_flow,
//             $res  // ['cert' => ..., 'pkey' => ...]
//         );
//     })->toArray();

//     $batch = Bus::batch($jobs)
//         ->then(function (Batch $batch) {
//             Log::info("Todos los PDFs firmados: {$batch->id}");
//         })
//         ->catch(function (Batch $batch, \Throwable $e) {
//             Log::error("Error en batch: {$e->getMessage()}");
//         })
//         ->dispatch();

//     return response()->json([
//         'success'  => true,
//         'batch_id' => $batch->id,
//         'total'    => count($jobs)
//     ]);
// }

// Endpoint para consultar el progreso
// public function estadoBatch(string $batchId)
// {
//     $batch = Bus::findBatch($batchId);

//     return response()->json([
//         'total'      => $batch->totalJobs,
//         'pendientes' => $batch->pendingJobs,
//         'fallidos'   => $batch->failedJobs,
//         'completado' => $batch->finished(),
//         'progreso'   => $batch->progress(), // 0-100
//     ]);
// }
    
    
 public function deletedocumentv2(Request $request)
{
    $rules = [
        'idocument' => 'required',
    ];

    $input     = $request->only('idocument');
    $validator = Validator::make($input, $rules);
    if ($validator->fails()) {
        return response()->json(['success' => false, 'error' => $validator->messages()]);
    }
     
    $document = Document::where('id_document', $request->idocument)->first();
    
    if ($document) {
        $document->removed = 1;
        $document->save();
        return response()->json(['success' => true, 'data' => $document->subject]);
    } else {
        return response()->json(['success' => false, 'data' => $document]);
    }
}
        
    
 public function createdocR2(Request $request)
{
    $rules = [
        'fkresponsible' => 'required',
        'fksign' => 'required',
        'fkflow' => 'required',
        'fkareadoc' => 'required',
       // 'fkcompany' =>'required',
        'file' => 'required|file|mimes:pdf',  
        'subject' => 'required',
        'note' => '',
    ];

    $validator = Validator::make($request->all(), $rules);
    
    if ($validator->fails()) {
        return response()->json(['success' => false, 'error' => $validator->messages()]);
    }
      //$usuario = $this->getAuthUser($request);
    $usuario = Usuario::where('id_user', $request->fkiduser)->first();
    
    if (!$usuario) {
        return response()->json(['success' => false, 'data' => ['error' => 'usuario no válido']]);
    }
     // ── Capturar IP y navegador ──
    $userAgent = $request->header('User-Agent');
    $clientIp = $request->input('client_ip');
    $ip = ($clientIp && filter_var($clientIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE))
     ? $clientIp
     : getRealIp();

    $browser  = 'Unknown';
    $platform = 'Unknown';

    if (str_contains($userAgent, 'Edg'))           $browser = 'Edge';
    elseif (str_contains($userAgent, 'Chrome'))    $browser = 'Chrome';
    elseif (str_contains($userAgent, 'Firefox'))   $browser = 'Firefox';
    elseif (str_contains($userAgent, 'Safari'))    $browser = 'Safari';

    if (str_contains($userAgent, 'Android'))       $platform = 'Android';
    elseif (str_contains($userAgent, 'iPhone') || str_contains($userAgent, 'iPad'))
                                                   $platform = 'iOS';
    elseif (str_contains($userAgent, 'Windows'))   $platform = 'Windows';
    elseif (str_contains($userAgent, 'Macintosh')) $platform = 'Mac';
    elseif (str_contains($userAgent, 'Linux'))     $platform = 'Linux';
    $uuid = Str::uuid();
    $date = Carbon::now()->format('Y-m-d H:i:s');
    $file = $request->file('file');
    
    try {
        // Subir DIRECTAMENTE a R2 usando streaming
        $r2Service = new CloudflareR2Service();
        $r2Key = 'documentorigin/' . $uuid . '.pdf';
        
        Log::info("Iniciando subida a R2: {$r2Key}");
        
        $r2Result = $r2Service->subirDesdeUploadStreaming($r2Key, $file);
        
        Log::info("Subida exitosa a R2", [
            'key' => $r2Result['key'],
            //'size' => $r2Result['size'],
            'url' => $r2Result['url']
        ]);
        
        // Crear el documento en la base de datos
        $document = Document::create([
            'fk_status' => 2,
            'fk_signuser' => $request->fksign,
            'fk_progres' => 1,
            'datetime' => $date,
            'fk_flow' => $request->fkflow,
            'fk_idareadoc' => $request->fkareadoc,
            'pathpdf' => $r2Result['url'], // URL pública de R2
            'uuidpdf' => $uuid,
            'fk_responsible' => $request->fkresponsible,
            'note' => '',
            'subject' => $request->subject,
            'fk_company'=>$usuario->fk_idcompany
        ]);
        
        // Crear trace del documento
        TraceDocument::create([
            'fk_tracetype' => 1,
            'fk_document' => $document->id_document,
            'fk_user' => $request->fkresponsible,
            'date_create' => $date,
            'ip_address'   => $ip,        // ← nuevo
            'user_agent'   => $userAgent, // ← nuevo
            'browser'      => $browser,   // ← nuevo
            'platform'     => $platform, 
            'latitude' =>$request->lat,
            'longitude' =>$request->long,
            
        ]);
        
        // Enviar notificaciones push
       // $this->enviarNotificacionesPush();
        
        return response()->json([
            'success' => true,
            'data' => [
                'iddoc' => $document->id_document,
                'uuidpdf' => $document->uuidpdf,
                'r2_url' => $r2Result['url'],
               // 'size' => $r2Result['size']
            ]
        ]);
        
    } catch (Exception $e) {
        Log::error('Error al subir PDF a R2', [
            'error' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);
        
        return response()->json([
            'success' => false,
            'error' => 'Error al subir el archivo: ' . $e->getMessage()
        ]);
    }
}


public function createdocR2Multiple(Request $request)
{
    $rules = [
        'fkresponsible' => 'required',
        'fksign'        => 'required',
        'fkflow'        => 'required',
        'fkareadoc'     => 'required',
        'files'         => 'required|array|min:1|max:10',
        'files.*'       => 'required|file|mimes:pdf',
        'subject'       => 'required',
        'note'          => '',
    ];

    $validator = Validator::make($request->all(), $rules);
    if ($validator->fails()) {
        return response()->json(['success' => false, 'error' => $validator->messages()]);
    }

    $usuario  = $this->getAuthUser($request);
    $date     = Carbon::now()->format('Y-m-d H:i:s');
    $r2Service = new CloudflareR2Service();

    // Preparar array para el service
    $archivos = [];
    $uuids    = [];

    foreach ($request->file('files') as $i => $file) {
        $uuid       = Str::uuid()->toString();
        $uuids[$i]  = $uuid;
        $archivos[] = [
            'key'  => 'documentorigin/' . $uuid . '.pdf',
            'file' => $file,
        ];
    }

    try {
        // Una sola llamada — todo el curl_multi vive en el service
        $results = $r2Service->subirMultiplesArchivos($archivos);

        // Persistir en BD solo si todos subieron OK
        $created = [];

        foreach ($results as $i => $result) {
            $document = Document::create([
                'fk_status'      => 2,
                'fk_signuser'    => $request->fksign,
                'fk_progres'     => 1,
                'datetime'       => $date,
                'fk_flow'        => $request->fkflow,
                'fk_idareadoc'   => $request->fkareadoc,
                'pathpdf'        => $result['url'],
                'uuidpdf'        => $uuids[$i],
                'fk_responsible' => $request->fkresponsible,
                'note'           => '',
                 'subject' => $request->subject[$i],
            ]);

            TraceDocument::create([
                'fk_tracetype' => 1,
                'fk_document'  => $document->id_document,
                'fk_user'      => $request->fkresponsible,
                'date_create'  => $date,
            ]);

            $created[] = [
                'iddoc'   => $document->id_document,
                'uuidpdf' => $uuids[$i],
                'r2_url'  => $result['url'],
            ];
        }

        return response()->json([
            'success'   => true,
            'uploaded'  => count($created),
            'documents' => $created,
        ]);

    } catch (Exception $e) {
        Log::error('Error en subida múltiple a R2', [
            'error' => $e->getMessage(),
        ]);

        return response()->json([
            'success' => false,
            'error'   => $e->getMessage(),
        ]);
    }
}
    
  public function createdocnew(Request $request)
    {
        $rules = [
            'fkresponsible' => 'required',
            'fksign' => 'required',
            'fkflow' => 'required',
            'fkareadoc'=>'required',
            'pathpdf'    => 'required',
            'subject' => 'required',
            'token'=>'required',
            'note ' => '',
             
        ];
    
        $input     = $request->only('fkflow','fksign','fkresponsible','pathpdf','subject','token','fkareadoc');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
        $usuario = $this->getAuthUser($request);
       //$usuario = UserToken::where('token',$request->token)->first();
        if($usuario){
             $uuid = Str::uuid();
            $date = Carbon::now()->format('Y-m-d H:i:s');
            $file = $request->file('file');
            $extension = $file->getClientOriginalExtension();
            $path = Storage::putFileAs(
            'public/documents', $request->file('file'), $uuid.'.pdf' );
    
            $url  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
         
            $document = Document::create(['fk_status' => 2, 'fk_signuser' => $request->fksign,'fk_progres'=>1,'datetime'=>$date,
            'fk_flow'=>$request->fkflow,'fk_idareadoc'=>$request->fkareadoc,'pathpdf'=>$url.'/documents/'.$uuid,'uuidpdf'=>$uuid,'fk_responsible'=>$request->fkresponsible,'note'=>$request->note,'subject'=>$request->subject]);
            
            $tracedoc=TraceDocument::create(['fk_tracetype'=>1,'fk_document'=>$document->id_document,
             'fk_user'=>$request->fkresponsible,'date_create'=>$date]);     
            
            $content=Storage::get('tokenfire.txt');
        $data2 = [
            
            //"to" => $firebaseToken,
            "to"=>$content,
            "notification" => [
                "title" => "Importante",
                "body" => "Tienes nuevos documentos pendientes por firmar",  
                // "image"=>'https://cdn-icons-png.flaticon.com/512/2800/2800737.png'
            ]
        ];
        $dataString2 = json_encode($data2);
      
        $headers2 = [
            //'Authorization: key=' . $SERVER_API_KEY,
            'Authorization: key=' . 'AAAAdFPBTDo:APA91bH3AwGD_55bAqsqRalaR3c-GdrHPn6apqhJLV_wJALbFIi4Via2bJfFt_vwMjYsqomk8eBTKfJUno0wpfy8w81Mh0JyNIKZjzTODVIosJYhEYEYADt45VKblBpz41CiDbBpu4zL',
            'Content-Type: application/json',
        ];
      
        $ch2 = curl_init();
        
        curl_setopt($ch2, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
        curl_setopt($ch2, CURLOPT_POST, true);
        curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers2);
        curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch2, CURLOPT_POSTFIELDS, $dataString2);
                 
        $respon2 = curl_exec($ch2);    
            
        $data = [
            //"to" => $firebaseToken,
            "to"=>"/topics/allnotification",
            "notification" => [
                "title" => "importante",
                "body" => "Tienes nuevos documentos pendientes por firmar",  
                // "image"=>'https://cdn-icons-png.flaticon.com/512/2800/2800737.png'
            ]
        ];
        $dataString = json_encode($data);
      
        $headers = [
            //'Authorization: key=' . $SERVER_API_KEY,
            'Authorization: key=' . 'AAAAdFPBTDo:APA91bH3AwGD_55bAqsqRalaR3c-GdrHPn6apqhJLV_wJALbFIi4Via2bJfFt_vwMjYsqomk8eBTKfJUno0wpfy8w81Mh0JyNIKZjzTODVIosJYhEYEYADt45VKblBpz41CiDbBpu4zL',
            'Content-Type: application/json',
        ];
      
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
                 
        $respon = curl_exec($ch);
        // if($response){
        //     return response()->json(['success' => true, 'message' =>"notificación enviada con exito"]);
        // }else{
        //     return response()->json(['success' => false, 'message' =>"ocurrio un error al enviar la notificación"]);
        // }
            
            
             return response()->json(['success' => true,'data' => array("iddoc"=>$document->id_document,"uuidpdf"=>$document->uuidpdf)]);
       // }

          }else{
              return response()->json(['success' => false, 'data' => array("error"=>'Token no válido')]);
          }  

    }
    
       public function deletedocument(Request $request){
        $rules = [
            'idocument' => 'required',
            
        ];
    
        $input     = $request->only('idocument');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
        $tracedoc=TraceDocument::where('fk_document',$request->idocument)->delete();
        $document= Document::where('id_document',$request->idocument)->delete();
        if($document){
            return response()->json(['success' => true, 'data' => $document]);
        }else{
            return response()->json(['success' => false, 'data' => $document]);
        }

    }
    
     public function resumedoc(Request $request){
        $total=Document::select('documents')->count();
        $firmados=Document::select('documents')->where('fk_progres', '=', 2)->count();
        $pendientes=$total-$firmados;

        return  response()->json(['success' => true, 'total' => $total,'slope'=> $pendientes,'sign'=>$firmados]);
    }

    protected function getAuthUser(Request $request)
    {
        $token = $request->bearerToken() ?? $request->token;
        if (!$token) return null;
        return UserToken::where('token', $token)->first();
    }
    
    public function listdocument(Request $request)
        {
            //4 NOTARIOS solo ven sus firmas y solo pendientes
            //2 EMPLEADO SOLO VER SUS DOCUMENTOS
            //3 SUB ADMIN VER TODOS LOS DOC DE SU AREA(PERMISOS DE SUS EMPLEADOS)
            //1 ADMIN TODO DESBLOQUEADO (VE TODAS LAS AREAS - AGREGA USERS)
             //$token = $request->bearerToken() ?? $request->token;
             $usuario = $this->getAuthUser($request);
             //$usuario = UserToken::where('token',$request->token)->first();
          // if($usuario){
               // ── NUEVO: parámetros de paginación ──────────────────────────────
            $perPage = min((int) ($request->per_page ?? 40), 100); // máximo 100
            $page    = max((int) ($request->page ?? 1), 1);
            // ─────────────────────────────────────────────────────────────────
           if ($request->fkrol == 4) {
                // Rol 6: Solo puede ver documentos asignados a su usuario con estado pendiente
                   $document = Document::select(
                    'documents.*',
                    'company.legal_name as company',
                    'statuses.description as status',
                    'progres.description as progres',
                    DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),
                    DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),
                    'flows.description as flow',
                    'areadocuments.description as areadoc'
                     )
                ->join('company','company.id','=','documents.fk_company')     
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->orderBy('id_document', 'desc')
                 ->where('removed','=',0) 
                ->where('fk_signuser', '=', $request->iduser)
                ->where('progres.id_progres', '=', '1')
           // ->get();
            ->paginate($perPage, ['*'], 'page', $page);
                }
                if ($request->fkrol==2) {
                    //empleado
                  if($request->upload){
                        $document = Document::select(
                      'documents.*',
                      'company.legal_name as company',
                  'statuses.description as status',
                  'progres.description as progres',
                  DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),
                  DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),
                  'flows.description as flow',
                   'areadocuments.description as areadoc'
                 )
                  ->join('company','company.id','=','documents.fk_company')     
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                 ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
             ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                 ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                 ->orderBy('id_document', 'desc')
                  ->where(function ($q) use ($request) {
                     $q->where('fk_responsible', $request->iduser)
                       ->orWhere('fk_signuser', $request->iduser);
                 })
                     //->get();
                      ->paginate($perPage, ['*'], 'page', $page);
                    }else{
                       if ($request->soloarea) {
                           $document=Document::select('documents.*',
                            'company.legal_name as company',
                           'statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                            ->join('company','company.id','=','documents.fk_company')     
                    ->join('statuses','statuses.id_status','=','documents.fk_status')
                    ->join('progres','progres.id_progres','=','documents.fk_progres')
                    ->join('flows','flows.id_flow','=','documents.fk_flow')
                     ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                    ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                      ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                    ->orderBy('id_document', 'desc')
                     ->where('removed','=',0) 
                     //->where('fk_signuser', '=', $request->iduser)
                      ->where('fk_idareadoc', '=', $request->iddocarea)
                   // ->get();
                      ->paginate($perPage, ['*'], 'page', $page);
                       }else{
                          $document=Document::select('documents.*','company.legal_name as company','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                     ->join('company','company.id','=','documents.fk_company')
                    ->join('statuses','statuses.id_status','=','documents.fk_status')
                    ->join('progres','progres.id_progres','=','documents.fk_progres')
                    ->join('flows','flows.id_flow','=','documents.fk_flow')
                     ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                    ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                      ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                    ->orderBy('id_document', 'desc')
                     ->where('removed','=',0) 
                     ->where('fk_signuser', '=', $request->iduser)
                   // ->where('fk_idareadoc', '=', $request->iddocarea)
                   // ->get(); 
                      ->paginate($perPage, ['*'], 'page', $page);
                       }
                    }
                }
                if ($request->fkrol==3) {
                    $usu = Usuario::find($request->iduser);
                    $areasSeleccionadas=json_decode($usu->idsareas, true);
                      $document=Document::select('documents.*','company.legal_name as company','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                      ->join('company','company.id','=','documents.fk_company')
                        ->join('statuses','statuses.id_status','=','documents.fk_status')
                        ->join('progres','progres.id_progres','=','documents.fk_progres')
                        ->join('flows','flows.id_flow','=','documents.fk_flow')
                        ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                        ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                        ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                        ->orderBy('id_document', 'desc')
                         ->where('removed','=',0) 
                        ->whereIn('fk_idareadoc', $areasSeleccionadas)
                       // ->where('user1.fk_idarea', $request->areauser)
                      //  ->get();
                       ->paginate($perPage, ['*'], 'page', $page);
                } 
                if($request->fkrol==1){
                    //admin
                    $document=Document::select('documents.*','company.legal_name as company','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                    ->join('company','company.id','=','documents.fk_company')
                    ->join('statuses','statuses.id_status','=','documents.fk_status')
                    ->join('progres','progres.id_progres','=','documents.fk_progres')
                    ->join('flows','flows.id_flow','=','documents.fk_flow')
                     ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                    ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                      ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                     ->where('removed','=',0) 
                    ->orderBy('id_document', 'desc')
                    //->get();
                     ->paginate($perPage, ['*'], 'page', $page);
                     }
                // $document     = Document::orderBy('id', 'desc')->get();
                return response()->json(['success' => true, 'data' => $document->items(),'pagination'   => [
                    'total'        => $document->total(),
                    'per_page'     => $document->perPage(),
                    'current_page' => $document->currentPage(),
                    'last_page'    => $document->lastPage(),
                    'from'         => $document->firstItem(),  // nro. registro inicio
                    'to'           => $document->lastItem(),   // nro. registro fin
                ]]);
               // return response()->json(['success' => false, 'data' => array("error"=>'el número de DNI ya existe')]);
            // }else{
            //   //return response()->json(['success' => false, 'data' => array("error"=>'Token no válido')]);
            //   return response()->json(['success' => false,"error"=>'Token no válido', 'data' => array()]);
            //  }
     }
    
    
    
    public function listdocument2(Request $request)
    {
    $usuario = $this->getAuthUser($request);

    $perPage = min((int) ($request->per_page ?? 60), 100);
    $page    = max((int) ($request->page ?? 1), 1);

    // ── Función auxiliar para aplicar filtros comunes ──────────────────
    $applyFilters = function ($query) use ($request) {
        // Filtro por fecha (busca en el campo datetime)
        if ($request->filled('fecha_desde')) {
            $query->whereDate('documents.datetime', '>=', $request->fecha_desde);
        }
        if ($request->filled('fecha_hasta')) {
            $query->whereDate('documents.datetime', '<=', $request->fecha_hasta);
        }
        // Filtro por usuario creador (fk_responsible)
        if ($request->filled('fk_creador')) {
            $query->where('documents.fk_responsible', $request->fk_creador);
        }
        // Filtro por área
        if ($request->filled('fk_area')) {
            $query->where('documents.fk_idareadoc', $request->fk_area);
        }
        // Filtro por flujo
        if ($request->filled('fk_flow_filter')) {
            $query->where('documents.fk_flow', $request->fk_flow_filter);
        }
         // Filtro por empresa
        if ($request->filled('fk_company_filter')) {
            $query->where('documents.fk_company', $request->fk_company_filter);
        }
        return $query;
    };

    // ── Base select reutilizable ───────────────────────────────────────
    $baseSelect = function () {
        return Document::select(
            'documents.*',
            'company.legal_name as company',
            'statuses.description as status',
            'progres.description as progres',
            DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),
            DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),
            'flows.description as flow',
            'areadocuments.description as areadoc'
        )
         ->join('company','company.id','=','documents.fk_company')
        ->join('statuses',      'statuses.id_status',       '=', 'documents.fk_status')
        ->join('progres',       'progres.id_progres',        '=', 'documents.fk_progres')
        ->join('flows',         'flows.id_flow',             '=', 'documents.fk_flow')
        ->join('usuarios as user1', 'user1.id_user',         '=', 'documents.fk_responsible')
        ->join('usuarios as user2', 'user2.id_user',         '=', 'documents.fk_signuser')
        ->join('areadocuments', 'areadocuments.id_areadoc',  '=', 'documents.fk_idareadoc')
        ->orderBy('id_document', 'desc');
    };

    // ── ROL 4: Notario — solo sus firmas pendientes ────────────────────
    if ($request->fkrol == 4) {
        $query = $baseSelect()
            ->where('removed', '=', 0)
            ->where('fk_signuser', '=', $request->iduser)
            ->where('progres.id_progres', '=', '1');

        $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);
    }

    // ── ROL 2: Empleado ────────────────────────────────────────────────
    if ($request->fkrol == 2) {
        if ($request->upload) {
            // Ve documentos donde es responsable o firmante
            $query = $baseSelect()
                ->where(function ($q) use ($request) {
                    $q->where('fk_responsible', $request->iduser)
                      ->orWhere('fk_signuser',  $request->iduser);
                });

            $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);

        } elseif ($request->soloarea) {
            // Ve todos los documentos de su área
            $query = $baseSelect()
                ->where('removed', '=', 0)
                ->where('fk_idareadoc', '=', $request->iddocarea);

            $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);

        } else {
            // Ve solo documentos donde es firmante
            $query = $baseSelect()
                ->where('removed', '=', 0)
                ->where('fk_signuser', '=', $request->iduser);

            $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);
        }
    }

    // ── ROL 3: Sub-Admin — ve las áreas asignadas ──────────────────────
    if ($request->fkrol == 3) {
        $usu = Usuario::find($request->iduser);
        $areasSeleccionadas = json_decode($usu->idsareas, true);

        $query = $baseSelect()
            ->where('removed', '=', 0)
            ->whereIn('fk_idareadoc', $areasSeleccionadas);

        $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);
    }

    // ── ROL 1: Admin — ve todo ─────────────────────────────────────────
    if ($request->fkrol == 1) {
        $query = $baseSelect()
            ->where('removed', '=', 0);

        $document = $applyFilters($query)->paginate($perPage, ['*'], 'page', $page);
    }

    return response()->json([
        'success' => true,
        'data'    => $document->items(),
        'pagination' => [
            'total'        => $document->total(),
            'per_page'     => $document->perPage(),
            'current_page' => $document->currentPage(),
            'last_page'    => $document->lastPage(),
            'from'         => $document->firstItem(),
            'to'           => $document->lastItem(),
        ]
    ]);
   }
    
    
     public function listdocumentapp(Request $request){
       // $usuario = UserToken::where('token',$request->token)->first();
        $usuario = $this->getAuthUser($request);
        if($usuario){
           
            if($request->admin){
                $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->orderBy('id_document', 'desc')
               // ->where('fk_responsible', '=', $request->iduser)
                ->get();
            }else{
                if($request->upload){
                    $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                  ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->orderBy('id_document', 'desc')
                  ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->where('fk_responsible', '=', $request->iduser)
                ->get();
                }else{
                    $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                  ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->orderBy('id_document', 'desc')
                  ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->where('fk_signuser', '=', $request->iduser)
                ->get();
                }
            } 
        
            // $document = Document::orderBy('id', 'desc')->get();
            return response()->json(['success' => true, 'data' => $document]);
           // return response()->json(['success' => false, 'data' => array("error"=>'el número de DNI ya existe')]);
        }else{
           //return response()->json(['success' => false, 'data' => array("error"=>'Token no válido')]);
           return response()->json(['success' => false,"error"=>'Token no válido', 'data' => array()]);
        }}
    
    
    public function listdocumentfilterdate(Request $request)
    {
       // $usuario = UserToken::where('token',$request->token)->first();
          $usuario = $this->getAuthUser($request);
        if($usuario){
            if ($request->soloarea) {
                $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                    ->join('statuses','statuses.id_status','=','documents.fk_status')
                    ->join('progres','progres.id_progres','=','documents.fk_progres')
                    ->join('flows','flows.id_flow','=','documents.fk_flow')
                    ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                    ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                    ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                    ->orderBy('id_document', 'desc')
                    ->whereBetween('datetime', [$request->dateini, $request ->datefin])
                     ->where('fk_idareadoc', '=', $request->iddocarea)
                    ->get();
            } else {
            if($request->admin){
                $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                  ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->orderBy('id_document', 'desc')
               // ->where('fk_responsible', '=', $request->iduser)
                ->get();
            }else{
                if($request->upload){
                    $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                  ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->orderBy('id_document', 'desc')
                ->where('fk_responsible', '=', $request->iduser)
                ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->get();
                }else{
                    $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                  ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->orderBy('id_document', 'desc')
                ->where('fk_signuser', '=', $request->iduser)
                ->whereBetween('datetime', [$request->dateini, $request->datefin])
                ->get();
                }
            }
            
            }

            
// $document     = Document::orderBy('id', 'desc')->get();
            return response()->json(['success' => true, 'data' => $document]);
           // return response()->json(['success' => false, 'data' => array("error"=>'el número de DNI ya existe')]);
        }else{
           //return response()->json(['success' => false, 'data' => array("error"=>'Token no válido')]);
           return response()->json(['success' => false,"error"=>'Token no válido', 'data' => array()]);
        }
    }

    public function base64PDF(Request $request)
    {
        $pdf=base64_decode($request->base64);
        Storage::disk('public')->put('444444.pdf',$pdf);
        return response()->json(['success' => true]);
    }

    public function searchsubject(Request $request)
    {
        $rules = [
            'subject' => 'required',
           // 'token'=>'required',
        ];
    
        $input     = $request->only('subject');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
        //  $usuario = $this->getAuthUser($request);
       // $usuario = UserToken::where('token',$request->token)->first();
      // if($usuario){
            
                 if ($request->soloarea) {
                $document=Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                    ->join('statuses','statuses.id_status','=','documents.fk_status')
                    ->join('progres','progres.id_progres','=','documents.fk_progres')
                    ->join('flows','flows.id_flow','=','documents.fk_flow')
                    ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                    ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                    ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                  //  ->orderBy('id_document', 'desc')
                    ->where('subject', '=', $request->subject)
                    ->where('fk_idareadoc', '=', $request->iddocarea)
                  //  ->whereBetween('datetime', [$request->dateini, $request->datefin])
                    ->get();
            } else {
                $document = Document::select('documents.*','statuses.description as status','progres.description as progres',DB::raw("CONCAT(user1.name,' ',user1.lasname) as nameupload"),DB::raw("CONCAT(user2.name,' ',user2.lasname) as namesign"),'flows.description as flow','areadocuments.description as areadoc')
                ->join('statuses','statuses.id_status','=','documents.fk_status')
                ->join('progres','progres.id_progres','=','documents.fk_progres')
                ->join('flows','flows.id_flow','=','documents.fk_flow')
                 ->join('usuarios as user1','user1.id_user','=','documents.fk_responsible')
                ->join('usuarios as user2','user2.id_user','=','documents.fk_signuser')
                 ->join('areadocuments','areadocuments.id_areadoc','=','documents.fk_idareadoc')
                ->where('subject', '=', $request->subject)
                ->get();
        }
        if($document->isNotEmpty()){
            
            return response()->json(['success' => true, 'data' => $document]);
        }else{
            return response()->json(['success' => false,'error'=>'No se encontro el asunto', 'data' => $document]);
        }
   // }else{
    //    return response()->json(['success' => false,'error'=>'Token no válido', 'data' => array()]);
   // }
    }
    
 public function searchcode(Request $request)
    {
         $rules = [
            'codelink' => 'required',
             'captcha_token' => 'required', 
            
        ];
    
           // 2. Validar (Usamos all() para incluir el token)
        $validator = Validator::make($request->all(), $rules);
   
       if ($validator->fails()) {
          return response()->json([
              'success' => false,
               'error' => $validator->messages()
           ]);
       }
  // 2. VERIFICACIÓN CON CLOUDFLARE TURNSTILE
        $response = Http::asForm()->post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
            'secret'   => env('TURNSTILE_SECRET_KEY'),
            'response' => $request->captcha_token,
            'remoteip' => $request->ip(),
        ]);
   
        $outcome = $response->json();
   
       // Si Cloudflare dice que el token es inválido o expiró
        if (!$outcome['success']) {
           return response()->json([
                'success' => false,
                'error' => 'Validación de seguridad fallida. Por favor, intente de nuevo.'
           ], 403);
        }
       $document = Document::where('code_link',$request->codelink)->first();
        if($document){
              $tracedocument = TraceDocument::where('fk_document',$document->id_document)->first();    
            $datec= $tracedocument->date_create;
           // $certificateuser=UserCertificate::where('fk_iduser',$document->fk_signuser)->first();
            $certificateuser=UserCertificate::select('user_certificates.*')           
        ->where('fk_iduser',$document->fk_signuser)
        ->get(); 
              foreach ($certificateuser as $email) {
                $email->datesignuser =  $datec;
                 }
                   $namepdf="";
                 if (empty($document->uuidpdf)) {
                    $namepdf= $document->subject;
                 }else{
                    $namepdf= $document->uuidpdf;       
                 }
            return response()->json(['success' => true,'urlpdf'=>$document->pathpdf,'certificateuser'=> $certificateuser]);
        }else{
            return response()->json(['success' => false,'error'=>'No se encontro el codigo', 'data' => $document]); 
        }
    }
    
 public function searchminicode(Request $request)
     {
         // 1. Validamos que lleguen los campos necesarios
        $rules = [
             'codeminilink' => 'required',
             'captcha_token' => 'required', // El token que enviamos desde React
        ];
   
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
           return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
   
        // 2. VERIFICACIÓN CON CLOUDFLARE TURNSTILE
        $response = Http::asForm()->post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
            'secret'   => env('TURNSTILE_SECRET_KEY'),
            'response' => $request->captcha_token,
            'remoteip' => $request->ip(),
        ]);
   
        $outcome = $response->json();
   
       // Si Cloudflare dice que el token es inválido o expiró
        if (!$outcome['success']) {
           return response()->json([
                'success' => false,
                'error' => 'Validación de seguridad fallida. Por favor, intente de nuevo.'
           ], 403);
        }
   
        // 3. LÓGICA DE BÚSQUEDA ORIGINAL (Solo si el captcha es válido)
        $document = Document::where('code_print', $request->codeminilink)->first();
   
        if($document){
            $tracedocument = TraceDocument::where('fk_document', $document->id_document)->first();
            $datec = $tracedocument->date_create;
   
           $certificateuser = UserCertificate::select('user_certificates.*')
               ->where('fk_iduser', $document->fk_signuser)
               ->get();
   
           foreach ($certificateuser as $email) {
                $email->datesignuser = $datec;
           }
           $namepdf = empty($document->uuidpdf) ? $document->subject : $document->uuidpdf;
   
            return response()->json([
               'success' => true,
             'urlpdf' => $document->pathpdf,
              'certificateuser' => $certificateuser
            ]);
        } else {
           return response()->json([
               'success' => false,
               'error' => 'No se encontró el código',
               'data' => $document
          ]);
     }
 }

    


    public function createdocument(Request $request)
    {
        $rules = [
            'fkresponsible' => 'required',
            'fksign' => 'required',
            'fkflow' => 'required',
            'fkareadoc'=>'required',
            'pathpdf'    => 'required',
            'subject' => 'required',
            'token'=>'required',
            'pdf64'=>'required',
            'note ' => '',
             
        ];
    
        $input     = $request->only('fkflow','fksign','fkresponsible','pathpdf','subject','pdf64','token','fkareadoc');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
          $usuario = $this->getAuthUser($request);
       // $usuario = UserToken::where('token',$request->token)->first();
        if($usuario){
       
        $date = Carbon::now()->format('Y-m-d H:i:s');
        Storage::disk('public')->put('/documents/'.$request->subject.'.pdf',base64_decode($request->pdf64));
        $url  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
        $document = Document::create(['fk_status' => 2, 'fk_signuser' => $request->fksign,'fk_progres'=>1,'datetime'=>$date,
        'fk_flow'=>$request->fkflow,'fk_idareadoc'=>$request->fkareadoc,'pathpdf'=>$url.'/documents/'.$request->pathpdf,'fk_responsible'=>$request->fkresponsible,'note'=>$request->note,'subject'=>$request->subject]);
        
         $tracedoc=TraceDocument::create(['fk_tracetype'=>1,'fk_document'=>$document->id_document,
         'fk_user'=>$request->fkresponsible,'date_create'=>$date]);  
         
        return response()->json(['success' => true, 'data' => array("id_doc"=>$document->id_document)]);
       // }
        }else{
            return response()->json(['success' => false, 'data' => array("error"=>'Token no válido')]);
        }
    }

  
    public function signdocument3(Request $request)
    {
        $rules = [
            'idocument' => 'required',
            'fkuser' => 'required',
            'pathpdf'    => 'required',
            'token'=>'required',
            'password'=>'required',
        ];
    
        $input= $request->only('idocument','fkuser','pathpdf','token','password');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
          $usuario = $this->getAuthUser($request);
        //$usuario = UserToken::where('token',$request->token)->first();
        if($usuario){
          
        $usercertificate=UserCertificate::where('fk_iduser',$request->fkuser)->orderBy('id_usercertificates', 'desc')->first();
        if(empty($usercertificate->certifying_entity)){
            // return response()->json(['success' => false,"error"=>'El usuario no tiene un certificado para firmar el documento', 'data' => array()]);
            
              //validar si ya se extrajo la firma si
            $pfxCertPrivado = Storage::disk('public')->path('/certificates/'.$usercertificate->name_certificate);
             $password =  $request->password;
            $pfxContent = file_get_contents($pfxCertPrivado.'.p12');
            $openSSL = openssl_pkcs12_read($pfxContent,$res, $password);
             $certInfo = $this->extractCertificateInfo($pfxCertPrivado . '.p12', $request->password,$request->fkuser,$usercertificate->name_certificate);
         $usercertificate=UserCertificate::where('fk_iduser',$request->fkuser)->orderBy('id_usercertificates', 'desc')->first();     
        }
        
        //busca area del documento
        $docarea=Document::where('id_document',$request->idocument)->first();
        //-====================
        
        $url  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
       // $file = Storage::disk('public')->path('/documents/'.$request->pathpdf.'.pdf'); 
       // $outputFile = Storage::disk('public')->path('/documentsign/'.$request->pathpdf.'.pdf');
        $file = Storage::disk('public')->path('/documents/'. $docarea->uuidpdf.'.pdf'); 
        $outputFile = Storage::disk('public')->path('/documentsign/'.$docarea->uuidpdf.'.pdf');
        $pfxCertPrivado = Storage::disk('public')->path('/certificates/'.$usercertificate->name_certificate);
            //echo '/certificates/'.$usercertificate->name_certificate;
            $res = [];
            $password =  $request->password;
            $pfxContent = file_get_contents($pfxCertPrivado.'.p12');
            $openSSL = openssl_pkcs12_read($pfxContent,$res, $password);
            if($openSSL) {
          try{
            
              
            //aqui se va directo al nuevo firmador   
            if($request->fkuser==35){
              //  echo "paso 35";
                $namedoc=$docarea->uuidpdf.'.pdf';
              $this->signdocumentAdvanced($file,$password,$outputFile,$request->idocument,$request->fkuser,$url,$namedoc);
              // echo "paso 35 fin";
              return response()->json(['success' => true, 'data' => array()]);
            //return;
            }
         if($docarea->fk_flow==2){
          
            $fpdi = new FPDI;
            $count = $fpdi->setSourceFile($file);
             $code=Str::random(12);
                        // $code="12121212121";
                          $date = Carbon::now()->format('d/m/Y H:i:s');
                          $date2 =  Carbon::now()->format('Y-m-d H:i:s');
                         $codelink=Str::random(40);
             for ($i=1; $i<=$count; $i++) {       
             // $date = Carbon::now()->format('d/m/Y H:i');
              $template   = $fpdi->importPage($i);
              $size       = $fpdi->getTemplateSize($template);
             $fpdi->SetPrintHeader(false);
              $fpdi->SetPrintFooter(false);
              $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
              $fpdi->useTemplate($template);  
            $fpdi-> SetAutoPageBreak(TRUE, 0);
            $style = array(
                'border' => false,
                'vpadding' => 'auto',
                'hpadding' => 'auto',
                'fgcolor' => array(0,0,0),
                'bgcolor' => false, //array(255,255,255)
                'module_width' => 1, // width of a single module in points
                'module_height' => 1 // height of a single module in points
            );
                
                //if($count=$i){
                    $sealDocs = SealDoc::where('fk_iddoc',$request->idocument)->get();
                    if ($sealDocs) {
                       
                        // Imprimir todas las coincidencias
                        foreach ($sealDocs as $sealDoc) {
                            
                            //aqui imagenes
                            
                              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', '', '', true, 150, '', 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);
                          }
                          if ($sealDoc->type==2) {
                              if($sealDoc->path=="sello1"){
                                  $pathimg = Storage::disk('public')->path('/pdfadd/'.$sealDoc->path.'.png'); 
                          $fpdi->Image($pathimg, $sealDoc->ejeX, $sealDoc->ejeY, 35,35, 'PNG', '', '', true, 150, '', false, false, 0, false, false, false); 
                              }else{
                                  $pathimg = Storage::disk('public')->path('/pdfadd/'.$sealDoc->path.'.png'); 
                          $fpdi->Image($pathimg, $sealDoc->ejeX, $sealDoc->ejeY, $sealDoc->witch,$sealDoc->height, 'PNG', '', '', true, 150, '', false, false, 0, false, false, false); 
                              }
                          }
                        //aqui qr si o si va 
                            if ( $sealDoc->type==1) {
                                //=================
                                
                                  $fpdi->write2DBarcode('https://document.fasttek.com.pe/verify/#/'.$codelink, 'QRCODE,H', $sealDoc->ejeX, $sealDoc->ejeY,20,20, $style, 'N');
                                $fpdi->SetFont("helvetica", "",5);
                               
                                $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+20), 'document.fasttek.com.pe/verify');
                                $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+23), 'código: '.$code);            
                                $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+26), 'FIRMADO DIGITALMENTE POR');
                                if($request->fkuser==24){
                                    $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+29), 'Asterio Francisco Carbajal Rojas');
                                     $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+32), 'abogado CIP: 64028');
                                }else{
                                    if($request->fkuser==35){
                                     $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+29), 'RICARDO FERNANDINI PINTO');
                                     $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+32), 'COMPOSTELA E.I.R.L');
                                }else{
                                     $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+29), 'RICARDO FERNANDINI BARREDA');
                                     $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+32), 'NOTARIO DE LIMA');
                                }
                                }
                               
                                
                                $fpdi->Text(intval($sealDoc->ejeX+1), intval($sealDoc->ejeY+35), $date);
                                }
                        }
                    } else {
                        // Manejar el caso en el que no hay coincidencias
                        echo "No hay registros en la tabla SealDocs para el id_document: " . $idDocument;
                         return response()->json(['success' => true, 'data' => "No hay registros en la tabla SealDocs para el id_document: " . $idDocument]);
                    }
        
        }
        
                // $prepend = "file://".$pfxCertPrivado.'.crt';                 
                //   // echo  $prepend;
                // $fpdi->setSignature($prepend, $prepend, $request->password, '', 2, '','A');
                 // Guardar certificado y clave en archivos temporales
                                // Crear archivos temporales
                    $tempCert = storage_path('app/temp/cert_' . uniqid() . '.crt');
                    $tempKey = storage_path('app/temp/key_' . uniqid() . '.key');

                    // Asegurarse que la carpeta temp existe
                if (!file_exists(storage_path('app/temp'))) {
                  mkdir(storage_path('app/temp'), 0755, true);
                }

                // Guardar certificado y clave en archivos temporales
                file_put_contents($tempCert, $res['cert']);
                file_put_contents($tempKey, $res['pkey']);
                     //$prepend = "file://".$pfxCertPrivado.'.p12';    
                   // echo  $prepend;
                // $fpdi->setSignature($prepend, $prepend, $request->password, '', 2, '','A');
                $fpdi->setSignature(
    'file://' . $tempCert,
    'file://' . $tempKey,
    '',  // Sin contraseña porque ya está desbloqueado
    '',
    2,
    '',
    'A'
);
                $fpdi->setSignatureAppearance(10,245, 35, 35);  
         $fpdi->Output($outputFile, 'F');

            //guardar como true sign en Documents
            $document = Document::find($request->idocument);
            $document->fk_progres = 2;
            $document->code_print = $code;
            $document->code_link = $codelink;
            $document->pathpdf=$url.'/documentsign/'.$document->uuidpdf;
            $resultado = $document->save();
            //guardar iduser y time ,estado(firmado) id document
           // $date = Carbon::now()->format('Y-m-d H:i:s');
            $tracedoc=TraceDocument::create(['fk_tracetype'=>4,'fk_document'=>$request->idocument,
            'fk_user'=>$request->fkuser,'date_create'=>$date2]);
            //
        
            return response()->json(['success' => true, 'data' => array()]);
        
    }

        $fpdi = new FPDI;
        $count = $fpdi->setSourceFile($file);
        for ($i=1; $i<=$count; $i++) {       
         // $date = Carbon::now()->format('d/m/Y H:i');
          $template   = $fpdi->importPage($i);
          $size       = $fpdi->getTemplateSize($template);
         $fpdi->SetPrintHeader(false);
          $fpdi->SetPrintFooter(false);
          $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
          $fpdi->useTemplate($template);  

        }

        // $file2 = Storage::disk('public')->path('/pdfadd/certificado.pdf'); 
       // echo $docarea->id_document;
        //  if($docarea->fk_idareadoc==1 || $docarea->fk_idareadoc==2 || $docarea->fk_idareadoc==3){
        //  $file2= Storage::disk('public')->path('/pdfadd/bancos.pdf'); 
        //  }else{
        //   $file2= Storage::disk('public')->path('/pdfadd/clientecalle.pdf'); 
        //  }
         
         // update 16/12/23
         if($docarea->fk_flow==1){
             //Testimonio electrónico Bancos
             $file2= Storage::disk('public')->path('/pdfadd/bancos.pdf'); 
         }
         if($docarea->fk_flow==3){
             //Testimonio Electrónico Modulo
             $file2= Storage::disk('public')->path('/pdfadd/clientecalle.pdf'); 
         }
         if($docarea->fk_flow==4){
             //Testimonio Electrónico RRPP
             $file2= Storage::disk('public')->path('/pdfadd/testimonio_rrpp.pdf'); 
         }
         //firma notaria Rosalis
          if($request->fkuser==47){
             //Testimonio Electrónico RRPP
             $file2= Storage::disk('public')->path('/pdfadd/rosalia_nuevo.pdf'); 
         }
          //firma notaria Maria Perez
          if($request->fkuser==49){
             //Testimonio Electrónico RRPP
             $file2= Storage::disk('public')->path('/pdfadd/mariaperez.pdf'); 
         }
         //firma edgardo H
           if($request->fkuser==63){
             //Testimonio Electrónico RRPP
             $file2= Storage::disk('public')->path('/pdfadd/edgardo.pdf'); 
         }
         
         //$file2 = Storage::disk('public')->path('/pdfadd/certificado.pdf'); 
         $count = $fpdi->setSourceFile($file2);
          $date = Carbon::now()->format('d/m/Y H:i');
         // $date="31/12/2025 09:23"; //<------- Poner fecha MANUAL
           $date2 = Carbon::now()->format('Y-m-d H:i:s');
            $code=Str::random(12);
              $codelink=Str::random(40);
           //$date2="2021-04-14 19:03:10";
         for ($i=1; $i<=$count; $i++) {       
            $template   = $fpdi->importPage($i);
            $size       = $fpdi->getTemplateSize($template);
           $fpdi->SetPrintHeader(false);
            $fpdi->SetPrintFooter(false);
            $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
            $fpdi->useTemplate($template);


            $fpdi-> SetAutoPageBreak(TRUE, 0);
            $style = array(
                'border' => false,
                'vpadding' => 'auto',
                'hpadding' => 'auto',
                'fgcolor' => array(0,0,0),
                'bgcolor' => false, //array(255,255,255)
                'module_width' => 1, // width of a single module in points
                'module_height' => 1 // height of a single module in points
            );
                $left = 45;
                //$top = 105;
                //solo rosalia
               if ($request->fkuser == 47 || $request->fkuser == 49) {
                 $top=142;
               }else{
                 $top = 105;
               }
                
                $text=$date;
                // $text='12/12/2025 19:29';
                $fpdi->SetFont("Times", "", 12);
                $fpdi->SetTextColor(0,0,0);
                $fpdi->Text($left,$top,$text);
                //if($count=$i){
                   // $codelink=Str::random(40);
                     $fpdi->write2DBarcode('https://document.fasttek.com.pe/verify/#/'.$codelink, 'QRCODE,H', 10, 242, 35, 35, $style, 'N');
                    $fpdi->SetFont("helvetica", "",8);
                   // $code=Str::random(12);
                    $fpdi->Text(11, 276, 'document.fasttek.com.pe/verify');
                  
                    $fpdi->Text(11, 280, 'FIRMADO DIGITALMENTE');
                    $fpdi->Text(11, 283, 'código: '.$code);
                   //$prepend = "file://".$pfxCertPrivado.'.crt';    
                   
                   // Crear archivos temporales
                    $tempCert = storage_path('app/temp/cert_' . uniqid() . '.crt');
                    $tempKey = storage_path('app/temp/key_' . uniqid() . '.key');

                    // Asegurarse que la carpeta temp existe
                if (!file_exists(storage_path('app/temp'))) {
                  mkdir(storage_path('app/temp'), 0755, true);
                }

                // Guardar certificado y clave en archivos temporales
                file_put_contents($tempCert, $res['cert']);
                file_put_contents($tempKey, $res['pkey']);
                     //$prepend = "file://".$pfxCertPrivado.'.p12';    
                   // echo  $prepend;
                // $fpdi->setSignature($prepend, $prepend, $request->password, '', 2, '','A');
                $fpdi->setSignature(
    'file://' . $tempCert,
    'file://' . $tempKey,
    '',  // Sin contraseña porque ya está desbloqueado
    '',
    2,
    '',
    'A'
);
                $fpdi->setSignatureAppearance(10,245, 35, 35); 
               //  @unlink($tempCert);
               //  @unlink($tempKey);
        
        }

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

            //guardar como true sign en Documents
            $document = Document::find($request->idocument);
            $document->fk_progres = 2;
            $document->code_print = $code;
            $document->code_link = $codelink;
            //$document->pathpdf=$url.'/documentsign/'.$document->subject;
            $document->pathpdf=$url.'/documentsign/'.$document->uuidpdf;
            $resultado = $document->save();
            //guardar iduser y time ,estado(firmado) id document
           // $date = Carbon::now()->format('Y-m-d H:i:s');
            $tracedoc=TraceDocument::create(['fk_tracetype'=>4,'fk_document'=>$request->idocument,
            'fk_user'=>$request->fkuser,'date_create'=>$date2]);
            //
        
            return response()->json(['success' => true, 'data' => array()]);
    //return true;
      } catch (\Exception $e) {
    // static::raiseError(__METHOD__ . '(), failed to load FPDI!');
  //echo 'PUTO ERROR'.$e;
   return response()->json(['success' => false,"error"=> $e->getMessage(),"code_error"=>$e->getCode(), 'data' => array()]);
  // echo 'Caught exception: ', $e->getMessage(), "\n";
 }
    }else{
            return response()->json(['success' => false,"error"=>'Contraseña del certificado es incorrecta', 'data' => array()]);
    } 
     }else{
            return response()->json(['success' => false,"error"=>'Token no válido', 'data' => array()]);
     }
     
    }
 

// Endpoint para consultar el progreso
public function estadoBatch(string $batchId)
{
    $batch = Bus::findBatch($batchId);

    return response()->json([
        'total'      => $batch->totalJobs,
        'pendientes' => $batch->pendingJobs,
        'fallidos'   => $batch->failedJobs,
        'completado' => $batch->finished(),
        'progreso'   => $batch->progress(), // 0-100
    ]);
}
    
    public function signDocumentWithImages(Request $request)
    {
        $rules = [
            'images' => 'nullable|json', // JSON con las posiciones de las imágenes
            'pdfInfo' => 'nullable|json', // Información del PDF (dimensiones, etc)
            'file' => 'nullable|file|mimes:pdf',
        ];
    
        $input = $request->only('images', 'pdfInfo');
        $validator = Validator::make($input, $rules);
        
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }

        // Obtener certificado del usuario
        $usercertificate = UserCertificate::where('fk_iduser', '9')
            ->orderBy('id_usercertificates', 'desc')
            ->first();

        if (!$usercertificate) {
            return response()->json(['success' => false, 'error' => 'Usuario no tiene certificado', 'data' => []]);
        }

        // Validar y extraer certificado si es necesario
        if (empty($usercertificate->certifying_entity)) {
            $pfxCertPrivado = Storage::disk('public')->path('/certificates/' . $usercertificate->name_certificate);
            $password = $request->password;
            $pfxContent = file_get_contents($pfxCertPrivado . '.p12');
            $openSSL = openssl_pkcs12_read($pfxContent, $res, $password);
            
            if ($openSSL) {
                $certInfo = $this->extractCertificateInfo(
                    $pfxCertPrivado . '.p12',
                    $request->password,
                    $request->fkuser,
                    $usercertificate->name_certificate
                );
                $usercertificate = UserCertificate::where('fk_iduser', $request->fkuser)
                    ->orderBy('id_usercertificates', 'desc')
                    ->first();
            }
        }
        
                // ===================================================================
        // NUEVO: Guardar PDF si se envía como archivo
        // ===================================================================
        $uuid = null;
        $uuidpdf = null;
        $docarea = null;
        
        if ($request->hasFile('file')) {
            // Generar UUID para el documento
            $uuid = Str::uuid();
            $uuidpdf = $uuid->toString();
            $date = Carbon::now()->format('Y-m-d H:i:s');
            
            // Guardar archivo PDF
            $file = $request->file('file');
            $extension = $file->getClientOriginalExtension();
            
            $path = Storage::putFileAs(
                'public/documents',
                $request->file('file'),
                $uuidpdf . '.pdf'
            );
            
            $url = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
            
        }
        
       // Rutas de archivos
        $url = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
        $file = Storage::disk('public')->path('/documents/' . $uuidpdf . '.pdf');
        $outputFile = Storage::disk('public')->path('/documentsign/' . $uuidpdf . '.pdf');
        $pfxCertPrivado = Storage::disk('public')->path('/certificates/' . $usercertificate->name_certificate);

        // Leer certificado
        $res = [];
        $password = 'NotariaFernandini2024';
        $pfxContent = file_get_contents($pfxCertPrivado . '.p12');
        $openSSL = openssl_pkcs12_read($pfxContent, $res, $password);

        if (!$openSSL) {
            return response()->json(['success' => false, 'error' => 'Contraseña del certificado incorrecta', 'data' => []]);
        }
        
        

        try {
            // Decodificar datos de imágenes desde el frontend
            $imagesData = $request->images ? json_decode($request->images, true) : [];
            $pdfInfo = $request->pdfInfo ? json_decode($request->pdfInfo, true) : null;

            // Inicializar FPDI
            $fpdi = new FPDI();
            $count = $fpdi->setSourceFile($file);

            // Generar códigos únicos
            $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');

            // Procesar cada página del documento original
            for ($i = 1; $i <= $count; $i++) {
                $template = $fpdi->importPage($i);
                $size = $fpdi->getTemplateSize($template);
                
                $fpdi->SetPrintHeader(false);
                $fpdi->SetPrintFooter(false);
                $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
                $fpdi->useTemplate($template);
                $fpdi->SetAutoPageBreak(true, 0);

                // Estilo para QR
                $style = [
                    'border' => false,
                    'vpadding' => 'auto',
                    'hpadding' => 'auto',
                    'fgcolor' => [0, 0, 0],
                    'bgcolor' => false,
                    'module_width' => 1,
                    'module_height' => 1
                ];

                // ===================================================================
                // NUEVO: Agregar imágenes desde el frontend (React)
                // ===================================================================
                if (!empty($imagesData)) {
                    foreach ($imagesData as $img) {
                        // Las coordenadas ya vienen en puntos (pt) desde el frontend
                        $x = $img['x'];
                        $y = $img['y'];
                        $width = $img['width'];
                        $height = $img['height'];
                        
                        // Decodificar imagen base64
                        $imageBase64 = $img['src'];
                        
                        // Remover prefijo data:image/...;base64,
                        if (preg_match('/^data:image\/(\w+);base64,/', $imageBase64, $type)) {
                            $imageBase64 = substr($imageBase64, strpos($imageBase64, ',') + 1);
                            $imageType = strtolower($type[1]);
                        } else {
                            continue; // Skip si no es válido
                        }

                        // Decodificar base64
                        $imageData = base64_decode($imageBase64);
                        if ($imageData === false) {
                            continue; // Skip si falla la decodificación
                        }

                        // Guardar imagen temporalmente
                        $tempFile = storage_path('app/temp/img_' . uniqid() . '.' . $imageType);
                        
                        // Asegurar que existe el directorio temp
                        if (!file_exists(storage_path('app/temp'))) {
                            mkdir(storage_path('app/temp'), 0755, true);
                        }
                        
                        file_put_contents($tempFile, $imageData);

                        // Insertar imagen en el PDF
                        $fpdi->Image(
                            $tempFile,
                            $x,
                            $y,
                            $width,
                            $height,
                            strtoupper($imageType),
                            '',
                            '',
                            true,
                            300,
                            '',
                            false,
                            false,
                            0,
                            false,
                            false,
                            false
                        );

                        // Limpiar archivo temporal
                        @unlink($tempFile);
                    }
                }
            }
            // ===================================================================
            // Aplicar firma digital
            // ===================================================================
            
            // Crear archivos temporales para el certificado
            $tempCert = storage_path('app/temp/cert_' . uniqid() . '.crt');
            $tempKey = storage_path('app/temp/key_' . uniqid() . '.key');

            // Asegurar que existe el directorio temp
            if (!file_exists(storage_path('app/temp'))) {
                mkdir(storage_path('app/temp'), 0755, true);
            }

            // Guardar certificado y clave en archivos temporales
            file_put_contents($tempCert, $res['cert']);
            file_put_contents($tempKey, $res['pkey']);

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

            // Guardar PDF firmado
            $fpdi->Output($outputFile, 'F');

            // Limpiar archivos temporales
            @unlink($tempCert);
            @unlink($tempKey);

   

            return response()->json([
                'success' => true,
                'data' => [
                    'code' => $code,
                    'codelink' => $codelink,
                    // 'path' => $url . '/documentsign/' . $document->uuidpdf . '.pdf'
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => $e->getMessage(),
                'code_error' => $e->getCode(),
                'data' => []
            ]);
        }
    }

    
    
    public function extractCertificateInfo($certPath, $password,$iduser,$namecer)
    {
    if (!file_exists($certPath)) {
        throw new Exception('Certificado no encontrado');
    }
    
    $pfxContent = file_get_contents($certPath);
    
    if (!openssl_pkcs12_read($pfxContent, $certData, $password)) {
        throw new Exception('Error al leer el certificado o contraseña incorrecta');
     }
     
    
    $CertPriv = openssl_x509_parse(openssl_x509_read($certData['cert']));
    $usercertificate=UserCertificate::create(['fk_iduser'=>$iduser,
   'name_certificate'=>$namecer,
   'certifying_entity'=>$CertPriv['issuer']['OU']['1'],
   'date_expire_certificate'=>date('Y-m-d H:i:s', $CertPriv['validTo_time_t']),
   'CN_nameuser'=>$CertPriv['subject']['CN'] ?? '',
   'C'=>  $CertPriv['subject']['C'] ?? '',
  'ST'=> $CertPriv['subject']['ST'] ?? '',
  // 'ST'=>'LIMA',
   'L'=>$CertPriv['subject']['L'] ?? '',
  //'L'=>'L',
   'organizationIdentifier'=>$CertPriv['subject']['organizationIdentifier'] ?? '',
   'emailAddress'=>$CertPriv['subject']['emailAddress'] ?? '',
   'serialNumber'=>$CertPriv['subject']['serialNumber'] ?? ''
   ]);
    
}
    


    public function signimage(Request $request){
            $pdf = new FPDI();
            $inputFile = Storage::disk('public')->path('/documents/imagepdf2.pdf');
             $outputFile = Storage::disk('public')->path('/documents/IMAGEN.png');
            $pageCount = $pdf->setSourceFile($inputFile);
              $imageFormat="jpeg"; 
            // Import the first page of the PDF and render it to an image
            $pageId = 1;
            $templateId = $pdf->importPage($pageId);
            $pageInfo = $pdf->getTemplateSize($templateId);
            $pdf->addPage($pageInfo['orientation'], array($pageInfo['width'], $pageInfo['height']));
            $pdf->useTemplate($templateId);
              $pdf->Output($outputFile, 'F');
            echo 'OK';
    }
    

public function testsign(){
      $file = Storage::disk('public')->path('/documents/2019.pdf');
      $outputFile = Storage::disk('public')->path('/documentsign/2019_sign.pdf');
         $pfxCertPrivado = Storage::disk('public')->path('/certificates/Notaria');
        try {
      $fpdi = new FPDI;
       $codelink=Str::random(40);
       $code=Str::random(12);
            $count = $fpdi->setSourceFile($file);
            for ($i=1; $i<=$count; $i++) {       
                $date = Carbon::now()->format('d/m/Y H:i');
                $template   = $fpdi->importPage($i);
                $size       = $fpdi->getTemplateSize($template);
               $fpdi->SetPrintHeader(false);
                $fpdi->SetPrintFooter(false);
                $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
                $fpdi->useTemplate($template);  
          //if($i==$count){
            $fpdi-> SetAutoPageBreak(TRUE, 0);
            $style = array(
                'border' => false,
                'vpadding' => 'auto',
                'hpadding' => 'auto',
                'fgcolor' => array(0,0,0),
                'bgcolor' => false, //array(255,255,255)
                'module_width' => 1, // width of a single module in points
                'module_height' => 1 // height of a single module in points
            );
                $left = 45;
                $top = 137;
                // $text=$date;
                // $fpdi->SetFont("helvetica", "", 9);
                // $fpdi->SetTextColor(0,0,0);
                // $fpdi->Text($left,$top,$text);
                //if($count=$i){
                    
                    $fpdi->write2DBarcode($codelink, 'QRCODE,H', 40, 0, 30, 30, $style, 'N');
                    $fpdi->SetFont("helvetica", "",8);
                    
                    $fpdi->Text(41, 28, 'document.fasttek.com.pe/verify');
                    $fpdi->Text(41, 31, 'FIRMADO DIGITALMENTE');
                    $fpdi->Text(41, 34, 'código: '.$code);
                    $prepend = "file://".$pfxCertPrivado.'.crt';                 
                   // echo  $prepend;
                $fpdi->setSignature($prepend, $prepend, '123123123', '', 2, '','A');
                $fpdi->setSignatureAppearance(10,245, 35, 35);    
        //     }
           
          
        }
        $fpdi->Output($outputFile, 'F');/*  */
    } catch (\Exception $e) {
       // static::raiseError(__METHOD__ . '(), failed to load FPDI!');
     echo 'PUTO ERROR'.$e;
      return response()->json(['success' => false,"error"=> $e->getMessage(),"code_error"=>$e->getCode(), 'data' => array()]);
     // echo 'Caught exception: ', $e->getMessage(), "\n";
    }

}

public function downloadpdf(Request $request) {
        $rules = [
            'subject' => 'required',
            'iduser' =>'required',
            'iddoc' =>'required',
            'sign'=>'required'
        ];
        $input     = $request->only('subject','iduser','iddoc','sign');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        } 
        $date = Carbon::now()->format('Y-m-d H:i:s');
        //$storagePath  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
        $tracedocument = TraceDocument::create(['fk_tracetype' =>3,
        'fk_document'=>$request->iddoc,'fk_user'=>$request->iduser,'date_create'=>$date]);
         $document=Document::where('id_document',$request->iddoc)->first();
        if ( $request->sign) {
            // $file_path =  $storagePath.'/documentsign/'.$request->subject.'.pdf';
            // $data = base64_encode($file_path);
            if (empty($document->uuidpdf)) {
                $storagePath  = Storage::disk('public')->get('/documentsign/'.$request->subject.'.pdf');
            }else{
                $storagePath  = Storage::disk('public')->get('/documentsign/'.$document->uuidpdf.'.pdf');
            }      
            $data = base64_encode($storagePath);
            return response()->json(['success' => true, 'data' => array("base64pdf"=> $data)]);
        } else {
            if (empty($document->uuidpdf)) {
                $storagePath  = Storage::disk('public')->get('/documents/'.$document->subject.'.pdf');
            }else{
                $storagePath  = Storage::disk('public')->get('/documentsign/'.$document->uuidpdf.'.pdf');
            }  
            $data = base64_encode($storagePath);
            return response()->json(['success' => true, 'data' => array("base64pdf"=> $data)]);
        }
      
      
      
      }
      
      
      
    public function downloadpdfzip(Request $request) {
        $rules = [     
            'iduser' =>'required',
            'archivos' =>'required',   
        ];
        $input     = $request->only('iduser','archivos');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        } 
        $namezip = Carbon::now()->format('Ymd_His');
        $zipFileName =   $namezip.'.zip';
        $zip = new ZipArchive;
        $openpath=Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
        if ($zip->open( $openpath. '/' . $zipFileName, ZipArchive::CREATE) === TRUE) {    
            // Add Multiple file   
            foreach($request->archivos as $key => $arrayItem) {
                
                $date = Carbon::now()->format('Y-m-d H:i:s');
                $tracedocument = TraceDocument::create(['fk_tracetype' =>3,
                'fk_document'=>$arrayItem['id'],'fk_user'=>$request->iduser,'date_create'=>$date]);
                
                $path = Storage::disk('public')->path('/documentsign/'.$arrayItem['uuidpdf'].'.pdf'); 
                $zip->addFile( $path,$arrayItem['subject'].'.pdf');
            }        
            $zip->close();
        }
        //if(file_exists($filetopath)){
            $headers = array(
                'Content-Type' => 'application/octet-stream',
            );
            $filetopath=Storage::disk('public')->path( $zipFileName); 
            return response()->download($filetopath,$zipFileName,$headers);
      }      
    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Document  $document
     * @return \Illuminate\Http\Response
     */
    public function show(Document $document)
    {
        //
    }
    
      public function savejson(Request $request)
    { 
        Storage::put('json/73946110.json',json_encode($request->all()));
    }
    
      public function getjson()
    { 
        $file=Storage::get('json/73946110.json');
        return response()->json(['success' => true, 'data' => $file]);
    }
    
   public function getpdf(Request $request){ 
        $uuidpdf = $request->route('uuidpdf');
        $pdfFilePath = Storage::disk('public')->path('/documents/'.$uuidpdf.'.pdf');
        $headers = [
                'Content-Type' => 'application/pdf',
            ];

            return response()->download($pdfFilePath,$uuidpdf, $headers);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Document  $document
     * @return \Illuminate\Http\Response
     */
    public function edit(Document $document)
    {
        //
    }
    
    
    public function testsignmoveqr(Request $request){
    $file = Storage::disk('public')->path('/documentsign/LEVANTAMIENTOBLOQUEO2.pdf');
    $outputFile = Storage::disk('public')->path('/documentsign/2023_sign2.pdf');
       //$pfxCertPrivado = Storage::disk('public')->path('/certificates/Notaria');
      try {
    $fpdi = new FPDI;
     $codelink=Str::random(40);
     $code=Str::random(12);
          $count = $fpdi->setSourceFile($file);
          for ($i=1; $i<=$count; $i++) {       
              $date = Carbon::now()->format('d/m/Y H:i');
              $template   = $fpdi->importPage($i);
              $size       = $fpdi->getTemplateSize($template);
             $fpdi->SetPrintHeader(false);
              $fpdi->SetPrintFooter(false);
              $fpdi->AddPage($size['orientation'], array($size['width'], $size['height']));
              $fpdi->useTemplate($template);  
        //if($i==$count){
        $fpdi->SetMargins(0,0,0);
          $fpdi-> SetAutoPageBreak(TRUE, 0);
          $style = array(
              'border' => false,
              'vpadding' => 'auto',
              'hpadding' => 'auto',
              'fgcolor' => array(0,0,0),
              'bgcolor' => false, //array(255,255,255)
              'module_width' => 1, // width of a single module in points
              'module_height' => 1 // height of a single module in points
          );
              $left = 45;
              $top = 137;
              // $text=$date;
              // $fpdi->SetFont("helvetica", "", 9);
              // $fpdi->SetTextColor(0,0,0);
              // $fpdi->Text($left,$top,$text);
              //if($count=$i){   
               $date = Carbon::now()->format('d/m/Y H:i:s');
                $fpdi->write2DBarcode('https://document.fasttek.com.pe/verify/#/'.$codelink, 'QRCODE,H',$request->x, $request->y, 30, 30, $style, 'N');
                //  $fpdi->SetFont("helvetica", "",8);
                //                 $code=Str::random(12);
                //                 $fpdi->Text(11, 277, 'document.fasttek.com.pe/verify');
                //                 $fpdi->Text(11, 280, 'código: '.$code);            
                //                 $fpdi->Text(11, 283, 'FIRMADO DIGITALMENTE POR');
                //                 $fpdi->Text(11, 286, 'RICARDO FERNANDINI BARREDA');
                //                 $fpdi->Text(11, 289, 'NOTARIO DE LIMA');
                                $fpdi->Text(11, 267, $date);
                 // $fpdi->SetFont("helvetica", "",8);        
                //  $fpdi->Text(41, 28, 'document.fasttek.com.pe/verify');
                //  $fpdi->Text(41, 31, 'FIRMADO DIGITALMENTE');
               //   $fpdi->Text(41, 34, 'código: '.$code);
                  //$prepend = "file://".$pfxCertPrivado.'.crt';                 
                 // echo  $prepend;
             // $fpdi->setSignature($prepend, $prepend, '123123123', '', 2, '','A');
             // $fpdi->setSignatureAppearance(10,245, 35, 35);    
      //     }       
      }
      $fpdi->Output($outputFile, 'D');/*  */
     // return response()->json(['success' => true, 'data' => array()]);
     return $fpdi;
  } catch (\Exception $e) {
     // static::raiseError(__METHOD__ . '(), failed to load FPDI!');
    return response()->json(['success' => false,"error"=> $e->getMessage(),"code_error"=>$e->getCode(), 'data' => array()]);
   // echo 'Caught exception: ', $e->getMessage(), "\n";
  }
}

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Document  $document
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Document $document)
    {
        //
    }
    
     public function updateDocArea(Request $request){
        $rules = [
            'iddoc'=>'required',
            'idareadoc'=>'required',
        ];
        $input     = $request->only('iddoc','idareadoc');
        $validator = Validator::make($input, $rules);
        if ($validator->fails()) {
            return response()->json(['success' => false, 'error' => $validator->messages()]);
        }
        $doc = Document::find($request->iddoc);
        if($doc){
            
            try{
            $doc->fk_idareadoc = $request->idareadoc;
            $resultado = $doc->save();
            return response()->json(['success' => $resultado]);
            } catch (\Exception $e) {
             return response()->json(['success' => false,"error"=> $e->getMessage(),"code_error"=>$e->getCode(), 'data' => array()]);
            }
            
        }else{
            return response()->json(['success' => false]);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Document  $document
     * @return \Illuminate\Http\Response
     */
    public function destroy(Document $document)
    {
        //
    }
    
  function combineImages($qrImage, $textImage) {
    $totalHeight = imagesy($qrImage) + imagesy($textImage);
    $finalImage = imagecreatetruecolor(imagesx($qrImage), $totalHeight);
    imagecopy($finalImage, $qrImage, 0, 0, 0, 0, imagesx($qrImage), imagesy($qrImage));
    imagecopy($finalImage, $textImage, 0, imagesy($qrImage), 0, 0, imagesx($textImage), imagesy($textImage));
    return $finalImage;
}

    
    public function createsello($datetimestring,$codeprinter,$codelink){
 $this->createqr($codelink); 
//---------------------------------------
// Cargar imágenes
//$qrImage = imagecreatefrompng('qr_code.png');
$qrImage = imagecreatefrompng(Storage::disk('public')->path('/qrcodes/qr_simple.png')); 
$textImage = imagecreate(350, 100); // Ajustar tamaño según el texto
$backgroundColor = imagecolorallocate($textImage, 255, 255, 255);
$textColor = imagecolorallocate($textImage, 0, 0, 0);
imagefill($textImage, 0, 0, $backgroundColor);
$font = "/home/fast/public_html/arial.ttf";
imagettftext($textImage, 8, 0, 10, 10, $textColor, $font, 'document.fasttek.com.pe/verify
código: '.$codeprinter.'
FIRMADO DIGITALMENTE POR
RICARDO FERNANDINI PINTO
COMPOSTELA E.I.R.L
'.
$datetimestring);
// Combinar imágenes
$finalImage = $this->combineImages($qrImage, $textImage);
// Mostrar imagen en el navegador
//header('Content-Type: image/png');
//imagepng($finalImage);

// Guardar imagen en archivo (opcional)
$url  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
imagepng($finalImage, $url.'/qrcodes/'.'qr_code_with_text.png');
// Liberar memoria
imagedestroy($qrImage);
imagedestroy($textImage);
imagedestroy($finalImage);
    }
    
 public function createqr($codelink)
 {
 require_once app_path('/Helpers/NewQRCode.php');
$data='https://document.fasttek.com.pe/verify/#/'.$codelink;
$options = [
    'w' => '200',
    'h' => '200',
    'wq' => '0',
     'fc' => '#00000000'
];
$generator = new \NewQRCode($data,$options);
$image = $generator->render_image();
$url  = Storage::disk('public')->getDriver()->getAdapter()->getPathPrefix();
imagepng($image, $url.'/qrcodes/'.'qr_simple.png');
imagedestroy($image);
return response()->json(['success' => true]);
 }
    
public function signdocumentAdvanced($filedoc,$passwordcer,$filedocsave,$idocument,$fkuser,$url,$namedoc){
    
require_once app_path('/Helpers/vendor/autoload.php');
 $date = Carbon::now()->format('d/m/Y H:i:s');
 $datebd =  Carbon::now()->format('Y-m-d H:i:s');
 $code=Str::random(12);
 $codelink=Str::random(40);
$this->createsello($date,$code,$codelink);
$qrImage = Storage::disk('public')->path('/qrcodes/qr_code_with_text.png');
$pfxCertPrivado = Storage::disk('public')->path('/certificates/pinto2025.pfx');
$password = "#7(Znq4KTj0sc9%w";
$passwordcer=$password;
//$file2 = $file; 
            $image = $qrImage; 
            $cer= $pfxCertPrivado;
            $file_content = file_get_contents($filedoc);
            $obj = PDFDoc::from_string($file_content);
           // echo "---objeto";
            
            if ($obj === false)
                echo "failed to parse file ";
                else {
                   // echo 'position';
             $position = [];
            $imagesize = @getimagesize($image);
            if ($imagesize === false) {
                echo "failed to open the image $image";
                return;
            }
            $pagesize = $obj->get_page_size(0);
             
            if ($pagesize === false){
                 echo 'failed to get page size';
                return ;
                 }
                 // Extraer las coordenadas de la página
// $pagesize = explode(" ", $pagesize[0]->val());
// $x0 = intval($pagesize[0]);
// $y0 = intval($pagesize[1]);
// $x1 = intval($pagesize[2]);
// $y1 = intval($pagesize[3]);

// // Calcular el ancho y la altura de la página
// $page_width = $x1 - $x0;
// $page_height = $y1 - $y0;


                  //position QR
                   $sealDocs = SealDoc::where('fk_iddoc',$idocument)->get();
                   if ($sealDocs) {
                      
                         foreach ($sealDocs as $sealDoc) {
                              if ( $sealDoc->type==1) {
//                                  $pagesize = explode(" ", $pagesize[0]->val());
// // Extrae los valores de las coordenadas de la página
// $p_x = intval($pagesize[0]); // Coordenada X inferior izquierda (normalmente 0)
// $p_y = intval($pagesize[1]); // Coordenada Y inferior izquierda (normalmente 0)
// $p_w = intval($pagesize[2]) - $p_x; // Ancho de la página
// $p_h = intval($pagesize[3]) - $p_y; // Alto de la página

// // Obtén el tamaño de la imagen
// $i_w = $imagesize[0]; // Ancho de la imagen
// $i_h = $imagesize[1]; // Alto de la imagen

// // Calcula el ratio para escalar la imagen
// $ratio_x = $p_w / $i_w;
// $ratio_y = $p_h / $i_h;
// $ratio = min($ratio_x, $ratio_y);

// // Escala la imagen
// $i_w = ($i_w * $ratio) / 4; // Ancho escalado de la imagen
// $i_h = ($i_h * $ratio) / 4; // Alto escalado de la imagen

// // Ajusta las coordenadas para la esquina superior izquierda
// $p_x = 10; // Margen izquierdo de 10 puntos (ajusta según sea necesario)
// $p_y = $p_h - $i_h - 10; // Posición Y desde la parte inferior

// // Coloca la firma en la esquina superior izquierda
// $obj->set_signature_appearance(0, [$p_x, $p_y, $p_x + $i_w, $p_y + $i_h], $image);
            
                                   $obj->set_signature_appearance(0, [ $sealDoc->ejeX,$sealDoc->ejeY, 80, 110], $image);
                              }
                         }
                   }
            // Set the image appearance and the certificate file
           // $obj->set_signature_appearance(0, [ 10, 10, 100, 150], $image);
 
                    if (!$obj->set_signature_certificate($cer,$passwordcer)) {
                        echo "not a valid certificate";
                    } else {
                       
                        $docsigned = $obj->to_pdf_file_s();
                       
                        if ($docsigned === false){
                           // echo "could not sign document";exit;   
                           echo "could not sign document";
                           return;
                        }
                        else{
                            $newObj= PDFDoc::from_string($docsigned);
                        //   Storage::disk('public')->put('/documents/'.$request->subject.'.pdf',base64_decode($request->pdf64));
                           
                        if (Storage::disk('public')->put('/documentsign/'.$namedoc, $docsigned)) {
                            
                    //guardar como true sign en Documents
                    $document = Document::find($idocument);
                     $document->fk_progres = 2;
                     $document->code_print = $code;
                     $document->code_link = $codelink;
                     $document->pathpdf=$url.'/documentsign/'.$document->uuidpdf;
                    $resultado = $document->save();
            //guardar iduser y time ,estado(firmado) id document
                 $tracedoc=TraceDocument::create(['fk_tracetype'=>4,'fk_document'=>$idocument,
            'fk_user'=>$fkuser,'date_create'=>$datebd]);
            //
                 
            // return response()->json(['success' => true,'urlcer'=>"$pfxCertPrivado", 'data' => array()]);
                            
                            // echo "Document saved successfully!\n";
                          } else {
                            echo "Error saving document!\n";
                            }
                          
                        }
                            
                    }
               
            }
    }
}
