<?php

namespace App\Http\Controllers\Admin;

use App\Exceptions\ImportEstacionesException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\EstacionesRequest;
use App\Http\Requests\Admin\ImportEstacionesRequest;
use App\Http\Requests\Admin\ImportEstacionesOmitidasRequest;
use App\Http\Resources\DefaultCollection;
use App\Http\Resources\DefaultResource;
use App\Models\Admin\Estacion;
use App\Services\EstacionesImportService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;

class EstacionesController extends Controller
{
    private const INDEX_COLUMNS = [
        'e.id',
        'e.direccion',
        'e.ubicacion',
        'e.slug',
        'e.estado',
        'e.ciudad_id',
        'e.created_at',
        'e.updated_at',
        'c.nombre as ciudad_titulo',
    ];

    public function index(): DefaultCollection
    {
        $size = request('page.size', 80);
        $page = request('page.number', 1);

        $sort = request('sort', null);

        $result = Estacion::from('estaciones as e')
            ->join('ciudades as c', 'c.id', 'e.ciudad_id')
            ->select(
                DB::raw("COALESCE(NULLIF(e.titulo, ''), e.direccion) as titulo"),
                ...self::INDEX_COLUMNS
            )
            ->applySorts($sort, 'e.id')
            ->filterLike(request('filter', []))
            ->orderByDesc('id') 
            ->paginate($size, array_merge([DB::raw("COALESCE(NULLIF(e.titulo, ''), e.direccion) as titulo")], self::INDEX_COLUMNS), 'page[number]', $page);

        return DefaultCollection::make($result);
    }

    public function store(EstacionesRequest $request): DefaultResource
    {
        $input = $request->validated();
        $input['titulo'] = trim((string) ($input['titulo'] ?? ''));
        $input['slug'] = str_slug((string) ($input['direccion'] ?? ''));
        $servicios_ids = $request->get('servicios', []);

        $result = Estacion::create($input);
        $result->servicios()->attach($servicios_ids);

        return DefaultResource::make($result);
    }

    public function edit($id): DefaultResource
    {
        $result = Estacion::query()->findOrFail($id);
        $result->servicios = $result->servicios()->pluck('servicio_id');

        return DefaultResource::make($result);
    }

    public function update(EstacionesRequest $request, $id): DefaultResource
    {
        $input = $request->validated();
        $input['titulo'] = trim((string) ($input['titulo'] ?? ''));
        $input['slug'] = str_slug((string) ($input['direccion'] ?? ''));
        $servicios_ids = $request->get('servicios', []);


        $result = Estacion::findOrFail($id);
        $result->fill($input)->save();
        $result->servicios()->sync($servicios_ids);

        return DefaultResource::make($result);
    }

    public function destroy($id)
    {
        Estacion::findOrFail($id)->delete();
        return response()->noContent();
    }

    /**
     * Importa estaciones desde un Excel validado y devuelve un resumen seguro.
     */
    public function import(
        ImportEstacionesRequest $request,
        EstacionesImportService $service
    ): JsonResponse {
        try {
            $result = $service->import(
                $request->file('file'),
                $request->input('mapping', [])
            );

            return response()->json($result);
        } catch (ImportEstacionesException $exception) {
            return response()->json([
                'message' => $exception->getMessage(),
            ], 422);
        } catch (Throwable $exception) {
            return response()->json([
                'message' => 'Ocurrió un error al importar las estaciones.',
            ], 500);
        }
    }

    /**
     * Inserta filas omitidas ya corregidas manualmente desde el resumen final.
     */
    public function importSkipped(
        ImportEstacionesOmitidasRequest $request,
        EstacionesImportService $service
    ): JsonResponse {
        try {
            $result = $service->importSkippedRows(
                $request->validated('rows')
            );

            return response()->json($result);
        } catch (ImportEstacionesException $exception) {
            return response()->json([
                'message' => $exception->getMessage(),
            ], 422);
        } catch (Throwable $exception) {
            return response()->json([
                'message' => 'Ocurrió un error al cargar las filas corregidas.',
            ], 500);
        }
    }
}
