<?php

namespace App\Http\Controllers;

use App\Exceptions\InvalidRequestException;
use App\Models\Roles;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Routing\Route;
use App\Http\Controllers\exception;
use App\Http\Controllers\Permission;
use Spatie\Permission\Traits\HasRoles;
use Spatie\Permission\Models\Role;
use App\Http\Controllers\Authh;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Models\Promocion;
use App\Models\PromocionSucursal;
use App\Models\Sucursal;
use App\Models\BeneficioNivel;
use App\Models\PromocionNotificacion;
use DateTime;
use DateInterval;


class PromocionesController extends Controller
{
    use HasRoles;

    public function __construct()
    {
        $this->middleware('permission:listar_promociones', ['only' => ['index', 'synchronize']]);
        $this->middleware('permission:crear_promociones', ['only' => ['create','store', 'synchronize']]);
        $this->middleware('permission:editar_promociones', ['only' => ['edit','update']]);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $usuarioAuth = Auth::user();

        $promociones = Promocion::select('id', 'status', 'tipo', 'nombre', 'updated_at', 'updated_by', 'incompleto', 'hasnotificaciones');
        // Sin permiso solo ve la sucursal que tiene asignada
        if (!$usuarioAuth->can('ver_todas_sucursales')) {
            $promociones->whereHas('Sucursal', function ($query) use ($usuarioAuth) {
                $query->where('idsucursal', $usuarioAuth->idsucursal);
            });
        }
        $promociones->where('tipo', 1);

        $promociones = $promociones->get();

        return view('Promociones.promociones_list', compact('promociones'));
    }

    public function synchronizePaises()
    {
        $url = env('APP_FOLIATTIAPI_URL') . "Catalogs/getPaises";
		$method="GET";
		$output = (new Tools)->CallAPI($method, $url);
		$result = json_decode($output);
        
        $paises = $result->paises;
        if($paises != null)
        {

            foreach ($paises as &$pais) 
            {
                try
                {
                    $paisToInsert = new Pais;
                    $paisToInsert->id = $pais->id;
                    $paisToInsert->nombre = $pais->nombre;
                    $paisToInsert->codigo = $pais->codigo;
                    $paisToInsert->activo = true;
                    $paisToInsert->save();
                }
			    catch(\Exception $excep)
		    	{
                    return $this->sendError($excep->getMessage(), 404);
   
                }



            }
        }


        return $this->sendResponse($result->paises[0]->id . $result->paises[0]->nombre . $result->paises[0]->codigo, 401);

    }



    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function synchronize(Request $request)//synchronize
    {
        //return view('Promociones.promociones_create', compact('sucursales'), compact('beneficio_niveles'));
        
        $usuarioAuth = Auth::user();

        //Get Sucursales to synchronize


//Sincronizar todas las sucursales $sucursales = Sucursal::all();

/** Syncrhonize process starts */
$url = env('APP_FOLIATTIAPI_URL') . "PromoEvent/getPromociones?CasinoId=1";
$method="GET";
$output = (new Tools)->CallAPI($method, $url);
$result = json_decode($output);

$promociones = $result->promociones;
if($promociones != null)
{

    foreach ($promociones as &$promocion) 
    {
        try
        {
            //Check if promocion existis
            $promocion->id_sucursal;
 

            if(Promocion::whereRaw("codigo = '$promocion->id_promocion'")->exists())
            {
                //Checar las sucursales
                $oPromocion = Promocion::whereRaw("codigo = '$promocion->id_promocion'")->first();
                $oPromocion->promocionSucursal()->delete();
                //foreach($request->id_sucursal as $idSucursal)
                {
                        PromocionSucursal::insert([
                            'idpromocion' => $oPromocion->id,
                            'idsucursal' => $promocion->id_sucursal
                        ]);
                }
            }
            else
            {
                $promocionToInsert = new Promocion();
                $promocionToInsert->status = true;
                $promocionToInsert->tipo = 1;
                $promocionToInsert->nombre = $promocion->nombre;
                $promocionToInsert->codigo = $promocion->id_promocion;
                $promocionToInsert->tipo_f = $promocion->tipo;
                $promocionToInsert->fecha_inicio = $promocion->fecha_inicio;
                $promocionToInsert->fecha_fin = $promocion->fecha_fin;
                $promocionToInsert->hora_inicio = $promocion->hora_inicio;
                $promocionToInsert->hora_fin = $promocion->hora_fin;

                $promocionToInsert->enlace = null;//$request->enlace;
                $promocionToInsert->updated_by = Auth::id();
                $promocionToInsert->imagen_mini = null;//$imagen_mini_name;
                $promocionToInsert->imagen = null;//$imagen_name;
                $promocionToInsert->hasnotificaciones = false;
                $promocionToInsert->incompleto = true;

                /*
                $promocionToInsert->beneficio_nivel_id = $request->beneficio_nivel_id;
                $promocionToInsert->f_lun = $request->f_lun;
                $promocionToInsert->f_mar = $request->f_mar;
                $promocionToInsert->f_mie = $request->f_mie;
                $promocionToInsert->f_jue = $request->f_jue;
                $promocionToInsert->f_vie = $request->f_vie;
                $promocionToInsert->f_sab = $request->f_sab;
                $promocionToInsert->f_dom = $request->f_dom;
                $promocionToInsert->not_hora = $request->not_hora;
                $promocionToInsert->not_mensaje = $request->not_mensaje;
                */

                $promocionToInsert->save();

                //foreach($request->id_sucursal as $idSucursal)
                {
                        PromocionSucursal::insert([
                            'idpromocion' => $promocionToInsert->id,
                            'idsucursal' => $promocion->id_sucursal
                        ]);
                }
            }
        }
        catch(\Exception $excep)
        {
            return $this->sendError($excep->getMessage(), 404);

        }
    }
}
/** Synchronize process ends */



        $promociones = Promocion::select('id', 'status', 'tipo', 'nombre', 'updated_at', 'updated_by');
        // Sin permiso solo ve la sucursal que tiene asignada
        if (!$usuarioAuth->can('ver_todas_sucursales')) {
            $promociones->whereHas('Sucursal', function ($query) use ($usuarioAuth) {
                $query->where('idsucursal', $usuarioAuth->idsucursal);
            });
        }
        $promociones = $promociones->get();

        return view('Promociones.promociones_list', compact('promociones'));
    }

    


    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        $usuarioAuth = Auth::user();

        $sucursales = Sucursal::where('status', true)->orderBy('nombre');
        if (!$usuarioAuth->can('ver_todas_sucursales')) {
            $sucursales->where('id', $usuarioAuth->sucursal->id);
        }
        $sucursales = $sucursales->get();

        $beneficio_niveles = BeneficioNivel::select('*');
        $beneficio_niveles = $beneficio_niveles->get();


        //return view('Promociones.promociones_create', compact('sucursales'));
        return view('Promociones.promociones_create', compact('sucursales'), compact('beneficio_niveles'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        try {
            if(Promocion::whereRaw("nombre ilike '$request->nombre'")->exists()){
                throw new \Exception("El nombre ya existe", 1);
            }

            $imagen_mini_name = null;
            $imagen_mini = getB64Image($request->imagen_mini);
            $img_extension = getB64Extension($request->imagen_mini);
            if(!in_array($img_extension, ['jpg', 'jpeg', 'png', 'gif'])){
                throw new \Exception("Extensión de imagen mini inválida", 1);
            }
            $imagen_mini_name = 'img_promocion'. time() . '.' . $img_extension;

            $imagen_name = null;
            if($request->imagen != ''){
                $imagen = getB64Image($request->imagen);
                $img_extension = getB64Extension($request->imagen);
                if(!in_array($img_extension, ['jpg', 'jpeg', 'png', 'gif'])){
                    throw new \Exception("Extensión de imagen inválida", 1);
                }
                $imagen_name = 'img_promocion_mini'. time() . '.' . $img_extension;
            }
            
            DB::beginTransaction();

            $oPromocion = new Promocion();
            $oPromocion->status = $request->status == 'true';
            $oPromocion->tipo = $request->tipo;
            $oPromocion->nombre = $request->nombre;
            $oPromocion->enlace = $request->enlace;
            $oPromocion->updated_by = Auth::id();
            $oPromocion->imagen_mini = $imagen_mini_name;
            $oPromocion->imagen = $imagen_name;
            $oPromocion->hasnotificaciones = $request->hasnotificaciones;

            $oPromocion->beneficio_nivel_id = $request->beneficio_nivel_id;
            $oPromocion->f_lun = $request->f_lun;
            $oPromocion->f_mar = $request->f_mar;
            $oPromocion->f_mie = $request->f_mie;
            $oPromocion->f_jue = $request->f_jue;
            $oPromocion->f_vie = $request->f_vie;
            $oPromocion->f_sab = $request->f_sab;
            $oPromocion->f_dom = $request->f_dom;
            $oPromocion->not_hora = $request->not_hora;
            $oPromocion->not_mensaje = $request->not_mensaje;



            $oPromocion->save();

            //Save with full path
            if($imagen_name != '')
            {
                $img_name_DB = env('APP_FOLIATTI_IMG_PATH') . 'promociones/' . $oPromocion->id . '/' .   $imagen_name;
                $oPromocion->imagen_fullpath = $img_name_DB;            
            }
            
            $img_mini_name_DB = env('APP_FOLIATTI_IMG_PATH') . 'promociones/' . $oPromocion->id . '/' .   $imagen_mini_name;
            $oPromocion->imagen_mini_fullpath = $img_mini_name_DB;            
            
            $oPromocion->save();

            foreach($request->id_sucursal as $idSucursal){
                PromocionSucursal::insert([
                    'idpromocion' => $oPromocion->id,
                    'idsucursal' => $idSucursal
                ]);
            }

            Storage::disk('promocion')->put($oPromocion->id . '/' .$imagen_mini_name, $imagen_mini);
            if($request->imagen != ''){
                Storage::disk('promocion')->put($oPromocion->id . '/' .$imagen_name, $imagen);
            }

            DB::commit();
        } catch (\Exception $e) {
            throw new InvalidRequestException($e->getMessage().$e->getLine());
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $usuarioAuth = Auth::user();

        $sucursales = Sucursal::where('status', true)->orderBy('nombre')->get();

        $idSucursalUsuario = null;
        if (!$usuarioAuth->can('ver_todas_sucursales')) {
            $idSucursalUsuario = $usuarioAuth->sucursal->id;
        }

        $promocion = Promocion::findOrFail($id);

        $aIdSucursalPromocion = $promocion->sucursal()->pluck('id')->toArray();

        $beneficio_niveles = BeneficioNivel::select('*');
        $beneficio_niveles = $beneficio_niveles->get();


        return view('Promociones.promociones_create', compact('sucursales', 'idSucursalUsuario', 'promocion', 'aIdSucursalPromocion'), compact('beneficio_niveles'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        try {
            if(Promocion::whereRaw("nombre ilike '$request->nombre'")->where('id','<>',$id)->exists()){
                throw new \Exception("El nombre ya existe", 1);
            }

            $oPromocion = Promocion::findOrFail($id);
            
            DB::beginTransaction();
            
            //throw new \Exception("El nombre ya existe segun-" . $request->f_lun, $oPromocion->id);

            $oPromocion->status = $request->status == 'true';
            $oPromocion->tipo = 1;
            $oPromocion->nombre = $request->nombre;
            $oPromocion->enlace = $request->enlace;


            $oPromocion->beneficio_nivel_id = 1;//$request->beneficio_nivel_id;
            $oPromocion->hasnotificaciones = $request->hasnotificaciones;
            $oPromocion->f_lun = $request->f_lun;
            $oPromocion->f_mar = $request->f_mar;
            $oPromocion->f_mie = $request->f_mie;
            $oPromocion->f_jue = $request->f_jue;
            $oPromocion->f_vie = $request->f_vie;
            $oPromocion->f_sab = $request->f_sab;
            $oPromocion->f_dom = $request->f_dom;

            $oPromocion->not_hora = $request->not_hora;
            $oPromocion->not_mensaje = $request->not_mensaje;
            $oPromocion->tipo = 2;


            $oPromocion->save();
            DB::commit();//TEMPORAL
            //throw new \Exception("CHECKPOINT 001" . $request->f_lun, $oPromocion->id);
            
            $oPromocion->not_hora = $request->not_hora;
            $oPromocion->not_mensaje = $request->not_mensaje;
            $oPromocion->incompleto = false;


            $oPromocion->updated_by = Auth::id();
            $imagenDelete = [];
            $imagen_name = "";
            $imagen_mini_name = "";

            if($request->imagen_mini != ''){
                $imagenDelete[] = $oPromocion->id . '/' .$oPromocion->imagen_mini;
                $imagen_mini = getB64Image($request->imagen_mini);
                $img_extension = getB64Extension($request->imagen_mini);
                if(!in_array($img_extension, ['jpg', 'jpeg', 'png', 'gif'])){
                    throw new \Exception("Extensión de imagen mini inválida", 1);
                }
                $imagen_mini_name = 'img_promocion_mini'. time() . '.' . $img_extension;
                $oPromocion->imagen_mini = $imagen_mini_name;
                Storage::disk('promocion')->put($oPromocion->id . '/' .$imagen_mini_name, $imagen_mini);

                //Save with full path
                $img_mini_name_DB = env('APP_FOLIATTI_IMG_PATH') . 'promociones/' . $oPromocion->id . '/' .   $imagen_mini_name;
                $oPromocion->imagen_mini_fullpath = $img_mini_name_DB;            

            }

            if($request->imagen_delete != ''){
                $imagenDelete[] = $oPromocion->id . '/' .$oPromocion->imagen;
                $oPromocion->imagen = null;

                $oPromocion->imagen_fullpath = null;            

            }

            if($request->imagen != ''){
                $imagenDelete[] = $oPromocion->id . '/' .$oPromocion->imagen;
                $imagen = getB64Image($request->imagen);
                $img_extension = getB64Extension($request->imagen);
                if(!in_array($img_extension, ['jpg', 'jpeg', 'png', 'gif'])){
                    throw new \Exception("Extensión de imagen inválida", 1);
                }
                $imagen_name = 'img_promocion'. time() . '.' . $img_extension;
                $oPromocion->imagen = $imagen_name;
                Storage::disk('promocion')->put($oPromocion->id . '/' .$imagen_name, $imagen);

                //Save with full path
                $img_name_DB = env('APP_FOLIATTI_IMG_PATH') . 'promociones/' . $oPromocion->id . '/' .   $imagen_name;
                $oPromocion->imagen_fullpath = $img_name_DB;            

            }
                       
                        
            $oPromocion->save();

            if (Auth::user()->can('ver_todas_sucursales')) {
                $oPromocion->promocionSucursal()->delete();
                foreach($request->id_sucursal as $idSucursal){
                    PromocionSucursal::insert([
                        'idpromocion' => $oPromocion->id,
                        'idsucursal' => $idSucursal
                    ]);
                }
            }

            Storage::disk('promocion')->delete($imagenDelete);

            DB::commit();//TEMPORAL
            //throw new \Exception("CHECKPOINT 002" . $request->f_lun, $oPromocion->id);

            //Guardar la programación de notificaciones
            /*$fecha_inicio = $oPromocion->fecha_inicio;
            $fecha_fin = $oPromocion->fecha_fin;
            $hora_inicio = $oPromocion->hora_inicio;
            $hora_fin = $oPromocion->hora_fin;
            */
            $fecha_inicio = "2024-01-17";
            $fecha_fin = "2024-12-31";
            $hora_inicio = "00:00:00";
            $hora_fin = "23:59:00";
            
            // Convierte las fechas a objetos DateTime
            $inicio = new DateTime($fecha_inicio);
            $fin = new DateTime($fecha_fin);
            
            // Verifica si la fecha_inicio es menor que la fecha actual
            $hoy = new DateTime(); // Fecha actual
            if ($inicio < $hoy) 
            {
                $inicio = $hoy;
            }
            
            // Crea un intervalo de 1 día
            $intervalo = new DateInterval('P1D');
            
            // Genera las fechas en el rango
            $fechas = [];
            $fechas_num = [];
            
            $oPromocion->promocionNotificacion()->delete();

            while ($inicio <= $fin) {
                $fecha_actual = $inicio->format('Y-m-d');
                $fechas[] = $fecha_actual;
                $fechas_num[] = $inicio->format('N');
                $inicio->add($intervalo);
            }
            
            //throw new \Exception("CHECKPOINT 002.5 Fechas: " . count($fechas) . " - " . $oPromocion->f_lun . " =>", $oPromocion->id);

            // Ahora puedes usar el array $fechas en tu lógica
            $num = 0;
            foreach ($fechas as $fecha) {
                //echo "Fecha: $fecha\n" .   " - " . $fechas_num[$num] . "<br>";
                //throw new \Exception("CHECKPOINT 002.55 Fechas: " . count($fechas) . " - " . $oPromocion->f_lun . " =>", $oPromocion->id);
            
            $numero = $fechas_num[$num];
            $programarfecha = false;
            switch ($numero) 
            {
                case 1:                   
                    if($oPromocion->f_lun || ($oPromocion->f_lun==1))
                        $programarfecha = true;
                    break;
                case 2:
                    if($oPromocion->f_mar)
                        $programarfecha = true;
                    break;
                case 3:
                    if($oPromocion->f_mie)
                        $programarfecha = true;
                    break;
                case 4:
                    if($oPromocion->f_jue)
                        $programarfecha = true;
                    break;
                case 5:
                    if($oPromocion->f_vie)
                        $programarfecha = true;
                    break;
                case 6:
                    if($oPromocion->f_sab)
                        $programarfecha = true;
                    break;
                case 7:
                    if($oPromocion->f_dom)
                        $programarfecha = true;
                    break;
                default:
                        $programarfecha = false;
            }

            //DB::commit();//TEMPORAL
            //throw new \Exception("CHECKPOINT 003: " . $programarfecha . " - ", $oPromocion->id);

            if($programarfecha) //Programar fecha
            {
                //throw new \Exception("CHECKPOINT 004: " . $fecha . " " . $oPromocion->not_hora, $oPromocion->id);
                $iPromocionNotificacion = new PromocionNotificacion();
                $iPromocionNotificacion->idpromocion = $oPromocion->id;
                $iPromocionNotificacion->fecha_notificacion = $fecha . " " . $oPromocion->not_hora;
                $iPromocionNotificacion->titulo = $oPromocion->nombre;
                $iPromocionNotificacion->mensaje = $oPromocion->not_mensaje;
                $iPromocionNotificacion->id_promocion_foliatti = $oPromocion->codigo;

                // Ejecutar la consulta
                $resultados = DB::table('promocion_sucursal')
                ->select('idsucursal')
                ->where('idpromocion', $oPromocion->id)
                ->get();

                // Obtener los valores de 'idsucursal' como una cadena separada por comas
                $sucursales = $resultados->pluck('idsucursal')->implode(',');

                $iPromocionNotificacion->sucursales = $sucursales;

                $iPromocionNotificacion->save();

                /*
                PromocionNotificacion::insert([                   
                    'idpromocion' => $oPromocion->id,
                    'fecha_notificacion' => $fecha . " " . $oPromocion->not_hora
                ]);
                */
                //throw new \Exception("CHECKPOINT 005: " . $programarfecha . " - ", $oPromocion->id);
            }                      
            
                $num = $num + 1;
                // Aquí puedes realizar otras operaciones con la fecha
            }
            






            DB::commit();
        } catch (\Exception $e) {
            throw new InvalidRequestException($e->getMessage().$e->getLine());
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $oBeneficio = Promocion::findOrFail($id);
        $oBeneficio->delete();
    }

}
