<?php

namespace App\Livewire\LicenseTokens;

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

class Show extends Component
{
    public LicenseToken $licenseToken;
    public array $selectedProducts = [];
    public array $selectedEnvironments = [];

    // Propiedades para el formulario de nuevo entorno
    public string $newEnvironmentName = '';
    public string $newEnvironmentDomain = '';
    public ?string $newEnvironmentDescription = null;
    public ?int $newEnvironmentTypeId = null;
    public string $newEnvironmentVersion = '';
    public string $newEnvironmentEnv = 'local';
    public ?int $newEnvironmentHosting = null; // Por ahora nullable hasta confirmar qué es

    public function mount(LicenseToken $license_token)
    {
        $this->licenseToken = $license_token->load(['client', 'products', 'environments.type']);
        // Inicializar los arrays con los valores actuales
        $this->selectedProducts = $this->licenseToken->products->pluck('id')->toArray();
        $this->selectedEnvironments = $this->licenseToken->environments->pluck('id')->toArray();
    }

    public function toggleProduct($productId)
    {
        $isLinked = $this->licenseToken->products->contains('id', $productId);

        if ($isLinked) {
            // Desvincular producto del token
            $this->licenseToken->products()->detach($productId);
        } else {
            // Vincular producto al token
            $this->licenseToken->products()->syncWithoutDetaching([
                $productId => [
                    'status' => 'active',
                    'assigned_by' => Auth::id(),
                ]
            ]);
        }

        // Refrescar la relación
        $this->licenseToken->refresh();
        $this->licenseToken->load('products');
    }

    public function isProductLinked($productId): bool
    {
        return $this->licenseToken->products->contains('id', $productId);
    }

    public function saveProducts(array $productIds)
    {
        // Obtener los IDs de productos actualmente vinculados
        $currentProductIds = $this->licenseToken->products->pluck('id')->toArray();

        // Productos a agregar (están en $productIds pero no en $currentProductIds)
        $productsToAdd = array_diff($productIds, $currentProductIds);

        // Productos a eliminar (están en $currentProductIds pero no en $productIds)
        $productsToRemove = array_diff($currentProductIds, $productIds);

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

        // Eliminar productos desvinculados
        if (!empty($productsToRemove)) {
            $this->licenseToken->products()->detach($productsToRemove);
        }

        // Refrescar la relación
        $this->licenseToken->refresh();
        $this->licenseToken->load('products');

        // Actualizar el array de productos seleccionados
        $this->selectedProducts = $this->licenseToken->products->pluck('id')->toArray();
    }

    public function toggleActive()
    {
        $this->licenseToken->active = !$this->licenseToken->active;
        $this->licenseToken->save();
        $this->licenseToken->refresh();
    }

    public function saveEnvironments(array $environmentIds)
    {
        // Obtener los IDs de entornos actualmente vinculados
        $currentEnvironmentIds = $this->licenseToken->environments->pluck('id')->toArray();

        // Entornos a agregar (están en $environmentIds pero no en $currentEnvironmentIds)
        $environmentsToAdd = array_diff($environmentIds, $currentEnvironmentIds);

        // Entornos a eliminar (están en $currentEnvironmentIds pero no en $environmentIds)
        $environmentsToRemove = array_diff($currentEnvironmentIds, $environmentIds);

        // Agregar nuevos entornos (vincular al token)
        if (!empty($environmentsToAdd)) {
            Environment::whereIn('id', $environmentsToAdd)
                ->update(['license_token_id' => $this->licenseToken->id]);
        }

        // Eliminar entornos desvinculados (poner license_token_id a null)
        if (!empty($environmentsToRemove)) {
            Environment::whereIn('id', $environmentsToRemove)
                ->update(['license_token_id' => null]);
        }

        // Refrescar la relación y el modelo completo
        $this->licenseToken->refresh();
        $this->licenseToken->load(['environments.type', 'client', 'products']);

        // Actualizar el array de entornos seleccionados
        $this->selectedEnvironments = $this->licenseToken->environments->pluck('id')->toArray();
    }

    public function createNewEnvironment()
    {
        $this->validate([
            'newEnvironmentName' => 'required|string|max:255',
            'newEnvironmentDomain' => 'required|string|max:255|unique:environments,domain',
            'newEnvironmentDescription' => 'nullable|string',
            'newEnvironmentTypeId' => 'nullable|exists:types,id',
            'newEnvironmentVersion' => 'required|string|max:50',
            'newEnvironmentEnv' => 'required|string|in:local,develop,pre,pro',
        ]);

        $environment = Environment::create([
            'name' => $this->newEnvironmentName,
            'domain' => $this->newEnvironmentDomain,
            'description' => $this->newEnvironmentDescription,
            'type_id' => $this->newEnvironmentTypeId,
            'version' => $this->newEnvironmentVersion,
            'env' => $this->newEnvironmentEnv,
            'client_id' => $this->licenseToken->client_id,
            'license_token_id' => $this->licenseToken->id,
            'active' => true,
        ]);

        // Limpiar el formulario
        $this->resetNewEnvironmentForm();

        // Refrescar la relación
        $this->licenseToken->refresh();
        $this->licenseToken->load('environments.type');

        // Actualizar selectedEnvironments con los valores actuales
        $this->selectedEnvironments = $this->licenseToken->environments->pluck('id')->toArray();

        // Emitir evento para cambiar a la vista de entornos existentes
        $this->dispatch('environment-created');
    }

    public function resetNewEnvironmentForm()
    {
        $this->newEnvironmentName = '';
        $this->newEnvironmentDomain = '';
        $this->newEnvironmentDescription = null;
        $this->newEnvironmentTypeId = null;
        $this->newEnvironmentVersion = '';
        $this->newEnvironmentEnv = 'local';
        $this->newEnvironmentHosting = null;
    }

    public function render()
    {
        $allProducts = Product::all();
        // Obtener todos los entornos del cliente asociado al token
        $allEnvironments = Environment::with('type')
            ->where('client_id', $this->licenseToken->client_id)
            ->orderBy('name')
            ->get()
            ->map(function ($environment) {
                // Agregar información sobre si está asociado a otro token
                $environment->is_associated_to_other = $environment->license_token_id &&
                                                $environment->license_token_id !== $this->licenseToken->id;
                return $environment;
            });

        return view('livewire.license-tokens.show', [
            'allProducts' => $allProducts,
            'allEnvironments' => $allEnvironments,
            'environmentTypes' => Type::orderBy('name')->get(),
            'environmentEnvironments' => Environment::ENVIRONMENTS,
        ])->layout('layouts.app');
    }
}

