<?php

use App\Models\NotificationSetting;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use PHPMailer\PHPMailer\PHPMailer;

if (!function_exists('dateInCustomTimezone')) {

    function dateInCustomTimezone($date, $format = "d M, Y -  h:i A", $timezone = "Asia/Dubai", $serverTimezone = "UTC")
    {
        // Use Laravel's timezone configuration if the server timezone is not provided
        $server_time_zone = $serverTimezone ?? config('app.timezone', 'UTC');

        try {
            // Parse the date in the server timezone
            $dateInServerTimeZone = Carbon::parse($date, $server_time_zone);

            // Convert to the user's timezone and format
            return $dateInServerTimeZone->timezone($timezone)->format($format);
        } catch (Exception $e) {
            // Handle invalid date or timezone errors
            return "Invalid date or timezone provided.";
        }
    }
}

if (!function_exists('image_upload')) {
    function image_upload($request,$model,$file_name, $mb_file_size = 25)
    {

        if($request->file($file_name ))
        {
            $file = $request->file($file_name);
            return  file_save($file,$model, $mb_file_size);
        }
        return ['status' =>false,'link'=>null,'message' => 'Unable to upload file'];
    }

    
}
if (!function_exists('file_save')) {
    function file_save($file,$model,$mb_file_size=25)
    {
        try {
            $model = str_replace('/','',$model);
            //validateSize
            $precision = 2;
            $size = $file->getSize();
            $size = (int) $size;
            $base = log($size) / log(1024);
            $suffixes = array(' bytes', ' KB', ' MB', ' GB', ' TB');
            $dSize = round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];

            $aSizeArray = explode(' ', $dSize);
            if ($aSizeArray[0] > $mb_file_size && ($aSizeArray[1] == 'MB' || $aSizeArray[1] == 'GB' || $aSizeArray[1] == 'TB')) {
                return ['status' =>false,'link'=>null,'message' => 'Image size should be less than equal '.$mb_file_size.' MB'];
            }
            // rename & upload files to upload folder
                    
            $fileName = uniqid() . '_' . time() . '.' . $file->getClientOriginalExtension();
            $filePath = $file->storeAs($model,$fileName,config('global.upload_bucket'));
            $image_url = $fileName;
                
            return ['status' =>true,'link'=>$image_url,'message' => 'file uploaded'];

        } catch (\Exception $e) {
            return ['status' =>false,'link'=> null ,'message' => $e->getMessage()];
        }
    }
}
if (!function_exists('generate_otp')) {
    function generate_otp(){
        //return rand(1111,9999);
        return 1111;
    }
}

if (!function_exists('send_normal_SMS')) {
    function send_normal_SMS($message, $mobile_numbers, $sender_id = "")
    {
        //return true;
        $curl = curl_init();
        $token = env('SMS_API_KEY'); // Replace it with your API Token
        $originator = "AutoSplash"; // Replace it with your Sender ID
        $recipients = array("+".str_replace("+","",$mobile_numbers)); // Replace it with real recipients
        $content = $message;
        $message_obj =  array(
            "channel"=> "sms",
            "msg_type"=> "text",
            "recipients"=> $recipients,
            "content"=> $content,
            "data_coding"=> "auto"
        );
        $globals_obj = array(
            "originator"=> $originator,
            "report_url"=> "https://the_url_to_recieve_delivery_report.com",
        );
        $payload = json_encode(
            array(
                "messages"=> array($message_obj),
                "message_globals"=> $globals_obj
            )
        );
        curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://api.d7networks.com/messages/v1/send',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS =>$payload,
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json',
            'Accept: application/json',
            'Authorization: Bearer '.$token
        ),
        ));
        $response = curl_exec($curl);
    // printr($response); exit;
        curl_close($curl);
        return  $response;
    }
}

if (!function_exists('convert_all_elements_to_string')) {
    function convert_all_elements_to_string($data = null, $emptyArrayShouldBeObject = false)
    {
        if ($data != null) {
            array_walk_recursive($data, function (&$value, $key) use ($emptyArrayShouldBeObject) {
                if (!is_object($value)) {
                    if ($value) {
                        $value = (string) $value;
                    } else {
                        $value = (string) $value;
                    }
                } else {
                    $json = json_encode($value);
                    $array = json_decode($json, true);

                    array_walk_recursive($array, function (&$obj_val, $obj_key) use ($emptyArrayShouldBeObject) {
                        $obj_val = (string) $obj_val;
                    });

                    if (!empty($array)) {
                        $json = json_encode($array);
                        $value = json_decode($json);
                    } else {
                        if ($emptyArrayShouldBeObject) {
                            $value = (object)[];
                        } else {
                            $value = [];
                        }
                    }
                }
            });
        }
        return $data;
    }
}

if (!function_exists('convert_all_elements_to_string_new')) {
    /**
     * Convert all scalar values to strings recursively while allowing certain keys to be skipped.
     *
     * @param mixed $data
     * @param bool $emptyArrayShouldBeObject When true, empty arrays/objects become (object)[]
     * @param array $skipKeys Keys to skip conversion for (exact key match)
     * @return mixed
     */
    function convert_all_elements_to_string_new($data = null, $emptyArrayShouldBeObject = false, $skipKeys = ['answer', 'question'])
    {
        if ($data === null) {
            return $data;
        }

        // We need to work on arrays (array_walk_recursive works only on arrays)
        // If top-level is object, convert to array first for traversal, but keep track to restore.
        $isTopLevelObject = is_object($data);

        if ($isTopLevelObject) {
            $data = json_decode(json_encode($data), true);
        }

        array_walk_recursive($data, function (&$value, $key) use ($emptyArrayShouldBeObject, $skipKeys) {
            // If this key is in skip list, preserve structure:
            if (in_array($key, $skipKeys, true)) {
                // If it's an empty array, convert to object when requested
                if (is_array($value) && empty($value) && $emptyArrayShouldBeObject) {
                    $value = (object) [];
                }
                // If it's null and we want object, make empty object
                if ($value === null && $emptyArrayShouldBeObject) {
                    $value = (object) [];
                }
                return;
            }

            // If value is an object (stdClass) it will be converted to array earlier,
            // but keep this check for safety if someone passes objects inside.
            if (is_object($value)) {
                // Convert object -> array to walk its values, then re-encode
                $json = json_encode($value);
                $array = json_decode($json, true);

                // Walk and cast nested scalars to string
                array_walk_recursive($array, function (&$obj_val) use ($emptyArrayShouldBeObject) {
                    if ($obj_val === null) {
                        $obj_val = (string) $obj_val;
                    } else {
                        $obj_val = (string) $obj_val;
                    }
                });

                if (!empty($array)) {
                    $value = json_decode(json_encode($array)); // object
                } else {
                    // empty => keep as object or empty array depending on flag
                    $value = $emptyArrayShouldBeObject ? (object) [] : [];
                }

                return;
            }

            // Arrays: array_walk_recursive will continue inside them; when scalar leaf:
            // Convert scalars (including null/false/0) to string (same behavior as original)
            if (!is_array($value) && !is_object($value)) {
                $value = (string) $value;
            }
        });

        // After traversal, restore top-level object if needed.
        if ($isTopLevelObject) {
            // Convert top-level array back to object (so empty objects remain objects)
            $data = json_decode(json_encode($data));
        }

        return $data;
    }
}


if (!function_exists('processAccesToken')) {
    function processAccesToken($access_token)
    {
        $user = App\Models\User::where(['user_access_token' => $access_token])->get();

        if ($user->count() == 0) {
            return 0;
        } else {
            $user = $user->first();
            return $user->id??0;
        }
    }
}

if (!function_exists('generate_random_string')) {
    function generate_random_string($length = 10)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[random_int(0, $charactersLength - 1)];
        }
        return $randomString;
    }
}

if (! function_exists('get_uploaded_image_url') ) {
    function get_uploaded_image_url( $filename='', $dir='', $default_file='placeholder.png' )
    {

        if ( !empty($filename) ) {

            $upload_dir = config('global.upload_path');
            if (! empty($dir) ) {
                $dir= config("global.{$dir}");
               
            }
            return \Storage::disk(config('global.upload_bucket'))->url($dir.$filename);
            if ( \Storage::disk(config('global.upload_bucket'))->exists($dir.$filename) ) {
                // return 'https://d3k2qvqsrjpakn.cloudfront.net/moda/public'.\Storage::url("{$dir}{$filename}");
                return \Storage::disk(config('global.upload_bucket'))->url($dir.$filename);
                //return asset(\Storage::url("{$dir}{$filename}"));
           }else{

            return asset(\Storage::url("{$dir}{$filename}"));
           }
        }
        if ( !empty($default_file) ) {
            if (! empty($dir) ) {
                $dir= config("global.{$dir}");
            }
            $default_file = asset(\Storage::url("{$dir}{$default_file}"));
        }
        if (! empty($default_file) ) {
            return $default_file;
        }


        return \Storage::url("logo.png");
    }
}
function send_email($to, $subject, $mailbody)
{
    require base_path("./vendor/autoload.php");
    $mail = new PHPMailer(true);

    try {
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = "smtp.gmail.com";
        $mail->SMTPAuth = true;
        $mail->Username = "info@luqia.ae";
        $mail->Password = "znfdirikfqwebqgy";
        $mail->SMTPSecure = "STARTTLS";
        $mail->Port = 587;
        $mail->setFrom("info@luqia.ae");
        $mail->addAddress($to);
        $mail->isHTML(true);
        $mail->addCC('anilnavis@gmail.com');
        $mail->addBCC('sooraj.a2solution@gmail.com');
        $mail->Subject = $subject;
        $mail->Body    = $mailbody;
        $mail->SMTPOptions = [
            'ssl' => [
                'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
            ]
        ];
        if (!$mail->send()) {
            // dd($mail);
        } else {
            return ['status' => true, 'message' => 'Email sent successfully'];
        }
    } catch (Exception $e) {
        // dd($e->getMessage());
        return ['status' => false, 'error' => $e->getMessage()];
    }
}

  if (! function_exists('get_user_notification_setting')) {
    function get_user_notification_setting($user_id, $slug)
    {
        $allSettings = NotificationSetting::where('user_id', $user_id)
        ->where('slug', 'all')
        ->first();
        if($allSettings && $allSettings->value == true){
            return NotificationSetting::where('user_id', $user_id)
            ->where('slug', $slug)
            ?->first()
            ->value ?? null;

        }
        if($allSettings && $allSettings->value == false){
            return false;

        }
        return false;
    }
}


  if (! function_exists('convertNullRelationsToObjects')) {

    function convertNullRelationsToObjects(array|object &$data)
    {
        $relations = [
            'children', 'preference', 'preference.sect', 'preference.education', 'preference.profession', 'images', 'nationality', 'emirate', 'country', 'details',
            'details.sect', 'details.education', 'details.profession', 'details.marital_status',
            'details.dress_code', 'plan', 'sports', 'activities', 'known_languages',
            'notification_settings', 'genetic_diseases'
        ];

        $isList = isIndexedArray($data);
        $items = $isList ? $data : [$data];

        foreach ($items as &$item) {
            foreach ($relations as $relation) {
                setRelationObject($item, explode('.', $relation));
            }
        }

        $data = $isList ? $items : $items[0];
    }

    function isIndexedArray(array $arr): bool
    {
        return array_keys($arr) === range(0, count($arr) - 1);
    }

    function setRelationObject(&$item, array $path)
    {
        $current = &$item;

        foreach ($path as $index => $key) {
            $isLast = $index === count($path) - 1;

            if (is_array($current)) {
                if (!isset($current[$key]) || $current[$key] === null) {
                    $current[$key] = $isLast ? (object)[] : [];
                } elseif (!is_array($current[$key]) && !is_object($current[$key])) {
                    $current[$key] = $isLast ? (object)[] : [];
                }

                $current = &$current[$key];
            } elseif (is_object($current)) {
                if (!isset($current->$key) || $current->$key === null) {
                    $current->$key = $isLast ? (object)[] : [];
                } elseif (!is_array($current->$key) && !is_object($current->$key)) {
                    $current->$key = $isLast ? (object)[] : [];
                }

                $current = &$current->$key;
            } else {
                // If not array or object, reset to empty array/object
                $current = $isLast ? (object)[] : [];
            }
        }
    }
}

if (! function_exists('getRelegiousCount')) {
    function getRelegiousCount($relegiousCount, $lang = 'en')
    {
        if (is_null($relegiousCount)) {
            if($lang == 'ar'){
                return 'الجميع';
            } else {
                return 'Any';
            }
        }

        $ranges = [
            [
            'from' => 0,
            'to' => 33,
            'label_en' => 'Not Practicing',
            'label_ar' => 'غير ممارس'
            ],
            [
            'from' => 34,
            'to' => 66,
            'label_en' => 'Moderate Practicing',
            'label_ar' => 'ممارس معتدل'
            ],
            [
            'from' => 67,
            'to' => 100,
            'label_en' => 'Very Practicing',
            'label_ar' => 'ممارس جدا'
            ],
        ];

        foreach ($ranges as $range) {
            if ($relegiousCount >= $range['from'] && $relegiousCount <= $range['to']) {
            return $range['label_' . $lang];
            }
        }

        return 'Out of Range';
    }
}

function send_notification_to_user($firebaseDB, $user, $data = [], $permission = '' , $type = '', $notificationId = '', $title = '', $description = '', $imageURL = ''){

    if (!empty($user->firebase_user_key)) {
        $notification_data["Notifications/" . $user->firebase_user_key . "/" . $notificationId] = array_merge([
            "title" => $title,
            "description" => $description,
            "notificationType" => $type,
            "createdAt" => gmdate("d-m-Y H:i:s", $notificationId),
            "status" => (string)1,
            "url" => "",
            "imageURL" => $imageURL,
            "read" => "0",
            "seen" => "0",
        ], $data);
        $firebaseDB->getReference()->update($notification_data);
    }

    if(!get_user_notification_setting($user->id, $permission)){
        return;
    }

    if (!empty($user->user_device_token)) {
        $res = send_single_notification(
            $user->user_device_token,
            [
                "title" => $title,
                "body" => $description,
                "icon" => 'myicon',
                "sound" => 'default',
                "click_action" => "EcomNotification"
            ],
            array_merge([
                "type" => $type,
                "notificationID" => $notificationId,
                "status" => (string) 1,
                "imageURL" => $imageURL,
            ],$data)
        );
    }
}




if (!function_exists('processConnectionStatus')) {
    function processConnectionStatus($currentUser, $targetUsers,$forceProfile=false)
    {
        $targetUsers = collect($targetUsers);

        // Get sent and received connection request IDs
        $sentRequests = DB::table('user_requests')
            ->where('sender_id', $currentUser->id)
            ->pluck('receiver_id')
            ->toArray();

        $receivedRequests = DB::table('user_requests')
            ->where('receiver_id', $currentUser->id)
            ->pluck('sender_id')
            ->toArray();

        // Get blocked user IDs (both directions)
        $blockedByMe = DB::table('user_blocks')
            ->where('user_id', $currentUser->id)
            ->pluck('blocked_user_id')
            ->toArray();

        $blockedMe = DB::table('user_blocks')
            ->where('blocked_user_id', $currentUser->id)
            ->pluck('user_id')
            ->toArray();

        // Get reported user IDs (both directions)
        $reportedByMe = DB::table('user_reports')
            ->where('reporter_id', $currentUser->id)
            ->pluck('reported_user_id')
            ->toArray();

        $reportedMe = DB::table('user_reports')
            ->where('reported_user_id', $currentUser->id)
            ->pluck('reporter_id')
            ->toArray();

        // Combine all blocked and reported user IDs to exclude
        $excludedUserIds = array_unique(array_merge(
            $blockedByMe,
            $blockedMe,
            $reportedByMe,
            $reportedMe
        ));
        

        if(!$forceProfile){
        // Exclude blocked/reported users from the target list
        $filteredUsers = $targetUsers->reject(function ($user) use ($excludedUserIds) {
            return in_array($user->id, $excludedUserIds);
        });
    }else{
$filteredUsers=$targetUsers;
    }

        // Process connection statuses and flags for filtered users
        return $filteredUsers->map(function ($u) use (
            $currentUser, $sentRequests, $receivedRequests,
            $blockedByMe, $blockedMe, $reportedByMe, $reportedMe
        ) {
            $is_blocked = in_array($u->id, $blockedByMe);
            $am_i_blocked = in_array($u->id, $blockedMe);
            $is_reported = in_array($u->id, $reportedByMe);
            $am_i_reported = in_array($u->id, $reportedMe);

            $connection = DB::table('user_connections')
                ->where(function ($query) use ($currentUser, $u) {
                    $query->where('user_id', $currentUser->id)
                          ->where('connected_user_id', $u->id);
                })
                ->orWhere(function ($query) use ($currentUser, $u) {
                    $query->where('user_id', $u->id)
                          ->where('connected_user_id', $currentUser->id);
                })
                ->first();
$connection1 = DB::table('user_connections')
    ->where('user_id', $currentUser->id)
    ->where('connected_user_id', $u->id)
    ->first();

$hideImageByCurrentUser = $connection1 ? (int) $connection1->hide_image : 0;

$ppRequest = DB::table('profile_picture_requests')
    ->where('sender_id', $currentUser->id)
    ->where('receiver_id', $u->id)
    ->first();

$hideImageByTargetUser = ($ppRequest && $ppRequest->status == 'accepted') ? '0' : '1';

$u->hide_image_by_current_user = $hideImageByCurrentUser;
$u->hide_image_by_target_user = $hideImageByTargetUser;

$existingChat = App\Models\Chat::where(function($query) use ($currentUser,$u) {
            $query->where('user_id_1', $currentUser->id)
                  ->where('user_id_2', $u->id);
        })->orWhere(function($query) use ($currentUser,$u) {
            $query->where('user_id_1', $u->id)
                  ->where('user_id_2', $currentUser->id);
        })->whereIn('status', ['active', 'pending_decision', 'need_more_time'])->first();
$u->chat_id = "0";
if($existingChat){
    $u->chat_id = $existingChat->id;
}
            $blockedOrReported = $is_blocked || $am_i_blocked || $is_reported || $am_i_reported;

            $u->is_connected = (!$blockedOrReported && $connection) ? 1 : 0;
            $u->is_image_blur=$u->is_connected?0: $u->is_image_blur;
            $u->connection_request_id = "0";
            if($connection){
                $u->connection_request_id = (string)($connection->id??0);
            }
            //$u->active_request_count = (string)$u->active_request_count;

            $u->is_blocked = $is_blocked ? 1 : 0;
            $u->am_i_blocked = $am_i_blocked ? 1 : 0;

            $u->is_reported = $is_reported ? 1 : 0;
            $u->am_i_reported = $am_i_reported ? 1 : 0;

            $u->is_sent = ((!$u->is_connected && !$blockedOrReported) && in_array($u->id, $sentRequests)) ? 1 : 0;
            $u->is_received = (!$u->is_connected && !$blockedOrReported && in_array($u->id, $receivedRequests)) ? 1 : 0;

            $u = $u->toArray();
            convertNullRelationsToObjects($u);
            return convert_all_elements_to_string($u, true);
        })->values()->toArray();
    }
}

