<?php

namespace App\Livewire\LicenseTokens;

use App\Models\Clients\Client;
use App\Models\Environments\Environment;
use App\Models\Products\LicenseToken;
use App\Models\Products\Product;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use Livewire\WithPagination;

class CreateWizard extends Component
{
    use WithPagination;

    public int $currentStep = 1;
    public bool $autoGenerateToken = true;
    public ?string $token = null;
    public ?int $clientId = null;
    public ?string $name = null;
    public string $clientSearchQuery = '';
    public ?string $startAt = null;
    public ?string $endAt = null;
    public ?string $observation = null;
    public string $environmentMode = 'existing';
    public array $selectedEnvironmentIds = [];
    public array $newEnvironmentData = [];
    public array $selectedProductIds = [];
    public ?int $createdLicenseTokenId = null;

    protected $paginationTheme = 'tailwind';

    protected $listeners = [
        'modeChanged',
        'environmentsSelected',
        'newEnvironmentDataUpdated',
        'productsSelected',
    ];

    public function mount()
    {
        $this->currentStep = 1;
        $this->autoGenerateToken = true;
        $this->generateToken(); // Generar token automáticamente al inicio
        $this->newEnvironmentData = [
            'name' => '',
            'domain' => '',
            'description' => null,
            'version' => '',
            'env' => 'local',
            'type_id' => null,
        ];
    }

    public function updatedAutoGenerateToken()
    {
        if ($this->autoGenerateToken) {
            $this->generateToken();
        } else {
            $this->token = null;
        }
    }

    public function updatedClientId()
    {
        // Limpiar entornos seleccionados cuando cambia el cliente
        $this->selectedEnvironmentIds = [];
        $this->newEnvironmentData = [
            'name' => '',
            'domain' => '',
            'description' => null,
            'version' => '',
            'env' => 'local',
            'type_id' => null,
        ];
    }

    public function updatedClientSearchQuery()
    {
        // Resetear paginación cuando cambia la búsqueda
        $this->resetPage();
    }

    public function getClientsProperty()
    {
        $query = Client::query();

        if (!empty($this->clientSearchQuery)) {
            $query->where(function($q) {
                $q->where('name', 'like', '%' . $this->clientSearchQuery . '%')
                  ->orWhere('shortname', 'like', '%' . $this->clientSearchQuery . '%');
            });
        }

        return $query->orderBy('name')->paginate(10);
    }

    public function updatedStartAt()
    {
        // Auto-completar endAt = startAt + 1 año
        if ($this->startAt) {
            $startDate = \Carbon\Carbon::parse($this->startAt);
            $this->endAt = $startDate->addYear()->format('Y-m-d');
        }
    }

    public function modeChanged($mode)
    {
        $this->environmentMode = $mode;
    }

    public function environmentsSelected($ids)
    {
        $this->selectedEnvironmentIds = $ids;
    }

    public function newEnvironmentDataUpdated($data)
    {
        $this->newEnvironmentData = $data;
    }

    public function productsSelected($ids)
    {
        $this->selectedProductIds = $ids;
    }

    public function generateToken()
    {
        $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

        do {
            // Generar token con patrón: 3IP-XXXX-XXXX-XXXX-XXXX
            $blocks = [];
            for ($i = 0; $i < 4; $i++) {
                $block = '';
                for ($j = 0; $j < 4; $j++) {
                    $block .= $characters[random_int(0, strlen($characters) - 1)];
                }
                $blocks[] = $block;
            }
            $generatedToken = '3IP-' . implode('-', $blocks);
        } while (LicenseToken::where('token', $generatedToken)->exists());

        $this->token = $generatedToken;
    }

    public function nextStep()
    {
        // Validar según el step actual
        if ($this->currentStep === 1) {
            $this->validateStep1();
        } elseif ($this->currentStep === 2) {
            $this->validateStep2();
        } elseif ($this->currentStep === 3) {
            $this->validateStep3();
        }

        if ($this->currentStep < 4) {
            $this->currentStep++;
        }
    }

    public function previousStep()
    {
        if ($this->currentStep > 1) {
            $this->currentStep--;
        }
    }

    protected function validateStep1()
    {
        $this->validate([
            'clientId' => 'required|exists:clients,id',
            'name' => 'nullable|string|max:255',
            'token' => 'required|string|max:100|unique:license_tokens,token',
            'startAt' => 'nullable|date',
            'endAt' => 'nullable|date|after_or_equal:startAt',
            'observation' => 'nullable|string',
        ], [], [
            'clientId' => 'cliente',
            'name' => 'nombre',
            'token' => 'token',
            'startAt' => 'fecha de inicio',
            'endAt' => 'fecha de fin',
        ]);
    }

    protected function validateStep2()
    {
        if ($this->environmentMode === 'existing') {
            $this->validate([
                'selectedEnvironmentIds' => 'required|array|min:1',
                'selectedEnvironmentIds.*' => 'exists:environments,id',
            ], [], [
                'selectedEnvironmentIds' => 'entornos',
            ]);
        } else {
            $this->validate([
                'newEnvironmentData.name' => 'required|string|max:255',
                'newEnvironmentData.domain' => 'required|string|max:255|unique:environments,domain',
                'newEnvironmentData.description' => 'nullable|string',
                'newEnvironmentData.version' => 'required|string|max:50',
                'newEnvironmentData.env' => 'required|string|in:local,develop,pre,pro',
                'newEnvironmentData.type_id' => 'nullable|exists:types,id',
            ], [], [
                'newEnvironmentData.name' => 'nombre',
                'newEnvironmentData.domain' => 'dominio',
                'newEnvironmentData.version' => 'versión',
                'newEnvironmentData.env' => 'desarrollo',
            ]);
        }
    }

    protected function validateStep3()
    {
        $this->validate([
            'selectedProductIds' => 'required|array|min:1',
            'selectedProductIds.*' => 'exists:products,id',
        ], [], [
            'selectedProductIds' => 'productos',
        ]);
    }

    public function saveLicense()
    {
        // Validar todos los pasos
        $this->validateStep1();
        $this->validateStep2();
        $this->validateStep3();

        // Crear el entorno si es nuevo (justo antes de crear la licencia)
        if ($this->environmentMode === 'new' && !empty($this->newEnvironmentData['name'])) {
            // Validar datos del nuevo entorno
            $this->validate([
                'newEnvironmentData.name' => 'required|string|max:255',
                'newEnvironmentData.domain' => 'required|string|max:255|unique:environments,domain',
                'newEnvironmentData.description' => 'nullable|string',
                'newEnvironmentData.version' => 'required|string|max:50',
                'newEnvironmentData.env' => 'required|string|in:local,develop,pre,pro',
                'newEnvironmentData.type_id' => 'nullable|exists:types,id',
            ], [], [
                'newEnvironmentData.name' => 'nombre',
                'newEnvironmentData.domain' => 'dominio',
                'newEnvironmentData.version' => 'versión',
                'newEnvironmentData.env' => 'desarrollo',
            ]);

            $data = $this->newEnvironmentData;
            $data['client_id'] = $this->clientId;
            $data['active'] = true;
            $environment = Environment::create($data);
            $this->selectedEnvironmentIds = [$environment->id];
        }

        // Crear la licencia
        $licenseToken = LicenseToken::create([
            'client_id' => $this->clientId,
            'name' => $this->name,
            'token' => $this->token,
            'active' => true,
            'start_at' => $this->startAt ? \Carbon\Carbon::parse($this->startAt) : null,
            'end_at' => $this->endAt ? \Carbon\Carbon::parse($this->endAt) : null,
            'observation' => $this->observation,
            'created_by' => Auth::id(),
        ]);

        // Asociar productos
        if (!empty($this->selectedProductIds)) {
            $syncData = [];
            foreach ($this->selectedProductIds as $productId) {
                $syncData[$productId] = [
                    'status' => 'active',
                    'assigned_by' => Auth::id(),
                ];
            }
            $licenseToken->products()->sync($syncData);
        }

        // Asociar entornos
        if (!empty($this->selectedEnvironmentIds)) {
            Environment::whereIn('id', $this->selectedEnvironmentIds)
                ->update(['license_token_id' => $licenseToken->id]);
        }

        $this->createdLicenseTokenId = $licenseToken->id;
        $this->currentStep = 5;
    }

    public function render()
    {
        return view('livewire.license-tokens.create-wizard')->layout('layouts.clean');
    }
}

