<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Resources\DefaultCollection;
use App\Http\Resources\DefaultResource;
use App\Models\Admin\Interna;
use App\Models\Admin\Modulos;
use App\Services\Image\ImageService;
use App\Services\UploadedImageService;
use Illuminate\Http\Response;
use App\Http\Requests\Admin\InternaBorradorRequest;
use App\Http\Requests\Admin\InternaStoreRequest;
use App\Http\Requests\InternaUpdateRequest;
use App\Models\Admin\Secciones;
use Illuminate\Support\Facades\DB;

use function PHPSTORM_META\map;

class InternasController extends Controller
{
    //?=========================
    //?       C.R.U.D.
    //?=========================

    public function index(string $slug_modulo): DefaultCollection | Response
    {
        $modulo = Modulos::slug($slug_modulo)
            ->activo()
            ->selectFillable()
            ->first();

        if (!$modulo)
            return response([
                'message' => 'No existe',
                'redirect' => 1
            ]);

        $operadores = request('operadores', null);
        $size = request('page.size', 10);
        $page = request('page.number', 1);

        $result = Interna::modulo($modulo->id)
            ->userBorradores()
            ->selectFillableAnd(['id as image_small_getter'])
            ->filterLike(request('filter', []))
            ->applySorts(request('sort'))
            ->orderByDesc('id') 
            ->whereOperadores($operadores)
            ->latest()
            ->fastPaginate(
                perPage: $size,
                columns: ['id'],
                page: $page,
                pageName: 'page[number]',
            )->appends(request()->only('sort', 'page.size', 'filter'));


        return DefaultCollection::make($result);
    }

    public function store(InternaStoreRequest $request): DefaultResource
    {
        $interna_id = $request->input('id', null);

        $interna = Interna::find($interna_id);
        $interna->fill([
            'borrador' => false
        ])->save();

        Secciones::where('interna_id', $interna_id)
            ->update([
                'borrador' => false
            ]);

        return DefaultResource::make($interna);
    }

    public function update(InternaUpdateRequest $request, UploadedImageService $uploadedImageService, $id): DefaultResource
    {

        $imagen = $request->file('imagen', null);

        $input = request()->all();

        //* No borrador
        $input = array_merge($input, [
            'borrador' => false
        ]);
        $result = Interna::find($id);
        $result->fill($input)->save();


        if ($request->hasFile('imagen')) {
            $result->imagen =
                $uploadedImageService
                ->setFile($imagen)
                ->setRelatedModel($result)
                ->move()
                ->createThumbnails()
                ->replaceFirst()
                ->getUrl('large');
        }

        Secciones::where('interna_id', $id)
            ->update([
                'borrador' => false
            ]);

        return DefaultResource::make($result);
    }

    public function destroy(string $slug_modulo, $id): Response
    {
        Interna::find($id)->delete();
        return response()->noContent();
    }

    public function show($slug, $slug_interna = null)
    {
        $grupo = Modulos::where('slug', strtolower(trim($slug)))
            ->select('id', 'titulo', 'icono')
            ->first();

        if (!$grupo)
            return response([
                'message' => 'No encontrado',
                'redirect' => 1
            ], 404);

        if (isset($slug_interna)) {
            $result = Interna::where('slug', strtolower(trim($slug_interna)))
                ->with(['secciones'])
                ->selectFillableAnd(['id as image_large_getter'])
                ->first();

            if ($result)
                $grupo->interna = $result;
            else
                $grupo->interna = null;
        }
        return DefaultResource::make($grupo)->additional([
            'meta' => [
                'largeThumbnailSettings' => $this->getLargeThumbnailSettings(),
            ],
        ]);
    }

    //*=========================
    //*       BORRADORES
    //*=========================

    public function getBorrador($slug, $slug_interna = null): DefaultResource| Response
    {
        $grupo = Modulos::where('slug', strtolower(trim($slug)))
            ->select('id', 'titulo', 'icono')
            ->first();

        if (!$grupo)
            return response([
                'message' => 'No encontrado',
                'redirect' => 1
            ], 404);

        if (isset($slug_interna)) {
            $result = Interna::where('slug', strtolower(trim($slug_interna)))
                ->where('borrador', true)
                ->with(['secciones'])
                ->selectFillableAnd(['id as image_large_getter'])
                ->first();

            if ($result)
                $grupo->interna = $result;
            else
                $grupo->interna = null;
        }

        return DefaultResource::make($grupo)->additional([
            'meta' => [
                'largeThumbnailSettings' => $this->getLargeThumbnailSettings(),
            ],
        ]);
    }

    public function borrador(InternaBorradorRequest $request, UploadedImageService $uploadedImageService): DefaultResource | Response
    {

        $imagen = $request->file('imagen', null);

        $id =  request('id', null);
        $input = request()->all();

        //?validamos si existe y si es un borrador
        $isBorrador = $this->isBorrador($id);

        if (!$isBorrador && $isBorrador !== null) {
            //* Cuando existe pero no es borrador
            return response([
                'message' => 'Esta sección no es un borrador',
                'id' => $id
            ], 422);
        } else if ($isBorrador === null) {
            //? Cuando no existe
            //*Creamos uno nuevo
            $input = array_merge($input, [
                'admin_id' => auth()->user()->id,
                'borrador' => true
            ]);
            $result = Interna::create($input);
        } else {
            //* Si es borrador
            $input = array_merge($input, [
                'borrador' => true
            ]);
            $result = Interna::find($id);
            $result->fill($input)->save();
        }

        if (isImageBase64(request('imageBase64', null))) {
            $result->imagen =
                $uploadedImageService
                ->setFile($imagen)
                ->setRelatedModel($result)
                ->move()
                ->createThumbnails()
                ->storeRelationship()
                ->getUrl('large');
        } else if (request('imagen', null)) {
            $result->imagen = request('imagen', null);
        }

        return DefaultResource::make($result);
    }

    public function getModulos()
    {
        $modulos = Modulos::activo()
            ->select(
                'id',
                'titulo as title',
                'icono as icon',
                DB::raw('"menu-item" as type'),
                DB::raw('"interna-lista" as routeName'),
                'slug'
            )
            ->ordenar()
            ->get()
            ->each(function ($modulo) {
                $modulo->params = (object) [
                    'slug_grupo' => $modulo->slug
                ];
            });

        $modulos_web = clone $modulos;

        $modulos_operadores =  $modulos->map(function ($modulo) {
            $newModulo = clone $modulo;
            $newModulo->routeName = "operadores-{$newModulo->routeName}";
            return $newModulo;
        });

        $modulos_operadores_vista = clone $modulos->map(function ($modulo) {
            $newModulo = clone $modulo;
            $newModulo->routeName = "internas-lista-portal-operadores";
            return $newModulo;
        });

        return [
            'web' => $modulos_web,
            'operadores' => $modulos_operadores,
            'operadores_vista' => $modulos_operadores_vista
        ];
    }

    public function thumbnailSettingsBySize(ImageService $imageService, string $size)
    {
        $thumbnailSettings = $imageService
            ->setModelType(Interna::class)
            ->getThumbnailSettingsBySize($size);

        return $thumbnailSettings;
    }

    //!=========================
    //!        PRIVATES
    //!=========================

    private function isBorrador(Int $id = null)
    {
        if (!isset($id))
            return null;

        $data = Interna::where('id', $id)
            ->first();

        if (!!$data)
            return $data->borrador;

        return null;
    }

    protected function getLargeThumbnailSettings()
    {
        $imageService = new ImageService;

        return $imageService
            ->setModelType(Interna::class)
            ->getLargeThumbnailSettings();
    }
}
