<?php

namespace App\Models;

use Illuminate\Support\Facades\Config;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use App\Models\Quiz_Configuration;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\URL;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class Common extends Model
{
    // Image Functions
    public function getImage($folder = "", $name = "")
    {
        try {
            $appUrl = Config::get('app.image_url');

            if (!empty($folder) && !empty($name)) {

                $filePath = $folder . '/' . $name;
                if (Storage::disk('public')->exists($filePath)) {
                    return $appUrl . $filePath;
                }
            }
            $defaultImage = ($folder === "user") ? asset('assets/imgs/default.png') : asset('assets/imgs/no_img.png');
            return $defaultImage;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function getFile($folder = "", $name = "")
    {
        try {
            $appUrl = Config::get('app.image_url');

            if (!empty($folder) && !empty($name)) {

                $filePath = $folder . '/' . $name;
                if (Storage::disk('public')->exists($filePath)) {
                    return $appUrl . $filePath;
                }
            }
            $defaultImage = "";
            return $defaultImage;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function imageNameToUrl($array, $column, $folder)
    {
        try {
            $appName = Config::get('app.image_url');
            $defaultImage = ($folder === "user") ? asset('assets/imgs/default.png') : asset('assets/imgs/no_img.png');

            foreach ($array as $key => $value) {
                $imageName = $value[$column] ?? '';

                if (!empty($imageName) && Storage::disk('public')->exists("$folder/$imageName")) {
                    $array[$key][$column] = $appName . $folder . '/' . $imageName;
                } else {
                    $array[$key][$column] = $defaultImage;
                }
            }
            return $array;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function saveImage($org_name, $folder, $prefix = "")
    {
        try {
            $img_ext = $org_name->getClientOriginalExtension();
            $filename = $prefix . date('Y_m_d_') . uniqid() . '.' . $img_ext;
            $org_name->move(base_path('storage/app/public/' . $folder), $filename);

            return $filename;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function deleteImageToFolder($folder, $name)
    {
        try {

            Storage::disk('public')->delete($folder . '/' . $name);
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function userImage($array) // 1- File Upload, 2- Avatar
    {
        try {
            foreach ($array as $key => $value) {

                if ($value['image_type'] == 1) {
                    $value['image'] = $this->getImage('user', $value['image']);
                } else if ($value['image_type'] == 2) {
                    $value['image'] = $this->getAvatarImage($value['image']);
                }
            }
            return $array;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function getAvatarImage($avatar_id)
    {
        try {

            $avatar = Avatar::where('id', $avatar_id)->first();
            if ($avatar) {
                return $this->getImage('avatar', $avatar['image']);
            }
            return asset('assets/imgs/default.png');
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }

    // Basic Function
    public function user_name($string)
    {
        $rand_number = rand(1111, 9999);
        $user_name = '@' . $string . '_' . $rand_number;

        $check = User::where('user_name', $user_name)->first();
        if ($check) {
            $this->user_name($string);
        }
        return $user_name;
    }
    public function user_bio()
    {
        return "Quiz lover exploring knowledge with " . App_Name() . "!";
    }
    function generateReferralCode($length = 6)
    {
        $characters = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
        $maxAttempts = 10;

        for ($i = 0; $i < $maxAttempts; $i++) {
            $code = '';
            for ($j = 0; $j < $length; $j++) {
                $code .= $characters[random_int(0, strlen($characters) - 1)];
            }

            if (!User::where('reference_code', $code)->exists()) {
                return $code;
            }
        }
        return "000000";
    }
    function create_room_code($length = 6)
    {
        $characters = '1234567890';
        $maxAttempts = 10;

        for ($i = 0; $i < $maxAttempts; $i++) {
            $code = '';
            for ($j = 0; $j < $length; $j++) {
                $code .= $characters[random_int(0, strlen($characters) - 1)];
            }

            if (!One_vs_One_Battles::where('room_code', $code)->exists()) {
                return $code;
            }
        }
        return "000000";
    }
    function Quiz_Configuration($id)
    {
        $quiz = Quiz_Configuration::where('id', $id)->first()->toArray();
        if ($quiz) {

            // if ($id == 1) {
            //     $quiz['sort_order'] = explode(',', $quiz['quiz_sort_order'] ?? "");
            // }
            return $quiz;
        }
        return [];
    }
    function Inactive_Challenge()
    {
        Ultimate_Challenge::where('end_date', '<', date('Y-m-d'))->update(['status' => 0]);
    }
    public function SetSmtpConfig()
    {
        $smtp = Smtp_Setting::latest()->first();
        if (isset($smtp) && $smtp != null && $smtp['status'] == 1) {

            if ($smtp) {
                $data = [
                    'driver' => 'smtp',
                    'host' => $smtp['host'],
                    'port' => $smtp['port'],
                    'encryption' => 'tls',
                    'username' => $smtp['user'],
                    'password' => $smtp['pass'],
                    'from' => [
                        'address' => $smtp['from_email'],
                        'name' => $smtp['from_name']
                    ]
                ];
                Config::set('mail', $data);
            }
        }
        return true;
    }
    public function is_badge_win($user_id, $badge_id)
    {
        return User_Badge_List::where('user_id', $user_id)->where('badge_id', $badge_id)->exists() ? 1 : 0;
    }
    public function get_quiz_config($quiz_id)
    {
        return Quiz_Configuration::where('id', $quiz_id)->first();
    }
    public function is_pass_level($user_id, $quiz_id, $category_id, $skill_id, $classification_id, $level_id)
    {
        if ($quiz_id == 2) {
            return Normal_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->where('status', 1)->exists() ? 1 : 0;
        }
        if ($quiz_id == 3) {
            return Audio_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->where('status', 1)->exists() ? 1 : 0;
        }
        if ($quiz_id == 4) {
            return Video_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->where('status', 1)->exists() ? 1 : 0;
        }
        if ($quiz_id == 5) {
            return True_False_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->where('status', 1)->exists() ? 1 : 0;
        }
        if ($quiz_id == 6) {
            return Fear_Factor_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->where('status', 1)->exists() ? 1 : 0;
        }
    }
    public function quiz_config_total_question($quiz_id)
    {
        return Quiz_Configuration::where('id', $quiz_id)->value('total_questions') ?? 0;
    }
    public function is_played_quiz($quiz_id, $user_id, $category_id, $skill_id, $classification_id, $level_id)
    {
        if ($quiz_id == 2) {
            return Normal_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
        if ($quiz_id == 3) {
            return Audio_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
        if ($quiz_id == 4) {
            return Video_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
        if ($quiz_id == 5) {
            return True_False_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
        if ($quiz_id == 6) {
            return Fear_Factor_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
        if ($quiz_id == 6) {
            return Fear_Factor_Quiz_Leaderboard::where('user_id', $user_id)->where('category_id', $category_id)->where('skill_id', $skill_id)->where('classification_id', $classification_id)->where('level_id', $level_id)->exists() ? 1 : 0;
        }
    }
    public function create_qr_code($user_id)
    {
        $user_id = $user_id ?? 0;

        $qr = QrCode::format('svg')->size(300)->generate($user_id);
        $filename = 'user/user_' . $user_id . '.svg';
        Storage::disk('public')->put($filename, $qr);

        return 'user_' . $user_id . '.svg';
    }
    public function notifly()
    {
        $data = Setting_Data();
        $app_id = $data['onesignal_app_id'] ?? "q";
        $rest_key = $data['onesignal_rest_key'] ?? "q";

        if (!$app_id || !$rest_key) {
            return false;
        }

        $users = User::where('wallet_coin', '!=', 0)->whereNotNull('device_token')->where('device_type', '!=', 0)->get();
        foreach ($users as $user) {

            $deviceType = $user['device_type'];
            $deviceToken = $user['device_token'];
            $balance = $user['wallet_coin'];
            $userName = $user['full_name'] ?? $user['user_name'];

            $message = "Hi {$userName}, your current wallet balance is {$balance}";
            $fields = [
                'app_id' => $app_id,
                'headings' => ['en' => App_Name()],
                'contents' => ['en' => $message],
                'channel_for_external_user_ids' => 'push'
            ];

            switch ($deviceType) {
                case 1: // Android
                    $fields['include_android_reg_ids'] = [$deviceToken];
                    break;
                case 2: // iOS
                case 3: // Web
                    $fields['include_player_ids'] = [$deviceToken];
                    break;
                default:
                    continue 2; // skip invalid device type
            }

            $this->sendOneSignalNotification($fields, $rest_key);

            Log::info("📤 Wallet balance sent to {$userName}");
        }
    }
    private function sendOneSignalNotification($fields, $restKey)
    {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => "https://onesignal.com/api/v1/notifications",
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json; charset=utf-8',
                'Authorization: Basic ' . $restKey,
            ],
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($fields),
            CURLOPT_SSL_VERIFYPEER => false,
        ]);

        $response = curl_exec($ch);
        $status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($status !== 200) {
            Log::error("❌ OneSignal send failed. Status: {$status}, Response: {$response}");
        }
    }
    function send_verify_mail($id, $email)
    {
        try {

            $this->SetSmtpConfig();

            $smtp = Smtp_Setting::latest()->first();
            if ($smtp && $smtp['status'] == 1) {

                $signedUrl = URL::temporarySignedRoute(
                    'verify_email',
                    now()->addMinutes(60),
                    ['id' => $id, 'email' => $email]
                );

                $details = [
                    'title' => App_Name() . ' - Verify Your Email',
                    'body' => 'Thank you for registering. Please verify your email by clicking the button below.',
                    'verify_url' => $signedUrl
                ];

                // Send Mail
                Mail::to($email)->send(new \App\Mail\mail($details, 'mail.register'));
                return true;
            } else {
                return true;
            }
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    function forgot_password($length = 6)
    {
        $characters = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';

        $code = '';
        for ($j = 0; $j < $length; $j++) {
            $code .= $characters[random_int(0, strlen($characters) - 1)];
        }
        return $code;
    }

    // API's Functions
    public function API_Response($status_code, $message, $array = [], $pagination = '')
    {
        try {
            $data['status'] = $status_code;
            $data['message'] = $message;

            if ($status_code == 200) {
                $data['result'] = $array;
            }

            if ($pagination) {
                $data['total_rows'] = $pagination['total_rows'];
                $data['total_page'] = $pagination['total_page'];
                $data['current_page'] = $pagination['current_page'];
                $data['more_page'] = $pagination['more_page'];
            }
            return $data;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function more_page($current_page, $page_size)
    {
        try {
            $more_page = false;
            if ($current_page < $page_size) {
                $more_page = true;
            }
            return $more_page;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
    public function pagination_array($total_rows, $page_size, $current_page, $more_page)
    {
        try {
            $array['total_rows'] = $total_rows;
            $array['total_page'] = $page_size;
            $array['current_page'] = (int) $current_page;
            $array['more_page'] = $more_page;

            return $array;
        } catch (Exception $e) {
            return response()->json(['status' => 400, 'errors' => $e->getMessage()]);
        }
    }
}
