<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\PromocionesRequest;
use App\Http\Resources\DefaultCollection;
use App\Http\Resources\DefaultResource;
use App\Models\Files;
use App\Models\Promociones;
use App\Services\UploadedImageService;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Psr7\Response;
use Illuminate\Http\Request;
use Illuminate\Http\Response as HttpResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PromocionesController extends Controller
{
    public function index(): DefaultCollection
    {
        $size = request('page.size', 10);
        $page = request('page.number', 1);
        $operadores = request('operadores', false);

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

        $result = Promociones::query()
            ->select(
                'id',
                'titulo',
                'slug',
                'subtitulo',
                'fecha_desde',
                'fecha_hasta',
                'estado',
                'orden',
                'all_dias',
                'all_estaciones',
                'operadores',
                'copete',
                'descripcion',
                'popup',
                'app',
                'id as image_large_getter'
            )
            ->where('operadores', $operadores ? true : false)
            ->applySorts($sort, 'id')
            ->filterLike(request('filter', []))
            ->orderByDesc('id') 
            ->paginate($size, ['id'], 'page[number]', $page);

        return DefaultCollection::make($result);
    }

    public function store(PromocionesRequest $request, UploadedImageService $uploadedImageService): DefaultResource
    {
        DB::beginTransaction();

        try {
            $input = $this->formatRequest($request);

            //? IMAGEN
            $imagen = $request->file('imagen', null);
            unset($input['imagen']);

            //? TERMINOS Y CONDICIONES
            $terminos_file_id = $request->get('terminos_file_id', null);
            $estaciones_file_id = $request->get('estaciones_file_id', null);
            $archivo_file_id = $request->get('archivo_file_id', null);

            unset($input['imagen_popup']);


            $result = Promociones::create($input);
            if (!$request->get('operadores', null)) {
                $result->metodosPagos()->attach($input['metodos_pagos'] ? $input['metodos_pagos'] : []);
                $result->servicios()->attach($input['servicios'] ? $input['servicios'] : []);
                $result->estaciones()->attach($input['estaciones'] ? $input['estaciones'] : []);

                $this->sincronizarDias($result, $input['dias'] ? $input['dias'] : []);
                //$result->dias()->attach($input['dias'] ? $input['dias'] : []);
            }


            //? Files data change
            $this->relacionarArchivo($result->id, $terminos_file_id, 'terminos');
            $this->relacionarArchivo($result->id, $estaciones_file_id, 'estaciones');
            $this->relacionarArchivo($result->id, $archivo_file_id, 'archivo');

            //? CONTROL POPUP
            if ($result->popup) {
                $this->disabledPopup($result->id);
            }

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

            DB::commit();
            return DefaultResource::make($result);
        } catch (Exception $e) {
            DB::rollBack();
            Log::error(json_encode($e->getMessage()));
            return response('Lo sentimos, hubo un problema', 422);
        }
    }

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

        try {
            DB::beginTransaction();

            $input = $this->formatRequest($request);

            //? IMAGEN
            $imagen = $request->file('imagen', null);
            unset($input['imagen']);
            unset($input['imagen_popup']);

            //? TERMINOS Y CONDICIONES
            $terminos_file_id = $request->get('terminos_file_id', null);
            $estaciones_file_id = $request->get('estaciones_file_id', null);
            $archivo_file_id = $request->get('archivo_file_id', null);

            $result = Promociones::find($id);
            $result->fill($input)->save();

            if (!$request->get('operadores', null)) {
                $result->metodosPagos()->sync($input['metodos_pagos']);
                $result->servicios()->sync($input['servicios']);
                $result->estaciones()->sync($input['estaciones']);

                //dd($result->dias()->syncWithoutDetaching($input['dias']));
                //$result->syncDias($input['dias']);
                $this->sincronizarDias($result, $input['dias']);
            }


            //? CONTROL POPUP
            if ($result->popup) {
                $this->disabledPopup($result->id);
            }

            //? Files data change
            $this->relacionarArchivo($id, $terminos_file_id, 'terminos');
            $this->relacionarArchivo($id, $estaciones_file_id, 'estaciones');
            $this->relacionarArchivo($id, $archivo_file_id, 'archivo');

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

            DB::commit();
            return DefaultResource::make($result);
        } catch (Exception $e) {
            DB::rollBack();
            Log::error(json_encode($e->getMessage()));
            return response('Lo sentimos, hubo un problema', 422);
        }
    }

    private function sincronizarDias($result, $dias)
    {
        $existente = $result->dias()
            ->pluck('dia')
            ->toArray();

        $eliminar = collect($existente)->diff($dias)->all();

        if (sizeof($eliminar)) {
            DB::table('promociones_dias')
                ->where('promocion_id', $result->id)
                ->whereIn('dia', $eliminar)
                ->delete();

            $existente = $result->dias()
                ->pluck('dia')
                ->toArray();
        }

        $agregar = collect($dias)->diff($existente)->all();
        if (sizeof($agregar)) {
            foreach ($agregar as $dia) {
                DB::table('promociones_dias')
                    ->insert([
                        'promocion_id' => $result->id,
                        'dia' => $dia,
                        'created_at' => Carbon::now(),
                        'updated_at' => Carbon::now()
                    ]);
            }
        }
    }

    private function formatRequest($request)
    {
        $input = $request->all();
        $isAllEstaciones = $request->get('all_estaciones', false);
        $isAllDias = $request->get('all_dias', false);

        //Eliminamos las estaciones
        if ($isAllEstaciones) {
            $input['estaciones'] = [];
        }

        //Eliminamos los dias
        if ($isAllDias) {
            $input['dias'] = [];
        }

        return $input;
    }

    private function relacionarArchivo($id, $file_id, $key)
    {
        Files::where('archivable_id', $id)
            ->where('archivable_type', Promociones::class)
            ->where('key', $key)
            ->where('id', '<>', $file_id)
            ->get()
            ->each(function ($item) use ($file_id) {
                if ($item->id !== $file_id)
                    $item->delete();
            });

        if ($file_id) {
            Files::find($file_id)
                ->update([
                    'archivable_id' => $id,
                    'borrador' => false
                ]);
        }
    }

    public function edit($id): DefaultResource
    {
        $result = Promociones::query()
            ->find($id);

        //! Por si se requiera cambiar de 1:M a M:M
        $servicios = $result->servicios()->pluck('servicio_id');
        $result->servicio_id = sizeof($servicios) ? $servicios[0] : null;
        //$result->servicios = $result->servicios()->pluck('servicio_id');

        $result->imagen = $result->imagen();

        if ($result->all_dias) {
            $result->dias = [
                1, 2, 3, 4, 5, 6, 7
            ];
        } else {
            $result->dias = $result->dias()->pluck('dia');
        }

        $result->terminos_file_id = $result->file('terminos');
        $result->estaciones_file_id = $result->file('estaciones');

        $result->archivo_file_id = $result->file('archivo');

        return DefaultResource::make($result);
    }

    public function destroy($id): HttpResponse
    {
        $promociones = Promociones::find($id);
        $promociones->deleteFiles();
        $promociones->delete();

        return response()->noContent();
    }

    public function uploadFile()
    {
        $file = request()->file('file');

        $model = new Files;
        $model->uploadBorrador($file, Promociones::class);
    }

    private function disabledPopup($id)
    {
        Promociones::where('popup', true)
            ->where('id', '<>', $id)
            ->update([
                'popup' => false
            ]);
    }
}
