<?php

namespace App\Livewire\Projects\Traits;

use App\Models\Feature;
use App\Models\Inspection;
use App\Models\InspectionTemplate;
use App\Models\Issue;
use App\Notifications\InspectionCompletedNotification;
use App\Notifications\InspectionDeletedNotification;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Livewire\Attributes\On;

trait MapInspections
{
    public $templates = [];

    public $selectedTemplateId = null;

    public $inspectionFormData = [];

    public $inspectionHistory = [];

    // Inspection workflow
    public $inspectionResult = '';

    public $inspectionNotes = '';

    public $inspectionPhotos = [];

    // Inspection viewer
    public $viewingInspection = null;

    // Inspection editor (para editar inspecciones existentes)
    public $editingInspection = null;

    public $editInspectionFormData = [];

    public $editInspectionResult = '';

    public $editInspectionNotes = '';

    public $editInspectionPhotos = [];

    public $editInspectionPhotosToDelete = [];

    public function loadTemplates()
    {
        // Las plantillas son globales; cada proyecto elige cuáles usa (pivot).
        $this->templates = $this->project->inspectionTemplates()
            ->orderBy('inspection_templates.name')
            ->get();
    }

    public function loadInspectionHistory()
    {
        if (! $this->selectedFeature) {
            $this->inspectionHistory = [];

            return;
        }
        $this->inspectionHistory = Inspection::where('feature_id', $this->selectedFeature->id)
            ->with('user', 'template')
            ->orderBy('created_at', 'desc')
            ->get();
    }

    public function resetInspectionForm()
    {
        $this->inspectionFormData = [];
        $this->inspectionResult = '';
        $this->inspectionNotes = '';
        $this->inspectionPhotos = [];
        if ($this->selectedTemplateId) {
            $template = InspectionTemplate::find($this->selectedTemplateId);
            if ($template) {
                foreach ($template->fields as $field) {
                    $this->inspectionFormData[$field['name']] = '';
                }
            }
        }
    }

    public function saveInspection()
    {
        if (! $this->selectedFeature || ! $this->selectedTemplateId) {
            $this->dispatch('notify', 'Selecciona un elemento y un template.');

            return;
        }

        // Verificar permiso
        if (! auth()->user()->can('create inspections')) {
            $this->dispatch('notify', 'Sin permisos para crear inspecciones.');

            return;
        }

        $feature = Feature::with('layer.phase')->find($this->selectedFeature->id);
        if (! $feature || $feature->layer->phase->project_id !== $this->project->id) {
            abort(403);
        }

        $this->validate([
            'selectedTemplateId' => 'required|exists:inspection_templates,id',
            'inspectionPhotos.*' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:10240',
        ]);

        $template = InspectionTemplate::find($this->selectedTemplateId);
        foreach ($template->fields as $field) {
            if (($field['required'] ?? false) && empty($this->inspectionFormData[$field['name']])) {
                $this->dispatch('notify', "El campo {$field['label']} es obligatorio.");

                return;
            }
        }

        $inspection = Inspection::create([
            'project_id' => $this->project->id,
            'layer_id' => $this->selectedFeature->layer_id,
            'feature_id' => $this->selectedFeature->id,
            'template_id' => $this->selectedTemplateId,
            'user_id' => auth()->id(),
            'inspector_user_id' => auth()->id(),
            'status' => 'completed',
            'completed_at' => now(),
            'result' => $this->inspectionResult ?: null,
            'notes' => $this->inspectionNotes ?: null,
            'data' => $this->inspectionFormData,
        ]);

        // Fotos adjuntas a la inspección
        foreach ($this->inspectionPhotos as $photo) {
            $mime = $photo->getMimeType();
            $path = $photo->store("uploads/inspections/{$inspection->id}", 'public');
            $inspection->media()->create([
                'name' => $photo->getClientOriginalName(),
                'file_path' => $path,
                'file_type' => $mime,
                'file_extension' => $photo->getClientOriginalExtension(),
                'file_size' => $photo->getSize(),
                'category' => str_starts_with($mime, 'image/') ? 'image' : 'document',
                'uploaded_by' => auth()->id(),
                'uuid' => (string) Str::uuid(),
            ]);
        }

        if ($this->inspectionResult === 'fail') {
            Issue::create([
                'project_id' => $this->project->id,
                'feature_id' => $this->selectedFeature->id,
                'inspection_id' => $inspection->id,
                'title' => 'Fallo en inspección: '.($template->name ?? 'Sin nombre'),
                'description' => $this->inspectionNotes,
                'priority' => 'high',
                'status' => 'open',
                'reported_by' => auth()->id(),
            ]);
            $this->openIssuesCount = Issue::where('project_id', $this->project->id)
                ->where('status', 'open')->count();
            $this->dispatch('notify', 'Inspección fallida — Issue creado automáticamente');
        } else {
            if (isset($this->inspectionFormData['progress'])) {
                $this->updateProgress($this->selectedFeature->id, (int) $this->inspectionFormData['progress'], 'Inspección registrada');
            }
            $this->dispatch('notify', 'Inspección guardada correctamente');
        }

        // Notificar a usuarios del proyecto (excepto creador)
        $usersToNotify = $this->project->users()
            ->where('user_id', '!=', auth()->id())
            ->get();
        foreach ($usersToNotify as $user) {
            $user->notify(new InspectionCompletedNotification($inspection));
        }

        // Reload global list
        $this->allInspections = Inspection::where('project_id', $this->project->id)
            ->with(['feature.layer.phase', 'template', 'user'])
            ->orderBy('created_at', 'desc')
            ->get();

        $this->loadInspectionHistory();
        $this->resetInspectionForm();
    }

    public function assignTemplateToFeature($templateId)
    {
        if (! $this->selectedFeature) {
            return;
        }
        $template = InspectionTemplate::where('id', $templateId)
            ->where('project_id', $this->project->id)->first();
        if (! $template) {
            abort(403);
        }
        $feature = Feature::findOrFail($this->selectedFeature->id);
        $feature->template_id = $templateId;
        $feature->save();
        $this->selectedFeature = $feature;
        $this->selectedTemplateId = $templateId;
        $this->resetInspectionForm();
        $this->dispatch('notify', 'Template asignado al elemento');
    }

    // ─── Inspection viewer ──────────────────────────────────────────────────────

    #[On('map-view-inspection')]
    public function viewInspection($id)
    {
        $ins = Inspection::where('project_id', $this->project->id)
            ->with(['feature.layer.phase', 'template', 'user', 'media'])
            ->find($id);
        if (! $ins) {
            return;
        }
        $this->viewingInspection = [
            'id' => $ins->id,
            'feature_name' => $ins->feature?->name ?? '—',
            'layer_name' => $ins->feature?->layer?->name ?? '—',
            'phase_name' => $ins->feature?->layer?->phase?->name ?? '—',
            'template_name' => $ins->template?->name ?? '—',
            'user_name' => $ins->user?->name ?? '—',
            'date' => $ins->created_at->format('d/m/Y H:i'),
            'status' => $ins->status,
            'result' => $ins->result,
            'notes' => $ins->notes,
            'data' => $ins->data ?? [],
            'fields' => $ins->template?->fields ?? [],
            'photos' => $ins->media->map(fn ($m) => ['url' => $m->url, 'name' => $m->name, 'id' => $m->id])->values()->all(),
        ];
    }

    public function closeViewInspection()
    {
        $this->viewingInspection = null;
    }

    // ─── Inspection Editor (editar inspección existente) ─────────────────────────

    #[On('edit-inspection')]
    public function editInspection($id)
    {
        $ins = Inspection::where('project_id', $this->project->id)
            ->with(['feature.layer.phase', 'template', 'user', 'media'])
            ->find($id);
        if (! $ins) {
            return;
        }

        $this->editingInspection = $ins;
        $this->editInspectionFormData = $ins->data ?? [];
        $this->editInspectionResult = $ins->result ?? '';
        $this->editInspectionNotes = $ins->notes ?? '';
        $this->editInspectionPhotos = [];
        $this->editInspectionPhotosToDelete = [];
        $this->selectedTemplateId = $ins->template_id;

        $this->dispatch('openEditInspectionModal');
    }

    public function closeEditInspection()
    {
        $this->editingInspection = null;
        $this->editInspectionFormData = [];
        $this->editInspectionResult = '';
        $this->editInspectionNotes = '';
        $this->editInspectionPhotos = [];
        $this->editInspectionPhotosToDelete = [];
    }

    public function deleteEditPhoto($mediaIndex)
    {
        if (! $this->editingInspection) {
            return;
        }
        $media = $this->editingInspection->media;
        if (isset($media[$mediaIndex])) {
            $m = $media[$mediaIndex];
            if (! in_array($m->id, $this->editInspectionPhotosToDelete)) {
                $this->editInspectionPhotosToDelete[] = $m->id;
            }
        }
    }

    public function saveEditInspection()
    {
        if (! $this->editingInspection) {
            return;
        }

        // Verificar permiso
        if (! auth()->user()->can('edit inspections')) {
            $this->dispatch('notify', 'Sin permisos para editar inspecciones.');

            return;
        }

        $this->validate([
            'selectedTemplateId' => 'required|exists:inspection_templates,id',
            'editInspectionPhotos.*' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:10240',
            'editInspectionPhotosToDelete' => 'array',
            'editInspectionPhotosToDelete.*' => 'exists:media,id',
        ]);

        $ins = $this->editingInspection;
        if ($ins->project_id !== $this->project->id) {
            abort(403);
        }

        $template = InspectionTemplate::find($this->selectedTemplateId);
        foreach ($template->fields as $field) {
            if (($field['required'] ?? false) && empty($this->editInspectionFormData[$field['name']])) {
                $this->dispatch('notify', "El campo {$field['label']} es obligatorio.");

                return;
            }
        }

        // Eliminar fotos marcadas
        if (! empty($this->editInspectionPhotosToDelete)) {
            $mediaToDelete = \App\Models\Media::whereIn('id', $this->editInspectionPhotosToDelete)
                ->where('mediable_type', Inspection::class)
                ->where('mediable_id', $ins->id)
                ->get();
            foreach ($mediaToDelete as $m) {
                $m->delete();
            }
        }

        // Actualizar datos
        $ins->update([
            'template_id' => $this->selectedTemplateId,
            'result' => $this->editInspectionResult ?: null,
            'notes' => $this->editInspectionNotes ?: null,
            'data' => $this->editInspectionFormData,
        ]);

        // Añadir nuevas fotos
        foreach ($this->editInspectionPhotos as $photo) {
            $mime = $photo->getMimeType();
            $path = $photo->store("uploads/inspections/{$ins->id}", 'public');
            $ins->media()->create([
                'name' => $photo->getClientOriginalName(),
                'file_path' => $path,
                'file_type' => $mime,
                'file_extension' => $photo->getClientOriginalExtension(),
                'file_size' => $photo->getSize(),
                'category' => str_starts_with($mime, 'image/') ? 'image' : 'document',
                'uploaded_by' => auth()->id(),
                'uuid' => (string) Str::uuid(),
            ]);
        }

        // Refresh
        $this->allInspections = Inspection::where('project_id', $this->project->id)
            ->with(['feature.layer.phase', 'template', 'user'])
            ->orderBy('created_at', 'desc')
            ->get();
        $this->loadInspectionHistory();

        $this->closeEditInspection();
        $this->dispatch('notify', 'Inspección actualizada correctamente');
    }

    // ─── Delete Inspection ──────────────────────────────────────────────────────

    #[On('delete-inspection')]
    public function deleteInspection($id)
    {
        \Log::info('deleteInspection: START', ['id' => $id]);

        if (! auth()->user()->can('delete inspections')) {
            $this->dispatch('notify', 'Sin permisos para eliminar inspecciones.');
            \Log::info('deleteInspection: permission denied');

            return;
        }

        $ins = Inspection::where('project_id', $this->project->id)
            ->with(['feature', 'media'])
            ->find($id);
        if (! $ins) {
            \Log::info('deleteInspection: inspection not found', ['id' => $id]);
            $this->dispatch('notify', 'Inspección no encontrada');

            return;
        }

        \Log::info('deleteInspection: BEFORE delete', ['id' => $ins->id, 'deleted_at' => $ins->deleted_at, 'project_id' => $ins->project_id]);

        // Delete associated media files (booted event deletes physical files)
        $ins->media()->get()->each->delete();

        $result = $ins->delete();
        \Log::info('deleteInspection: delete() returned', ['result' => $result]);

        $fresh = $ins->fresh();
        \Log::info('deleteInspection: AFTER delete', ['id' => $id, 'fresh_deleted_at' => $fresh ? $fresh->deleted_at : 'null', 'fresh_exists' => $fresh ? 'yes' : 'no']);

        // Refresh lists
        $this->allInspections = Inspection::where('project_id', $this->project->id)
            ->with(['feature.layer.phase', 'template', 'user'])
            ->orderBy('created_at', 'desc')
            ->get();
        $this->loadInspectionHistory();

        $this->dispatch('notify', 'Inspección eliminada correctamente');
        \Log::info('deleteInspection: dispatched notify SUCCESS');
    }
}