<?php

namespace App\Services;

use App\Events\NotificationEvent;
use App\Http\Resources\NotificationsResource;
use App\Models\DetailUserNotifications;
use App\Models\Notifications;
use App\Models\User;
use App\Traits\HasResponse;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Broadcasting\BroadcastException;
use Illuminate\Support\Facades\Log;

class NotificationsService
{
    use HasResponse;

    public function get($request, $withPagination)
    {
        try {
            $notifications = DetailUserNotifications::whereHas('notification', function ($query) use ($request) {
                $query->active()->filters();
                return $query;
            })->where('idreceiver', JWTAuth::user()->id)->filters()->orderBy('id', 'desc');

            $notifications = !empty($withPagination)
                ? $notifications->paginate($withPagination['perPage'], page: $withPagination['page'])
                : $notifications->get();

            $paginationTotal = DetailUserNotifications::whereHas(
                'notification',
                fn($q) => $q->active()
            )->where('idreceiver', JWTAuth::user()->id)->where('status_N', 1)->active()->count();

            $notifications = NotificationsResource::collection($notifications->load('notification.sender'));
            return $this->successPaginationResponse('Lista exitosa', $paginationTotal, $notifications);
        } catch (\Throwable $th) {
            throw $th;
        }
    }

    public function create($params)
    {
        DB::beginTransaction();
        try {
            if (!isset($params['ids_receiver'])) {
                return $this->errorResponse("No existe ningun destinatario", 400);
            }

            # Validar que los usuarios estén activos
            $users = User::whereIn('id', $params['ids_receiver'])->active()->count();
            if ($users != count($params['ids_receiver'])) {
                return $this->errorResponse("No existe uno de los destinatarios enviados", 400);
            }

            $notification = Notifications::create([
                'idsender'      =>  isset($params['idsender']) ? $params['idsender'] : (JWTAuth::user()->id ?? null),
                'message_title' =>  $params['message_title'],
                'message_body'  => isset($params['message_body']) ?  $params['message_body']  : null,
                'data_json'     =>  json_encode($params['data_json']),
                'date_sent'     =>  Carbon::now()->toDateTimeString(),
                'idcompany'     =>  $params['idcompany'],
            ]);

            foreach ($params['ids_receiver'] as $key => $iduser_receiver) {
                DetailUserNotifications::create([
                    'idreceiver'     =>  $iduser_receiver,
                    'idnotification' =>  $notification->id,
                ]);

                $userEPN =  User::activeForID($iduser_receiver)->first();
                
                $notificationsC = DetailUserNotifications::whereHas('notification', function ($query) use ($params) {
                    $query = $query->active()->where('idcompany', $params['idcompany']);
                    return $query;
                })->where('idreceiver', $iduser_receiver)->where('status_N', 1)->active()->count();

                $JSON = [
                    "url" => $params['data_json']['url'],
                    "count" => $notificationsC,
                    "idnotification" => $notification->id,
                ];

                if (isset($params['data_json']->idurl)) {
                    $JSON['idurl'] = $params['data_json']->idurl;
                }

                try {
                    event(new NotificationEvent(
                        $userEPN->id,
                        $params['message_title'],
                        $params['message_body'],
                        $JSON
                    ));
                } catch (BroadcastException $e) {
                    // return $this->errorResponse('Error al conectar con Pusher: ' . $e->getMessage(), 400);
                    Log::error('Error al conectar con Pusher: ' . $e->getMessage());
                }
                
            }

            DB::commit();
            return $this->successResponse('Notificacion creado con éxito', $notification);
        } catch (\Throwable $th) {
            DB::rollBack();
            throw $th;
        }
    }

    public function changeStatusN($id)
    {
        DB::beginTransaction();
        try {

            $notifications = DetailUserNotifications::whereHas('notification', function ($query) use ($id) {
                return $query->activeForID($id)->active();
            })->where('idreceiver', JWTAuth::user()->id)->where('status_N', 1)->filters()->first();
            if (!$notifications) return $this->errorResponse('Usted no es el receptor o la notificación dejo de estar pendiente', 400);
            $notifications->update(['date_seen' => now(), 'status_N' => 2]);
            $notifications->fresh();
            DB::commit();
            $notifications = NotificationsResource::make($notifications->load('notification.sender'));
            return $this->successResponse('Registro modificado a visto', $notifications);
        } catch (\Throwable $th) {
            DB::rollBack();
            throw $th;
        }
    }

    public function delete($id)
    {
        DB::beginTransaction();
        try {
            #Validar existencia del registro
            $notification = Notifications::activeForId($id)->first();
            if (!$notification) return $this->errorResponse('la notificacion no es válida.', 400);
            $notification->update(['status' => 2]);
            DB::commit();
            return $this->successResponse('Notificacion eliminada satisfactoriamente', $notification);
        } catch (\Throwable $th) {
            DB::rollBack();
            throw $th;
        }
    }
}
