<?php
namespace App\Http\Controllers;

use App\Models\Asset;
use App\Models\AssetCategory;
use App\Models\AssetModel;
use App\Models\AssetManufacturer;
use App\Models\AssetAssignment;
use App\Models\AssetIntervention;
use App\Models\Department;
use App\Models\User;
use Illuminate\Http\Request;

class AssetController extends Controller
{
    // ── Lista de activos ──────────────────────────────────────────────────────
    public function index()
    {
        abort_unless(auth()->user()->can('assets.index'), 403);
        $categories = AssetCategory::active()->withCount('assets')->get();
        $statuses   = Asset::$statuses;
        return view('assets.index', compact('categories', 'statuses'));
    }

    // ── Formulario crear ──────────────────────────────────────────────────────
    public function create()
    {
        abort_unless(auth()->user()->can('assets.create'), 403);
        $categories     = AssetCategory::active()->with('customFields')->get();
        $manufacturers  = AssetManufacturer::active()->get();
        $departments    = Department::active()->orderBy('name')->get();
        $users          = User::active()->orderBy('name')->get();
        return view('assets.create', compact('categories', 'manufacturers', 'departments', 'users'));
    }

    // ── Guardar activo ────────────────────────────────────────────────────────
    public function store(Request $request)
    {
        abort_unless(auth()->user()->can('assets.create'), 403);
        $data = $request->validate([
            'name'           => 'required|string|max:255',
            'serial_number'  => 'nullable|string|max:100',
            'category_id'    => 'required|exists:asset_categories,id',
            'model_id'       => 'nullable|exists:asset_models,id',
            'status'         => 'required|in:active,in_repair,in_storage,decommissioned,on_loan',
            'location'       => 'nullable|string|max:200',
            'department_id'  => 'nullable|exists:departments,id',
            'assigned_to'    => 'nullable|exists:users,id',
            'purchase_date'  => 'nullable|date',
            'purchase_price' => 'nullable|numeric|min:0',
            'warranty_until' => 'nullable|date',
            'notes'          => 'nullable|string',
        ]);

        $data['code'] = Asset::generateCode();
        $asset = Asset::create($data);

        // Guardar campos personalizados
        foreach ($request->input('custom_fields', []) as $fieldId => $value) {
            $asset->fieldValues()->updateOrCreate(
                ['field_id' => $fieldId],
                ['value' => $value]
            );
        }

        // Registrar asignación inicial si tiene usuario
        if ($data['assigned_to']) {
            AssetAssignment::create([
                'asset_id'    => $asset->id,
                'user_id'     => $data['assigned_to'],
                'assigned_by' => auth()->id(),
                'assigned_at' => now()->toDateString(),
                'reason'      => 'Asignación inicial',
            ]);
        }

        return redirect()->route('assets.show', $asset)
            ->with('success', "Activo {$asset->code} creado correctamente.");
    }

    // ── Detalle del activo ────────────────────────────────────────────────────
    public function show(Asset $asset)
    {
        abort_unless(auth()->user()->can('assets.index'), 403);
        $asset->load([
            'category.customFields', 'model.manufacturer', 'department',
            'assignedUser', 'fieldValues.field',
            'assignments.user', 'assignments.assignedBy',
            'interventions.technician', 'tickets.status', 'tickets.priority'
        ]);
        $users = User::active()->orderBy('name')->get();
        return view('assets.show', compact('asset', 'users'));
    }

    // ── Formulario editar ─────────────────────────────────────────────────────
    public function edit(Asset $asset)
    {
        abort_unless(auth()->user()->can('assets.edit'), 403);
        $categories    = AssetCategory::active()->with('customFields')->get();
        $manufacturers = AssetManufacturer::active()->get();
        $departments   = Department::active()->orderBy('name')->get();
        $users         = User::active()->orderBy('name')->get();
        $asset->load(['fieldValues', 'category.customFields']);
        return view('assets.edit', compact('asset', 'categories', 'manufacturers', 'departments', 'users'));
    }

    // ── Actualizar activo ─────────────────────────────────────────────────────
    public function update(Request $request, Asset $asset)
    {
        abort_unless(auth()->user()->can('assets.edit'), 403);
        $data = $request->validate([
            'name'           => 'required|string|max:255',
            'serial_number'  => 'nullable|string|max:100',
            'category_id'    => 'required|exists:asset_categories,id',
            'model_id'       => 'nullable|exists:asset_models,id',
            'status'         => 'required|in:active,in_repair,in_storage,decommissioned,on_loan',
            'location'       => 'nullable|string|max:200',
            'department_id'  => 'nullable|exists:departments,id',
            'assigned_to'    => 'nullable|exists:users,id',
            'purchase_date'  => 'nullable|date',
            'purchase_price' => 'nullable|numeric|min:0',
            'warranty_until' => 'nullable|date',
            'notes'          => 'nullable|string',
        ]);

        // Detectar cambio de asignación
        if ($asset->assigned_to != ($data['assigned_to'] ?? null)) {
            // Cerrar asignación anterior
            AssetAssignment::where('asset_id', $asset->id)
                ->whereNull('returned_at')->update(['returned_at' => now()->toDateString()]);
            // Abrir nueva asignación
            if (!empty($data['assigned_to'])) {
                AssetAssignment::create([
                    'asset_id'    => $asset->id,
                    'user_id'     => $data['assigned_to'],
                    'assigned_by' => auth()->id(),
                    'assigned_at' => now()->toDateString(),
                    'reason'      => $request->input('assignment_reason', 'Reasignación'),
                ]);
            }
        }

        $asset->update($data);

        // Actualizar campos personalizados
        foreach ($request->input('custom_fields', []) as $fieldId => $value) {
            $asset->fieldValues()->updateOrCreate(
                ['field_id' => $fieldId],
                ['value' => $value]
            );
        }

        return redirect()->route('assets.show', $asset)->with('success', 'Activo actualizado.');
    }

    // ── Eliminar ──────────────────────────────────────────────────────────────
    public function destroy(Asset $asset)
    {
        abort_unless(auth()->user()->can('assets.delete'), 403);
        $asset->delete();
        return redirect()->route('assets.index')->with('success', "Activo {$asset->code} eliminado.");
    }

    // ── Agregar intervención ──────────────────────────────────────────────────
    public function addIntervention(Request $request, Asset $asset)
    {
        abort_unless(auth()->user()->can('assets.edit'), 403);
        $data = $request->validate([
            'type'              => 'required|in:maintenance,repair,upgrade,inspection',
            'title'             => 'required|string|max:255',
            'description'       => 'required|string',
            'cost'              => 'nullable|numeric|min:0',
            'intervention_date' => 'required|date',
            'status_after'      => 'nullable|string',
        ]);

        $data['asset_id']      = $asset->id;
        $data['technician_id'] = auth()->id();
        $data['status_before'] = $asset->status;

        AssetIntervention::create($data);

        if (!empty($data['status_after']) && $data['status_after'] !== $asset->status) {
            $asset->update(['status' => $data['status_after']]);
        }

        return back()->with('success', 'Intervención registrada.');
    }
}
