<?php

namespace App\Jobs;

use App\Services\Facturapi\FacturapiCustomerService;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

use Throwable;

use App\Models\Hotel\Client;

class SyncFacturapiCustomerId implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     */
    public function __construct() {}

    /**
     * Execute the job.
     */
    public function handle(FacturapiCustomerService $facturapi): void
    {
      // Counters
        $total_updated = 0;
        $total_errors = 0;
        $total_not_fount = 0;

      // Get Facturapi Costumer's Data
        $customers = collect($facturapi->getAllCustomers()['data'])
            // ->reject(fn ($customer) => in_array( // Avoid generic RFCs
                // $customer['tax_id'], [ 'XAXX010101000', 'XEXX010101000' ])
            // )
            ->sortByDesc('created_at')
            ->groupBy('tax_id')
            ->map(fn ($group) => $group->first());

      // Select and Update Local Clients Data
        $customers
            ->sortByDesc('created_at')
            ->each(function ($customer) use (&$total_updated, &$total_errors, &$total_not_fount) {

              // Search Client on Local
                $client = Client::firstWhere('tax_id', $customer['tax_id']);

                if(!$client) { // If records doesn't exist on DB
                    $total_not_fount++; return; // Increment no fount data
                }

              // Update Facturapi_Customer_UUID
                $old_id = $client->facturapi_customer_id;

                try{
                    $client->update([
                        'facturapi_customer_id' => $customer['id']
                    ]);

                    $total_updated++; // Increment updated data

                    Log::channel('tax_patches')->info(
                        'Cliente sincronizado con su facturapi_customer_id',
                        [
                            'client_id' => $client->id,
                            'legal_name' => $client->legal_name,
                            'tax_id' => $client->tax_id,
                            'old_id' => $old_id,
                            'new_id' => $customer['id'],
                            'status' => 'success',
                            'changed_at' => now()->toDateTimeString(),
                    ]);
                }catch(Throwable $th){
                    $total_errors++; // Increment error count

                    Log::channel('tax_patches')->error(
                        'Error al sincronizar facturapi_customer_id con el cliente',
                        [
                            'client_id' => $client->id,
                            'legal_name' => $client->legal_name,
                            'tax_id' => $client->tax_id,
                            'old_id' => $old_id,
                            'new_id' => $customer['id'],
                            'status' => 'error',
                            'messages' => $th->getMessage(),
                            'changed_at' => now()->toDateTimeString(),
                    ]);
                }
            });

        // Final summary
        Log::channel('tax_patches')->info(
            'Resumen de sincronización de facturapi_customer_id',
            [
                'summary' => true,
                'processed' => $customers->count(),
                'updated' => $total_updated,
                'errors' => $total_errors,
                'not_found' => $total_not_fount,
                'date' => now()->toDateTimeString(),
        ]);
    }
}
