<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\OneSignalRequest;
use App\Models\Config;
use App\Models\Currency;
use App\Models\Language;
use App\Models\MovieLanguage;
use App\Models\Timezone;
use App\Repositories\Interfaces\Admin\SettingInterface;
use App\Traits\ImageTrait;
use App\Traits\OneSignalPushTrait;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use ReCaptcha\ReCaptcha;

class ConfigController extends Controller
{
    use ImageTrait;
    use OneSignalPushTrait;

    protected $setting;

    public function __construct(SettingInterface $setting)
    {
        $this->setting = $setting;
    }

    public function systemSettings()
    {
        $page_data['timezones'] = Timezone::get();
        $page_data['currencies'] = Currency::get();
        $page_data['system_languages'] = Language::where('status', 1)->get();

        return view('admin.settings.system_settings', $page_data);
    }

    public function adminSettings()
    {
        return view('admin.settings.admin_settings');
    }

    public function recaptchaSettings()
    {
        return view('admin.settings.recaptcha_settings');
    }

    public function tmdbSettings()
    {
        $page_data['movie_languages'] = MovieLanguage::get();

        return view('admin.settings.tmdb_settings', $page_data);
    }

    public function socialSettings()
    {
        return view('admin.settings.social_settings');
    }

    public function settingUpdate(Request $request, $type = null)
    {
        if (isDemoMode()) {
            return redirect()->back()->with('toastr_error', 'This action is disabled in demo mode.');
        }
        Session::put('tab_type', $type);

        if ($type === 'recaptcha') {
            $recaptchaBlock = $this->validateRecaptchaSettingsBeforeSave($request);
            if ($recaptchaBlock !== null) {
                return $recaptchaBlock;
            }
        }

        try {
            $timestamp = Carbon::now();
            foreach ($request->all() as $key => $value) {
                if ($key === '_token' || $key === 'g-recaptcha-response') {
                    continue;
                }
                if ($request->hasFile($key)) {
                    // Delete old image if exists
                    if (! blank(get_config($key))) {
                        $this->deleteImage(json_decode(get_config($key), true));
                    }
                    // Save the new image
                    $response = $this->saveImage($request->file($key), $key);
                    $value = json_encode($response['images']);
                }
                Config::updateOrCreate(
                    ['title' => $key],
                    [
                        'value' => $value,
                        'updated_at' => $timestamp,
                        'created_at' => Config::where('title', $key)->exists() ? Config::where('title', $key)->value('created_at') : $timestamp,
                    ]
                );
            }

            return redirect()->back()->with('toastr_success', __('setting_updated_successfully'));
        } catch (\Exception $e) {
            Log::error('Error updating settings: '.$e->getMessage());

            return redirect()->back()->with('toastr_error', __('setting_updated_failled'));
        }
    }

    public function smsGatewaySettings()
    {
        return view('admin.settings.sms_gateway');
    }

    public function systemStatus(Request $request)
    {
        if (isDemoMode()) {
            $data = [
                'status' => 'error',
                'message' => 'This action is disabled in demo mode.',
                'title' => __('error'),
                'is_reload' => false,
            ];

            return response()->json($data);
        }
        try {

            $data = $this->setting->systemStatus($request);

            return response()->json($data);
        } catch (\Exception $e) {
            $data = [
                'status' => 'error',
                'message' => __('setting_updated_failled'),
                'title' => __('error'),
                'is_reload' => true,
            ];

            return response()->json($data);
        }
    }

    public function oneSignal()
    {
        return view('admin.notification.one_signal');
    }

    public function oneSignalSend()
    {
        return view('admin.notification.one_signal_send');
    }

    public function oneSignalTest(OneSignalRequest $request)
    {
        if (isDemoMode()) {
            return redirect()->back()->with('toastr_error', 'This action is disabled in demo mode.');
        }
        if (! get_config('one_signal_status')) {
            return redirect()->back()->with('toastr_error', __('on_signal_disable_now'));
        }
        try {
            $response = $this->sendPush($request);
            if (isset($response['errors'])) {
                return redirect()->back()->with('toastr_error', __('message_send_failed'));
            } else {
                return redirect()->back()->with('toastr_success', __('message_send_successfully'));
            }
        } catch (\Exception $e) {
            return redirect()->back()->with('toastr_error', __('message_send_failed'));
        }
    }

    public function jobSetting()
    {
        return view('admin.settings.job_settings');
    }

    public function storageSetting()
    {
        Gate::authorize('storage.setting');

        return view('admin.settings.storage_setting');
    }

    public function saveStorageSetting(Request $request)
    {
        if (isDemoMode()) {
            return redirect()->back()->with('toastr_error', 'This action is disabled in demo mode.');
        }
        $request->validate([
            'aws_access_key_id' => 'required_if:default_storage,==,aws_s3',
            'aws_secret_access_key' => 'required_if:default_storage,==,aws_s3',
            'aws_default_region' => 'required_if:default_storage,==,aws_s3',
            'aws_bucket' => 'required_if:default_storage,==,aws_s3',
            'wasabi_access_key_id' => 'required_if:default_storage,==,wasabi',
            'wasabi_secret_access_key' => 'required_if:default_storage,==,wasabi',
            'wasabi_default_region' => 'required_if:default_storage,==,wasabi',
            'wasabi_bucket' => 'required_if:default_storage,==,wasabi',
            'image_optimization_percentage' => 'required_if:image_optimization,==,setting-status-change/image_optimization',
        ]);

        try {
            $this->setting->storageUpdate($request);

            return redirect()->back()->with('toastr_success', __('update_successfully'));
        } catch (\Exception $e) {
            return redirect()->back()->with('toastr_error', __('something_went_wrong_please_try_again!'));
        }
    }

    public function cron_key_run($key)
    {
        if ($key == get_config('cron_key')) {
            Artisan::call('queue:work', [
                '--tries' => 3,
                '--stop-when-empty' => true,
            ]);
        }
    }

    /**
     * Block saving invalid reCAPTCHA credentials. When enabling, requires a successful
     * widget verification (site + secret pair). When disabled, probes the secret with Google.
     */
    protected function validateRecaptchaSettingsBeforeSave(Request $request): ?\Illuminate\Http\RedirectResponse
    {
        $siteKey = trim((string) $request->input('recaptcha_site_key', ''));
        $secret = trim((string) $request->input('recaptcha_secret_key', ''));
        $enabled = (string) $request->input('is_recaptcha_activated') === '1';

        if ($enabled) {
            if ($siteKey === '' || $secret === '') {
                return redirect()->back()->withInput()->with('toastr_error', __('recaptcha_keys_required_to_enable'));
            }
            if (! $this->recaptchaSecretAcceptedByGoogle($secret)) {
                return redirect()->back()->withInput()->with('toastr_error', __('recaptcha_credentials_are_not_correct'));
            }
            $token = trim((string) $request->input('g-recaptcha-response', ''));
            if ($token === '') {
                return redirect()->back()->withInput()->with('toastr_error', __('recaptcha_complete_challenge_to_enable'));
            }
            $recaptcha = new ReCaptcha($secret);
            if (! $recaptcha->verify($token, $request->ip())->isSuccess()) {
                return redirect()->back()->withInput()->with('toastr_error', __('recaptcha_credentials_are_not_correct'));
            }

            return null;
        }

        if ($secret !== '' && ! $this->recaptchaSecretAcceptedByGoogle($secret)) {
            return redirect()->back()->withInput()->with('toastr_error', __('recaptcha_credentials_are_not_correct'));
        }

        return null;
    }

    /**
     * Ask Google whether the secret key is recognized (dummy response must not yield invalid-input-secret).
     */
    protected function recaptchaSecretAcceptedByGoogle(string $secret): bool
    {
        if ($secret === '') {
            return false;
        }
        try {
            $response = Http::asForm()->timeout(15)->post('https://www.google.com/recaptcha/api/siteverify', [
                'secret' => $secret,
                'response' => '__invalid_token_secret_probe__',
            ]);
            $json = $response->json();
            if (! is_array($json)) {
                return false;
            }
            if (($json['success'] ?? false) === true) {
                return true;
            }
            $codes = $json['error-codes'] ?? [];
            if (in_array('invalid-input-secret', $codes, true)) {
                return false;
            }

            return true;
        } catch (\Throwable $e) {
            Log::warning('reCAPTCHA secret probe failed', ['message' => $e->getMessage()]);

            return false;
        }
    }
}
