<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\BasesCondicionesRequest;
use App\Http\Resources\DefaultCollection;
use App\Http\Resources\DefaultResource;
use App\Models\BasesCondicion;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class BasesCondicionesController extends Controller
{
    public function index(): DefaultCollection
    {
        $size = request('page.size', 10);
        $page = request('page.number', 1);
        $sort = request('sort', null);

        $result = BasesCondicion::query()
            ->select('id', 'titulo', 'slug', 'archivo', 'activo', 'created_at', 'updated_at')
            ->applySorts($sort, 'id')
            ->filterLike(request('filter', []))
            ->orderByDesc('id')
            ->paginate($size, ['id'], 'page[number]', $page);

        return DefaultCollection::make($result);
    }

    public function store(BasesCondicionesRequest $request): DefaultResource
    {
        $data = $this->prepareData($request);

        $registro = BasesCondicion::create($data);

        return DefaultResource::make($registro);
    }

    public function edit(int $id): DefaultResource
    {
        $registro = BasesCondicion::findOrFail($id);

        return DefaultResource::make($registro);
    }

    public function update(BasesCondicionesRequest $request, int $id): DefaultResource
    {
        $registro = BasesCondicion::findOrFail($id);

        $data = $this->prepareData($request, $registro);

        $registro->fill($data)->save();

        return DefaultResource::make($registro);
    }

    public function destroy(int $id): Response
    {
        $registro = BasesCondicion::findOrFail($id);

        $this->deleteArchivo($registro->archivo);

        $registro->delete();

        return response()->noContent();
    }

    private function prepareData(BasesCondicionesRequest $request, BasesCondicion $registro = null): array
    {
        $data = $request->validated();

        $data['titulo'] = trim($data['titulo']);
        $data['slug'] = $data['slug'] ?? Str::slug($data['titulo']);
        $data['slug'] = $data['slug'] ?: (string) Str::uuid();
        $data['activo'] = $request->boolean('activo');

        if ($request->hasFile('archivo')) {
            $data['archivo'] = $this->storeArchivo(
                $request->file('archivo'),
                optional($registro)->archivo
            );
        } elseif ($registro) {
            unset($data['archivo']);
        }

        if ($data['activo']) {
            BasesCondicion::query()
                ->when($registro, fn ($query) => $query->where('id', '!=', $registro->id))
                ->update(['activo' => false]);
        }

        return $data;
    }

    private function storeArchivo(UploadedFile $archivo, ?string $archivoActual = null): string
    {
        $this->deleteArchivo($archivoActual);

        $nombreOriginal = pathinfo($archivo->getClientOriginalName(), PATHINFO_FILENAME);
        $extension = $archivo->getClientOriginalExtension();
        $filename = Str::slug($nombreOriginal . '-' . time()) . '.' . $extension;

        $path = $archivo->storeAs('bases-condiciones', $filename, 'public');

        return 'storage/' . $path;
    }

    private function deleteArchivo(?string $path): void
    {
        if (!$path) {
            return;
        }

        $relativePath = Str::startsWith($path, 'storage/')
            ? Str::replaceFirst('storage/', '', $path)
            : $path;

        Storage::disk('public')->delete($relativePath);
    }
}
