<?php
namespace App\Http\Controllers;

use App\Models\Lote;
use App\Models\Urbanizacion;
use App\Models\Distrito;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class LoteController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    // ─── Listado con búsqueda ───────────────────────────────────────────────
    public function index(Request $request)
    {
        $urbanizaciones = Urbanizacion::orderBy('nombre')->get();

        $query = Lote::with(['urbanizacionRel', 'distrito']);

        // Filtros
        if ($request->filled('idlote')) {
            $query->where('id', 'like', $request->idlote . '%');
        } else {
            if ($request->filled('select1') && $request->select1 != 0)
                $query->where('urbanizacion', $request->select1);
            if ($request->filled('select2') && $request->select2 != 0)
                $query->where('relacion', $request->select2);
            if ($request->filled('select3') && $request->select3 != '0')
                $query->where('manzano', 'like', $request->select3);
        }

        $lotes = $query->orderBy('manzano')->orderBy('nombre')->paginate(50)->withQueryString();

        return view('lotes.index', compact('lotes', 'urbanizaciones'));
    }

    // ─── Ver detalle ────────────────────────────────────────────────────────
    public function show($id)
    {
        $lote = Lote::with(['urbanizacionRel', 'distrito'])->findOrFail($id);

        // Contrato activo asociado
        // OJO: la tabla contratos tiene DOS campos relacionados al lote:
        //   - idlote  → id numérico del lote (FK real, igual que el original: WHERE contratos.idlote = $idlote)
        //   - lote    → nombre alfanumérico del lote ("15", "A1", etc.)
        // Se debe buscar por idlote, NO por lote, para encontrar contratos
        // registrados tanto desde el sistema anterior como desde este sistema.
        $contrato = DB::table('contratos')
            ->join('clientes', 'contratos.idcliente', '=', 'clientes.id')
            ->where('contratos.idlote', $id)
            ->where('contratos.anul', '!=', 1)
            ->select('contratos.id as idcont', 'contratos.fecha',
                     'clientes.id as codcli', 'clientes.nombre as nomcli')
            ->first();

        return view('lotes.show', compact('lote', 'contrato'));
    }

    // ─── Formulario nuevo ───────────────────────────────────────────────────
    public function create()
    {
        $this->soloAdminOTecnico();
        $urbanizaciones = Urbanizacion::orderBy('nombre')->get();
        $nuevoId = (Lote::max('id') ?? 0) + 1;
        return view('lotes.create', compact('urbanizaciones', 'nuevoId'));
    }

    // ─── Guardar nuevo ──────────────────────────────────────────────────────
    public function store(Request $request)
    {
        $this->soloAdminOTecnico();

        $request->validate([
            'id'       => 'required|integer|unique:lotes,id',
            'select1'  => 'required|integer|not_in:0',
            'select2'  => 'required|integer|not_in:0',
            'nolote'   => 'nullable|regex:/^[0-9]{1,4}$/',
            'superficie' => 'required|numeric|min:50',
            'tipo'     => 'required|in:1,2,3',
        ], [
            'id.unique'        => 'El código de lote ya existe.',
            'select1.not_in'   => 'Debe seleccionar una urbanización.',
            'select2.not_in'   => 'Debe seleccionar un distrito.',
            'superficie.min'   => 'La superficie debe ser mínimo 50 m².',
            'tipo.required'    => 'Debe marcar el tipo de lote.',
        ]);

        // Manzano: viene del select o del campo libre
        $manzano = ($request->select3 && $request->select3 != '0')
            ? $request->select3
            : strtoupper($request->manzano ?? '');

        if (empty($manzano)) {
            return back()->withErrors(['manzano' => 'Ingrese un manzano válido.'])->withInput();
        }

        Lote::create([
            'id'          => $request->id,
            'urbanizacion'=> $request->select1,
            'relacion'    => $request->select2,
            'manzano'     => $manzano,
            'nombre'      => $request->nolote,
            'superf'      => $request->superficie,
            'itetip'      => $request->tipo,
            'iteest'      => 1, // Disponible al crear
            'alcanta'     => $request->has('alcantarillado') ? 1 : 0,
            'luz'         => $request->has('luz')            ? 1 : 0,
            'agua'        => $request->has('agua')           ? 1 : 0,
            'telef'       => $request->has('telefono')       ? 1 : 0,
            'transpor'    => $request->has('transporte')     ? 1 : 0,
            'cordon'      => $request->has('cordon')         ? 1 : 0,
            'acera'       => $request->has('acera')          ? 1 : 0,
            'muralla'     => $request->has('muralla')        ? 1 : 0,
            'observ'      => $request->observaciones,
            'plano'       => '',
        ]);

        $this->registrarSeguimiento($request->id, 1); // alta

        return redirect()->route('lotes.index')
                         ->with('success', 'Lote guardado correctamente.');
    }

    // ─── Formulario editar ──────────────────────────────────────────────────
    public function edit($id)
    {
        $this->soloAdminOTecnico();
        $lote = Lote::with(['urbanizacionRel', 'distrito'])->findOrFail($id);
        $urbanizaciones = Urbanizacion::orderBy('nombre')->get();
        $distritos = Distrito::where('relacion', $lote->urbanizacion)->orderBy('nombre')->get();
        $manzanos  = Lote::where('relacion', $lote->relacion)
                         ->distinct()->pluck('manzano');

        return view('lotes.edit', compact('lote', 'urbanizaciones', 'distritos', 'manzanos'));
    }

    // ─── Guardar edición ────────────────────────────────────────────────────
    public function update(Request $request, $id)
    {
        $this->soloAdminOTecnico();

        $request->validate([
            'superficie' => 'required|numeric|min:50',
            'tipo'       => 'required|in:1,2,3',
        ]);

        $lote = Lote::findOrFail($id);

        $datos = [
            'itetip'  => $request->tipo,
            'superf'  => $request->superficie,
            'alcanta' => $request->has('alcantarillado') ? 1 : 0,
            'luz'     => $request->has('luz')            ? 1 : 0,
            'agua'    => $request->has('agua')           ? 1 : 0,
            'telef'   => $request->has('telefono')       ? 1 : 0,
            'transpor'=> $request->has('transporte')     ? 1 : 0,
            'cordon'  => $request->has('cordon')         ? 1 : 0,
            'acera'   => $request->has('acera')          ? 1 : 0,
            'muralla' => $request->has('muralla')        ? 1 : 0,
            'observ'  => $request->observaciones,
            'plano'   => '',
        ];

        // Solo admin puede cambiar el estado
        if (auth()->user()->tipo == 1 && $request->filled('estador')) {
            $datos['iteest'] = $request->estador;
        }

        $lote->update($datos);
        $this->registrarSeguimiento($id, 2); // modificar

        return redirect()->route('lotes.show', $id)
                         ->with('success', 'Lote modificado correctamente.');
    }

    // ─── Eliminar ───────────────────────────────────────────────────────────
    public function destroy($id)
    {
        $this->soloAdmin();

        $tieneContrato = DB::table('contratos')->where('idlote', $id)->exists();

        if ($tieneContrato) {
            $contrato = DB::table('contratos')->where('idlote', $id)->value('id');
            return back()->with('error',
                "No se puede eliminar este lote porque está asociado al contrato Nro. $contrato.");
        }

        Lote::destroy($id);
        $this->registrarSeguimiento($id, 3); // baja

        return redirect()->route('lotes.index')
                         ->with('success', 'Lote eliminado correctamente.');
    }

    // ─── AJAX: cargar distritos por urbanización ────────────────────────────
    public function getDistritos($idUrbanizacion)
    {
        $distritos = Distrito::where('relacion', $idUrbanizacion)
                             ->orderBy('nombre')
                             ->get(['id', 'nombre']);
        return response()->json($distritos);
    }

    // ─── AJAX: cargar manzanos por distrito ─────────────────────────────────
    public function getManzanos($idDistrito)
    {
        $manzanos = Lote::where('relacion', $idDistrito)
                        ->distinct()
                        ->orderBy('manzano')
                        ->pluck('manzano');
        return response()->json($manzanos);
    }

    // ─── Helpers privados ───────────────────────────────────────────────────
    private function soloAdmin()
    {
        if (auth()->user()->tipo != 1)
            abort(403, 'Privilegio de acceso denegado.');
    }

    private function soloAdminOTecnico()
    {
        if (!in_array(auth()->user()->tipo, [1, 4]))
            abort(403, 'Privilegio de acceso denegado.');
    }

    private function registrarSeguimiento($idRegistro, $tipomov)
    {
        $now = now('America/La_Paz');
        $max = DB::table('seguimiento')->max('no') + 1;
        DB::table('seguimiento')->insert([
            'no'       => $max,
            'id'       => $idRegistro,
            'tipomov'  => $tipomov,
            'tipoid'   => 10, // tipoid 10 = lotes
            'ubicacion' => session('ubicacion_num', 1),
            'usuario'  => auth()->id(),
            'fecha'    => $now->format('Y-m-d'),
            'hora'     => $now->format('H:i:s'),
        ]);
    }
}