<?php

namespace App\Models\Helpers;

use Carbon\Carbon as CarbonCarbon;
use DateTime;
use Hamcrest\Type\IsNumeric;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;

class General extends Model
{
    use HasFactory;

    public static function explode_with_colon($text)
    {
        try {
            $text_without_space = trim($text);
            $second_index = explode(':', $text_without_space)[1];
            return trim($second_index);
        } catch (\Throwable $th) {
            self::logError("TRYING TO EXPLODE A STRING USING ':'", $th->getMessage(), "explode_with_colon in Models/Helpers/General.php");
            return $text;
        }
    }

    public static function check_lotto_message($message)
    {
        $data = [
            'title' => '',
            'banker' => '',
            'two_sure' => '',
            'three_direct' => '',
            'permutations' => '',
        ];
        $lines_of_text = explode('---', $message);
        for ($i = 0; $i < count($lines_of_text); $i++) {
            $my_text = $lines_of_text[$i];
            //Check title
            if (str_contains(strtolower($my_text), 'title')) {
                $data['title'] = self::explode_with_colon($my_text);
            }
            //Check banker
            if (str_contains(strtolower($my_text), 'banker')) {
                $data['banker'] = self::explode_with_colon($my_text);
            }
            //Check two sure
            if (str_contains(strtolower($my_text), 'sure')) {
                $data['two_sure'] = self::explode_with_colon($my_text);
            }
            //Check three direct
            if (str_contains(strtolower($my_text), 'direct')) {
                $data['three_direct'] = self::explode_with_colon($my_text);
            }
            //Check permutations
            if (str_contains(strtolower($my_text), 'perm')) {
                $data['permutations'] = self::explode_with_colon($my_text);
            }
        }
        return $data;
    }

    public static function excel_Reading_Result($rows, $file_name, $empty_file)
    {
        try {
            $message = '';
            $path = 'ExcelReading/' . $file_name;
            $date = Carbon::now();

            if ($empty_file) {
                $message = 'No action could be performed on the file you uploaded. The reason is that the file contained no data';
            }
            if (count($rows) > 0) {
                $error_rows = json_encode($rows);
                $message = "We found some issues with the file you uploaded. The rows with errors have been specified below.\nROWS WITH ERRORS: $error_rows";
            } else {
                $myRows = json_encode($rows);
                $message = "We encountered some errors on the below specified rows. Kindly check those rows to ensure that the provided data is accurate. Thank you.\nROWS WITH ERRORS: $myRows";
            }

            Storage::put($path, "DATE: $date\nTITLE: Result After Reading Membership Data File\nMESSAGE: $message");
            return true;
        } catch (\Throwable $th) {
            Log::info('TRYING TO CREATE LOGS FOR THE EXCEL FORECAST DATA READING: === ' . $th->getMessage());
            return false;
        }
    }

    public static function convert_excel_date($my_date_as_integer)
    {
        //When a date is entered in excel, it is converted to an integer value.
        //The code below will convert it back to date form.
        try {
            $excelEpoch = new DateTime('1900-01-01'); // Excel's epoch date
            $date = clone $excelEpoch;
            $my_date = $date->modify("+" . ($my_date_as_integer - 2) . " days");
            $year = $my_date->format('Y');
            $month = $my_date->format('m');
            $day = $my_date->format('d');
            $new_date = Carbon::create($year, $month, $day);
            $current_date = Carbon::now()->startOfDay();
            if ($new_date >= $current_date) {
                return true;
            } else {
                return false;
            }
        } catch (\Throwable $th) {
            self::logError('TRYING TO CONVERT schedule in Excel Forecast Data', $th->getMessage(), 'convert_excel_date');
            return false;
            //throw $th;
        }
    }

    public static function send_user_credential($data)
    {
        $name = $data['name'];
        $email = $data['email'];
        $password = $data['password'];
        $phone = $data['phone'];

        $message = "Lotto Keys User Credential\n\nDear $name\nKindly find your credentials below\n\nEmail: $email\nPassword: $password";

        $sms_api_url            =   env('NPONTU_SMS_URL');
        $data['username']       =   env('MALTA_SMS_USERNAME');
        $data['password']       =   env('MALTA_SMS_PASSWORD');
        $data['source']         =   env('MALTA_SMS_SOURCE'); //Sender ID
        $data['destination']    =   $data['phone'];
        $data['message']        =   $message;

        $output = Http::post($sms_api_url, $data);

        return $output;
    }

    public static function send_lotto_numbers(array $my_data)
    {
        // $encoded_message        =   urlencode($message);
        $title = strtoupper($my_data['title']) ?? 'N/A';
        $banker = $my_data['banker'] ?? 'N/A';
        $two_sure = $my_data['two_sure'] ?? 'N/A';
        $three_direct = $my_data['three_direct'] ?? 'N/A';
        $permutations = $my_data['permutations'] ?? 'N/A';

        $message = "Lotto Keys FORECAST\n\n$title\n\nBanker: $banker\nTwo sure: $two_sure\nThree Direct: $three_direct\nPermutations: $permutations\n";

        $sms_api_url            =   env('NPONTU_SMS_URL');
        $data['username']       =   env('MALTA_SMS_USERNAME');
        $data['password']       =   env('MALTA_SMS_PASSWORD');
        $data['source']         =   env('MALTA_SMS_SOURCE'); //Sender ID
        $data['destination']    =   $my_data['phone'];
        $data['message']        =   $message;

        $output = Http::post($sms_api_url, $data);

        return $output;
    }

    public static function generate_password($password_count = 12)
    {
        $uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $lowercase = 'abcdefghijklmnopqrstuvwxyz';
        $numbers = '0123456789';
        $symbols = '!@#$%^&*()_+=-[]{}|;:,.<>?';

        $allChars = $uppercase . $lowercase . $numbers . $symbols;

        $password = '';
        for ($i = 0; $i < $password_count; $i++) {
            $password .= $allChars[rand(0, strlen($allChars) - 1)];
        }

        return $password;
    }

    public static function validate_phone(array $prefixes, $phone_number)
    {
        return preg_match('/^(' . implode('|', $prefixes) . ')\d{8}$/', $phone_number);
    }

    public static function clear_lotto_session()
    {
        Session::forget('title');
        Session::forget('banker');
        Session::forget('two_sure');
        Session::forget('three_direct');
        Session::forget('permutations');
        Session::forget('schedule');
    }

    public static function logError($description, $errorMessage, $method_name)
    {
        try {
            $path = 'SystemErrors/errors.log';
            $date = Carbon::now();
            $user = auth()->user()->email ?? 'Action was triggered without logging in. Hence the user cannot be determined';
            $my_content = "\nDATE & TIME: $date\nTITLE: $description\nSYSTEM USER: $user\nCONTROLLER ACTION METHOD: $method_name\nCONTENT / ERROR MESSAGE: $errorMessage\n";
            // Storage::disk('public')->append($path, $my_content);
            Log::info($my_content);
        } catch (\Throwable $th) {
            Log::info($th->getMessage());
        }
    }

    public static function log_API_data($description, $errorMessage, $method_name)
    {
        try {
            $path = 'API/api_errors.log';
            $date = Carbon::now();
            // $user = auth()->user()->email ?? 'Action was triggered without logging in. Hence the user cannot be determined';
            $my_content = "DATE & TIME: $date\nTITLE: $description\nCONTROLLER ACTION METHOD: $method_name\nCONTENT / ERROR MESSAGE: $errorMessage\n";
            Storage::disk('public')->append($path, $my_content);
        } catch (\Throwable $th) {
            Log::info($th->getMessage());
        }
    }

    public static function check_banker($value)
    {
        try {
            $new_value = intval($value);
            if ($new_value > 0 && $new_value < 90) {
                return true;
            } else {
                return false;
            }
        } catch (\Throwable $th) {
            self::logError('TRYING TO VALIDATE BANKER NUMBER', $th->getMessage(), 'check_banker in Models/Helpers/General.php');
            return false;
        }
    }

    public static function check_two_sure($values)
    {
        $my_array = [];
        // Remove any non-numeric characters
        $array_of_numbers = explode('-', $values);
        if (count($array_of_numbers) == 2) {
            for ($i = 0; $i < count($array_of_numbers); $i++) {
                $current_number = $array_of_numbers[$i];
                if (is_numeric($current_number) && intval($current_number)) {
                    $num = intval($current_number);
                    if ($num < 0 || $num > 90) {
                        // return true;
                        array_push($my_array, $current_number);
                    }
                } else {
                    array_push($my_array, $current_number);
                }
            }
        } else {
            array_push($my_array, '00');
        }
        return $my_array;
    }

    public static function check_three_direct($values)
    {
        $my_array = [];
        // Remove any non-numeric characters
        $array_of_numbers = explode('-', $values);
        if (count($array_of_numbers) == 3) {
            for ($i = 0; $i < count($array_of_numbers); $i++) {
                $current_number = $array_of_numbers[$i];
                if (is_numeric($current_number) && intval($current_number)) {
                    $num = intval($current_number);
                    if ($num < 0 || $num > 90) {
                        // return true;
                        array_push($my_array, $current_number);
                    }
                } else {
                    array_push($my_array, $current_number);
                }
            }
        } else {
            array_push($my_array, '00');
        }
        return $my_array;
    }

    public static function check_permutations($values)
    {
        $my_array = [];
        // Remove any non-numeric characters
        $array_of_numbers = explode('-', $values);
        if (count($array_of_numbers) > 2) {
            for ($i = 0; $i < count($array_of_numbers); $i++) {
                $current_number = $array_of_numbers[$i];
                if (is_numeric($current_number) && intval($current_number)) {
                    $num = intval($current_number);
                    if ($num < 0 || $num > 90) {
                        // return true;
                        array_push($my_array, $current_number);
                    }
                } else {
                    array_push($my_array, $current_number);
                }
            }
        } else {
            array_push($my_array, '00');
        }
        return $my_array;
    }

    public static function is_a_number($value)
    {
        if (is_numeric($value)) {
            $num = intval($value);
            if (($num > 0) && ($num < 90)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}
