<?php

namespace App\Livewire\ScssCdn;

use App\Models\Products\Product;
use App\Models\ScssCdn\ScssCdnBundle;
use App\Models\ScssCdn\ScssCdnFile;
use App\Services\ScssCdn\ScssCdnUrlService;
use Livewire\Component;

class BundleShow extends Component
{
    public Product $product;
    public ScssCdnBundle $bundle;
    public $selectedFiles = []; // Para borrado masivo
    public bool $selectAll = false;
    public bool $makeAllServable = false;

    public function mount(Product $product, ScssCdnBundle $bundle)
    {
        $this->product = $product;
        $this->bundle = $bundle->load(['product', 'creator', 'updater', 'files']);
        
        // Verificar que el bundle pertenezca al producto
        if ($this->bundle->product_id !== $this->product->id) {
            abort(404, 'El bundle no pertenece a este producto.');
        }
    }

    public function toggleServable($fileId)
    {
        $file = ScssCdnFile::findOrFail($fileId);
        
        if ($file->scss_cdn_bundle_id !== $this->bundle->id) {
            session()->flash('error', 'El archivo no pertenece a este bundle.');
            return;
        }

        $file->update([
            'is_servable' => !$file->is_servable,
            'updated_by' => auth()->id(),
        ]);

        $this->bundle->refresh();
        session()->flash('success', 'Estado del archivo actualizado.');
    }

    public function duplicateBundle()
    {
        try {
            $newBundle = $this->bundle->duplicate();
            session()->flash('success', "Bundle duplicado. Nueva versión: {$newBundle->version}");
            return $this->redirect(route('products.scss-cdn.bundle.show', [$this->product, $newBundle]), navigate: true);
        } catch (\Exception $e) {
            session()->flash('error', 'Error al duplicar el bundle: ' . $e->getMessage());
        }
    }

    public function deleteFile($fileId)
    {
        try {
            $file = ScssCdnFile::findOrFail($fileId);
            
            if ($file->scss_cdn_bundle_id !== $this->bundle->id) {
                session()->flash('error', 'El archivo no pertenece a este bundle.');
                return;
            }

            // Eliminar archivo físico
            \App\Services\ScssCdn\ScssCdnStorageService::deleteFile(
                $this->product,
                $this->bundle,
                $file->relative_path
            );

            // Eliminar de BD
            $file->delete();

            $this->bundle->refresh();
            $this->selectedFiles = array_diff($this->selectedFiles, [$fileId]);
            session()->flash('success', 'Archivo eliminado correctamente.');
        } catch (\Exception $e) {
            session()->flash('error', 'Error al eliminar el archivo: ' . $e->getMessage());
        }
    }

    public function toggleSelectFile($fileId)
    {
        if (in_array($fileId, $this->selectedFiles)) {
            $this->selectedFiles = array_diff($this->selectedFiles, [$fileId]);
        } else {
            $this->selectedFiles[] = $fileId;
        }
    }

    public function updatedSelectAll($value)
    {
        if ($value) {
            $this->selectedFiles = $this->bundle->files->pluck('id')->toArray();
        } else {
            $this->selectedFiles = [];
        }
    }

    public function updatedMakeAllServable($value)
    {
        try {
            $this->bundle->files()->update([
                'is_servable' => $value,
                'updated_by' => auth()->id(),
            ]);

            $this->bundle->refresh();
            $status = $value ? 'servibles' : 'no servibles';
            session()->flash('success', "Todos los archivos marcados como {$status}.");
        } catch (\Exception $e) {
            session()->flash('error', 'Error al actualizar archivos: ' . $e->getMessage());
            // Revertir el estado del checkbox si hay error
            $this->makeAllServable = !$value;
        }
    }

    /**
     * Calcula si todos los archivos están marcados como servibles
     */
    public function getAllServableProperty()
    {
        $files = $this->bundle->files;
        if ($files->isEmpty()) {
            return false;
        }
        return $files->every(fn($file) => $file->is_servable);
    }

    public function deleteSelectedFiles()
    {
        if (empty($this->selectedFiles)) {
            session()->flash('error', 'No hay archivos seleccionados para eliminar.');
            return;
        }

        $deletedCount = 0;
        $errors = [];

        foreach ($this->selectedFiles as $fileId) {
            try {
                $file = ScssCdnFile::find($fileId);
                
                if (!$file || $file->scss_cdn_bundle_id !== $this->bundle->id) {
                    continue;
                }

                // Eliminar archivo físico
                \App\Services\ScssCdn\ScssCdnStorageService::deleteFile(
                    $this->product,
                    $this->bundle,
                    $file->relative_path
                );

                // Eliminar de BD
                $file->delete();
                $deletedCount++;
            } catch (\Exception $e) {
                $errors[] = "Error al eliminar archivo ID {$fileId}: " . $e->getMessage();
            }
        }

        $this->selectedFiles = [];
        $this->selectAll = false;
        $this->bundle->refresh();

        if ($deletedCount > 0) {
            $message = "Se eliminaron {$deletedCount} archivo(s) correctamente.";
            if (!empty($errors)) {
                $message .= ' Errores: ' . implode(', ', array_slice($errors, 0, 3));
            }
            session()->flash('success', $message);
        } else {
            session()->flash('error', 'No se pudo eliminar ningún archivo.');
        }
    }

    public function getFileUrl($fileId)
    {
        $file = ScssCdnFile::find($fileId);
        if (!$file) {
            return null;
        }
        return ScssCdnUrlService::getFileUrl($file);
    }

    public function render()
    {
        $files = $this->bundle->files()->orderBy('relative_path')->get();
        $servableFiles = $this->bundle->files()->servable()->orderBy('relative_path')->get();
        
        // Sincronizar el estado del checkbox con el estado real
        $this->makeAllServable = $this->allServable;
        
        // Organizar archivos en estructura de árbol
        $tree = $this->buildFileTree($files);

        return view('livewire.scss-cdn.bundle-show', [
            'files' => $files,
            'servableFiles' => $servableFiles,
            'tree' => $tree,
        ])->layout('layouts.app');
    }

    /**
     * Construye estructura de árbol de archivos
     */
    private function buildFileTree($files)
    {
        $tree = [];

        foreach ($files as $file) {
            $pathParts = explode('/', $file->relative_path);
            $current = &$tree;

            foreach ($pathParts as $index => $part) {
                if ($index === count($pathParts) - 1) {
                    // Es el archivo final
                    $current['_files'][] = $file;
                } else {
                    // Es un directorio
                    if (!isset($current[$part])) {
                        $current[$part] = ['_files' => []];
                    }
                    $current = &$current[$part];
                }
            }
        }

        return $tree;
    }
}
