<?php

use App\Models\User;
use App\Models\Setting;
use App\Models\Organization;

if (!function_exists("get_user_name")) {
    function get_user_name($user)
    {
        return $user->user_name;
    }

}

if (!function_exists("get_email_signature")) {
    function get_email_signature($user = null)
    {
        $email_signature = Setting::where("settings_key", "mail_signature")->first()->settings_value;
        return isset($email_signature) ? $email_signature : 'Smart Report Maker Team';
    }

}

if (!function_exists("get_from_name")) {
    function get_from_name()
    {
        $from_name = Setting::where("settings_key", "fromName")->first()->settings_value;

        return isset($from_name) ? $from_name : get_owner()->user_name;
    }

}

if (!function_exists("get_from_email")) {
    function get_from_email()
    {
        $from_email = Setting::where("settings_key", "fromEmail")->first()->settings_value;

        return isset($from_email) ? $from_email : get_owner()->Email;
    }

}

if (!function_exists("get_owner")) {
    function get_owner()
    {
        $owner = User::where('is_owner', 1)->first();

        return isset($owner) ? $owner : false;
    }

}

if (!function_exists("get_organization")) {
    function get_organization()
    {
        $organization = Organization::first() !== null ? Organization::first()->name : null;

        return isset($organization) ? $organization : 'Smart Report Maker Team';
    }

}


/**
 * Get the receivers for the task, combining users from groups, task admins, and the "from" email.
 *
 * This function collects all the receivers for a given task by merging users from task groups, task admins,
 * and the "from" email address. It also handles excluding users based on retry count and manually triggered tasks.
 *

 * @tag srm_schdular
 */
if (!function_exists("getReceivers")) {
    function getReceivers($task, $taskGroups, $manual = false)
    {
        $receivers = [];

        foreach ($taskGroups as $group) {
            $receivers[] = array_map(function ($userGroup) {
                return [
                    "id"        => $userGroup["user_ID"],
                    "email"     => $userGroup["Email"],
                    "username"  => $userGroup["user_name"],
                    "firstname" => $userGroup["first_name"]
                ];
            }, $group->users->where('status', 'Active')
                    ->whereNotNull('email_verified_at')->toArray());
        }

        $mergedArray = call_user_func_array('array_merge', array_map('array_values', $receivers));

        $fromEmail = [
            [

                "id"         => "from_id",
                "email"      => get_from_email(),
                "username"   => get_from_name(),
                "first_name" => get_from_name()
            ]
        ];

        $finalArray = array_merge($mergedArray, getTaskAdmins($task), $fromEmail);

        if ($task->retry_count > 0 && !$manual) {
            $task->recieved_users = !is_null($task->recieved_users) ? $task->recieved_users : [];
            return excludeUsers(uniqueUsersBy($finalArray, 'email'), $task->recieved_users);
        }

        return uniqueUsersBy($finalArray, 'email');
    }

}


/**
 * Excludes specific users from the given list of users.
 *
 * This function filters out users from the list based on their ID, removing any user in the excluded list.
 *
 * @tag srm_schdular
 */
if (!function_exists("excludeUsers")) {

    function excludeUsers($users, $excludedUsers)
    {
        $filteredUsers = array_filter($users, function ($user) use ($excludedUsers) {
            return !in_array($user['id'], $excludedUsers);
        });
        return array_values($filteredUsers);

    }

}


/**
 * Generates personalized email bodies for each receiver.
 *
 * This function generates email bodies for each receiver, replacing placeholders with user-specific information.
 *
 * @tag srm_schdular
 */
if (!function_exists("getBodies")) {

    function getBodies($resource, $body, $receivers)
    {
        $bodies = [];

        foreach ($receivers as $receiver) {
            $firstName            = isset($receiver['firstname']) ? $receiver['firstname'] : $receiver['username'];
            $email                = isset($receiver['email']);
            $withFirstName        = str_replace("{{user first name}}", $firstName, $body);
            $resourceStatement    = getResourceStatement($resource);
            $withResourceStatment = strpos($withFirstName, "{{email signature}}") !== false ? str_replace("{{email signature}}", "$resourceStatement\n{{email signature}}", $withFirstName) : $withFirstName . "\n$resourceStatement";
            $finalBody            = str_replace("{{email signature}}", get_email_signature(), $withResourceStatment);
            $bodies[]             = $finalBody;
        }

        return $bodies;
    }

}


/**
 * Retrieves the admins related to a specific task.
 *
 * This function returns a list of admins for the given task based on the task's settings.
 *
 * @tag srm_schdular
 */
if (!function_exists("getTaskAdmins")) {

    function getTaskAdmins($task)
    {

        if ($task->send_to_admins) {

            $adminCollection = User::where('is_admin', 1)->orWhere('is_owner', 1)->get()->toArray();
            $admins          = array_map(function ($admin) {
                return [
                    "id"        => $admin["user_ID"],
                    "email"     => $admin["Email"],
                    "username"  => $admin["user_name"],
                    "firstname" => $admin["first_name"]
                ];
            }, $adminCollection);

        } else {
            $taskAdmins = $task->created_by == $task->edited_by || is_null($task->edited_by)
            ? [$task->createdBy->toArray()]
            : [$task->createdBy->toArray(), $task->editedBy->toArray()];

            $admins = array_map(function ($admin) {
                return [
                    "id"        => $admin["user_ID"],
                    "email"     => $admin["Email"],
                    "username"  => $admin["user_name"],
                    "firstname" => $admin["first_name"]
                ];
            }, $taskAdmins);

        }

        return $admins;
    }

}

/**
 * Removes duplicates from an array based on a given key.
 *
 * This function filters the array of users, removing duplicates based on a specific key.
 *
 * @tag srm_schdular
 */
if (!function_exists("uniqueUsersBy")) {

    function uniqueUsersBy($array, $key)
    {
        $uniqueEmails = [];
        $uniqueUsers  = [];

        foreach ($array as $user) {

            if (!in_array($user[$key], $uniqueEmails)) {
                $uniqueEmails[] = $user[$key];
                $uniqueUsers[]  = $user;
            }

        }

        return $uniqueUsers;
    }

}
