<?php

namespace App\Http\Controllers\Admin;

use App\Data\AmadastCities;
use App\Data\PaymentGateways;
use App\Http\Controllers\Controller;
use App\Models\AmadastCity;
use App\Models\ProductCategory;
use App\Models\Setting;
use App\Services\TorobPayService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\Rule;

class AdminSettingsController extends Controller
{
    private const AMADAST_AUTH_BASE    = 'https://api.amadast.com/api/v1.0';
    private const AMADAST_CITIES_URL   = 'https://shop-integration.amadast.com/v1/cities';
    private const AMADAST_CLIENT_ID    = 5;

    private const AUTH_KEYS = [
        'amadast_access_token',
        'amadast_refresh_token',
        'amadast_token_expires_at',
        'amadast_mobile',
        'amadast_user_name',
        'amadast_user_balance',
    ];

    // ── Pages ─────────────────────────────────────────────────────────────────

    public function main()
    {
        $faviconFile = Setting::get('site_favicon', '');

        $config = [
            'site_name'             => Setting::get('site_name', config('app.name', 'فروشگاه')),
            'site_home_title_desc'  => Setting::get('site_home_title_desc', ''),
            'favicon_file'          => $faviconFile,
            'favicon_url'           => $faviconFile
                ? asset('uploads/site/' . $faviconFile)
                : null,
            'maintenance_mode'      => in_array((string) Setting::get('maintenance_mode', '0'), ['1', 'true'], true),
        ];

        return view('admin.settings.main', compact('config'));
    }

    public function mainSave(Request $request)
    {
        $section = $request->input('_section', 'identity');

        if ($section === 'maintenance') {
            $enabled = $request->boolean('maintenance_mode');
            Setting::set('maintenance_mode', $enabled ? '1' : '0');

            return redirect()
                ->route('admin.settings.main', ['tab' => 'maintenance'])
                ->with('success', $enabled
                    ? 'حالت تعمیرات فعال شد. فروشگاه برای بازدیدکنندگان قفل است.'
                    : 'حالت تعمیرات غیرفعال شد.');
        }

        $request->validate([
            'site_name'            => 'required|string|max:120',
            'site_home_title_desc' => 'nullable|string|max:200',
            'favicon'              => 'nullable|file|mimes:ico,png,jpg,jpeg,gif,svg,webp|max:1024',
        ], [
            'site_name.required' => 'نام سایت الزامی است.',
            'site_name.max'      => 'نام سایت حداکثر ۱۲۰ کاراکتر باشد.',
            'favicon.mimes'      => 'فرمت مجاز فاوایکون: ICO، PNG، JPG، SVG، WebP.',
            'favicon.max'        => 'حداکثر حجم فاوایکون ۱ مگابایت است.',
        ]);

        Setting::set('site_name', trim($request->input('site_name')));
        Setting::set('site_home_title_desc', trim($request->input('site_home_title_desc', '')));

        if ($request->has('_remove_favicon')) {
            $old = Setting::get('site_favicon', '');
            if ($old && file_exists(public_path('uploads/site/' . $old))) {
                @unlink(public_path('uploads/site/' . $old));
            }
            Setting::set('site_favicon', '');
            return redirect()
                ->route('admin.settings.main', ['tab' => 'identity'])
                ->with('success', 'فاوایکون حذف شد.');
        }

        if ($request->hasFile('favicon')) {
            $dir = public_path('uploads/site');
            if (!is_dir($dir)) {
                mkdir($dir, 0755, true);
            }

            $old = Setting::get('site_favicon', '');
            if ($old && file_exists($dir . DIRECTORY_SEPARATOR . $old)) {
                @unlink($dir . DIRECTORY_SEPARATOR . $old);
            }

            $ext      = strtolower($request->file('favicon')->getClientOriginalExtension() ?: 'png');
            $filename = 'favicon-' . time() . '.' . $ext;
            $request->file('favicon')->move($dir, $filename);
            Setting::set('site_favicon', $filename);
        }

        return redirect()
            ->route('admin.settings.main', ['tab' => 'identity'])
            ->with('success', 'تنظیمات هویت ذخیره شد.');
    }

    public function torobApi()
    {
        $config = [
            'enabled'        => in_array((string) Setting::get('torob_api_enabled', '0'), ['1', 'true'], true),
            'audience'       => Setting::get('torob_api_audience', ''),
            'webhook_token'  => Setting::get('torob_webhook_token', ''),
            'endpoint'       => url('/torob_api/v3/products'),
            'webhook_url'    => \App\Services\TorobWebhookService::ENDPOINT,
            'docs_url'       => url('/docs/torob-api-v3.pdf'),
            'host_hint'      => request()->getHost() . (
                !in_array((int) request()->getPort(), [80, 443], true)
                    ? ':' . request()->getPort()
                    : ''
            ),
        ];

        return view('admin.settings.torob-api', compact('config'));
    }

    public function torobApiSave(Request $request)
    {
        $request->validate([
            'torob_api_audience'   => 'nullable|string|max:255',
            'torob_webhook_token'  => 'nullable|string|max:2000',
        ]);

        Setting::set('torob_api_enabled', $request->boolean('torob_api_enabled') ? '1' : '0');
        Setting::set('torob_api_audience', trim($request->input('torob_api_audience', '')));
        Setting::set('torob_webhook_token', trim($request->input('torob_webhook_token', '')));

        return back()->with('success', 'تنظیمات اتصال ترب ذخیره شد.');
    }

    public function paymentMethods()
    {
        $methods = PaymentGateways::orderedList();
        return view('admin.settings.payment-methods', compact('methods'));
    }

    public function paymentMethodsSave(Request $request)
    {
        $registry    = PaymentGateways::registry();
        $order       = (array) $request->input('order', []);
        $active      = (array) $request->input('active', []);
        $installment = (array) $request->input('installment_flag', []);

        $result = [];
        foreach ($order as $id) {
            if (!isset($registry[$id])) continue;
            $defaultInstallment = !empty($registry[$id]['is_installment']) ? 1 : 0;
            $result[] = [
                'id'              => $id,
                'checkout_active' => in_array($id, $active),
                'is_installment'  => isset($installment[$id]) ? ((int) $installment[$id] ? 1 : 0) : $defaultInstallment,
            ];
        }

        // Append any registry items not included in the submitted order
        $savedIds = array_column($result, 'id');
        foreach ($registry as $id => $gw) {
            if (!in_array($id, $savedIds)) {
                $result[] = [
                    'id'              => $id,
                    'checkout_active' => false,
                    'is_installment'  => !empty($gw['is_installment']) ? 1 : 0,
                ];
            }
        }

        Setting::set('checkout_payment_methods', json_encode($result));
        \Illuminate\Support\Facades\Cache::forget('biata_bot_installment_json');

        return back()->with('success', 'تنظیمات روش‌های پرداخت ذخیره شد.');
    }

    public function cardToCard()
    {
        $config = [
            'card_to_card_enabled'     => (bool) Setting::get('card_to_card_enabled', false),
            'card_to_card_number'      => Setting::get('card_to_card_number', ''),
            'card_to_card_account'     => Setting::get('card_to_card_account', ''),
            'card_to_card_holder_name' => Setting::get('card_to_card_holder_name', ''),
            'card_to_card_description' => Setting::get('card_to_card_description', ''),
        ];

        return view('admin.settings.card-to-card', compact('config'));
    }

    public function cardToCardSave(Request $request)
    {
        if ($request->boolean('_enable_only')) {
            Setting::set('card_to_card_enabled', $request->boolean('card_to_card_enabled') ? '1' : '0');
            return back()->with('success', 'وضعیت درگاه کارت به کارت ذخیره شد.');
        }

        $request->merge([
            'card_to_card_number' => preg_replace('/\D/', '', $request->input('card_to_card_number', '')),
        ]);

        $request->validate([
            'card_to_card_number'      => 'required|digits:16',
            'card_to_card_holder_name' => 'required|string|max:100',
            'card_to_card_account'     => 'nullable|string|max:30',
            'card_to_card_description' => 'nullable|string|max:500',
        ], [
            'card_to_card_number.required' => 'شماره کارت الزامی است.',
            'card_to_card_number.digits'   => 'شماره کارت باید ۱۶ رقم باشد.',
            'card_to_card_holder_name.required' => 'نام دارنده کارت الزامی است.',
        ]);

        Setting::setMany([
            'card_to_card_enabled'     => $request->boolean('card_to_card_enabled') ? '1' : '0',
            'card_to_card_number'      => $request->input('card_to_card_number', ''),
            'card_to_card_account'     => trim($request->input('card_to_card_account', '')),
            'card_to_card_holder_name' => trim($request->input('card_to_card_holder_name', '')),
            'card_to_card_description' => trim($request->input('card_to_card_description', '')),
        ]);

        return back()->with('success', 'تنظیمات کارت به کارت با موفقیت ذخیره شد.');
    }

    public function zibal()
    {
        $config = [
            'zibal_enabled'      => (bool) Setting::get('zibal_enabled', false),
            'zibal_merchant'     => Setting::get('zibal_merchant', ''),
            'zibal_test_mode'    => (bool) Setting::get('zibal_test_mode', false),
            'zibal_display_name' => Setting::get('zibal_display_name', ''),
            'zibal_icon'         => Setting::get('zibal_icon', ''),
        ];

        return view('admin.settings.zibal', compact('config'));
    }

    public function zibalSave(Request $request)
    {
        if ($request->boolean('_enable_only')) {
            Setting::set('zibal_enabled', $request->boolean('zibal_enabled') ? '1' : '0');
            return back()->with('success', 'وضعیت درگاه زیبال ذخیره شد.');
        }

        $isTestMode = $request->boolean('zibal_test_mode');

        $rules = [
            'zibal_icon' => 'nullable|image|mimes:jpeg,jpg,png,gif,svg,webp|max:1024',
        ];
        $messages = [
            'zibal_icon.image' => 'فایل آیکون باید تصویر باشد.',
            'zibal_icon.mimes' => 'فرمت آیکون مجاز نیست.',
            'zibal_icon.max'   => 'حجم آیکون حداکثر ۱ مگابایت باشد.',
        ];

        if (!$isTestMode) {
            $rules['zibal_merchant'] = 'required|string|min:5';
            $messages['zibal_merchant.required'] = 'کلید پذیرنده الزامی است.';
            $messages['zibal_merchant.min'] = 'کلید پذیرنده معتبر نیست.';
        }

        $request->validate($rules, $messages);

        // Note: zibal_enabled is managed exclusively by the separate enable toggle
        // (the "_enable_only" form above). We must not touch it here, otherwise
        // saving the config form would silently disable the gateway.
        Setting::setMany([
            'zibal_merchant'     => $isTestMode ? 'zibal' : trim($request->input('zibal_merchant', '')),
            'zibal_test_mode'    => $isTestMode ? '1' : '0',
            'zibal_display_name' => trim($request->input('zibal_display_name', '')),
        ]);

        $this->savePaymentGatewayIcon($request, 'zibal_icon', 'zibal');

        return back()->with('success', 'تنظیمات درگاه زیبال با موفقیت ذخیره شد.');
    }

    public function torobpay(TorobPayService $torobPay)
    {
        $config = [
            'torobpay_enabled'                 => (bool) Setting::get('torobpay_enabled', false),
            'torobpay_display_name'            => Setting::get('torobpay_display_name', 'پرداخت اقساطی ترب‌پی'),
            'torobpay_base_url'                => Setting::get('torobpay_base_url', 'https://cpg.torobpay.com/'),
            'torobpay_client_id'               => Setting::get('torobpay_client_id', ''),
            'torobpay_client_secret'           => Setting::get('torobpay_client_secret', ''),
            'torobpay_client_username'         => Setting::get('torobpay_client_username', ''),
            'torobpay_client_password'         => Setting::get('torobpay_client_password', ''),
            'torobpay_direct_payment'          => (bool) Setting::get('torobpay_direct_payment', true),
            'torobpay_disable_payment_retry'   => (bool) Setting::get('torobpay_disable_payment_retry', true),
            'torobpay_overselling_prevention'  => (bool) Setting::get('torobpay_overselling_prevention', false),
            'torobpay_utm_torob_enabled'       => (bool) Setting::get('torobpay_utm_torob_enabled', false),
            'torobpay_utm_exclude_others'      => (bool) Setting::get('torobpay_utm_exclude_others', false),
            'torobpay_success_message'         => Setting::get('torobpay_success_message', 'با تشکر از شما . سفارش شما با موفقیت پرداخت شد .'),
            'torobpay_failed_message'          => Setting::get('torobpay_failed_message', 'پرداخت شما ناموفق بوده است . لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید .'),
            'torobpay_cancelled_message'       => Setting::get('torobpay_cancelled_message', 'پرداخت به دلیل انصراف شما ناتمام باقی ماند .'),
            'torobpay_icon'                    => Setting::get('torobpay_icon', ''),
        ];

        $campaign = $this->buildTorobpayCampaignState($torobPay);

        return view('admin.settings.torobpay', compact('config', 'campaign'));
    }

    public function torobpaySave(Request $request)
    {
        if ($request->boolean('_enable_only')) {
            Setting::set('torobpay_enabled', $request->boolean('torobpay_enabled') ? '1' : '0');
            return back()->with('success', 'وضعیت درگاه ترب‌پی ذخیره شد.');
        }

        $request->validate([
            'torobpay_display_name'    => 'nullable|string|max:60',
            'torobpay_base_url'        => 'required|url|max:255',
            'torobpay_client_id'       => 'required|string|max:255',
            'torobpay_client_secret'   => 'required|string|max:255',
            'torobpay_client_username' => 'required|string|max:255',
            'torobpay_client_password' => 'required|string|max:255',
            'torobpay_success_message' => 'nullable|string|max:1000',
            'torobpay_failed_message'  => 'nullable|string|max:1000',
            'torobpay_cancelled_message' => 'nullable|string|max:1000',
            'torobpay_icon'            => 'nullable|image|mimes:jpeg,jpg,png,gif,svg,webp|max:1024',
        ], [
            'torobpay_base_url.required'        => 'آدرس درگاه الزامی است.',
            'torobpay_base_url.url'             => 'آدرس درگاه معتبر نیست.',
            'torobpay_client_id.required'       => 'شماره مشتری الزامی است.',
            'torobpay_client_secret.required'   => 'کد امنیتی مشتری الزامی است.',
            'torobpay_client_username.required' => 'نام کاربری مشتری الزامی است.',
            'torobpay_client_password.required' => 'رمز عبور مشتری الزامی است.',
            'torobpay_icon.image'               => 'فایل آیکون باید تصویر باشد.',
            'torobpay_icon.mimes'               => 'فرمت آیکون مجاز نیست.',
            'torobpay_icon.max'                 => 'حجم آیکون حداکثر ۱ مگابایت باشد.',
        ]);

        $baseUrl = rtrim(trim($request->input('torobpay_base_url', '')), '/') . '/';

        // Note: torobpay_enabled is managed exclusively by the separate enable toggle.
        Setting::setMany([
            'torobpay_display_name'           => trim($request->input('torobpay_display_name', '')),
            'torobpay_base_url'               => $baseUrl,
            'torobpay_client_id'              => trim($request->input('torobpay_client_id', '')),
            'torobpay_client_secret'          => trim($request->input('torobpay_client_secret', '')),
            'torobpay_client_username'        => trim($request->input('torobpay_client_username', '')),
            'torobpay_client_password'        => trim($request->input('torobpay_client_password', '')),
            'torobpay_direct_payment'         => $request->boolean('torobpay_direct_payment') ? '1' : '0',
            'torobpay_disable_payment_retry'  => $request->boolean('torobpay_disable_payment_retry') ? '1' : '0',
            'torobpay_overselling_prevention' => $request->boolean('torobpay_overselling_prevention') ? '1' : '0',
            'torobpay_utm_torob_enabled'      => $request->boolean('torobpay_utm_torob_enabled') ? '1' : '0',
            'torobpay_utm_exclude_others'     => $request->boolean('torobpay_utm_exclude_others') ? '1' : '0',
            'torobpay_success_message'        => trim($request->input('torobpay_success_message', '')),
            'torobpay_failed_message'         => trim($request->input('torobpay_failed_message', '')),
            'torobpay_cancelled_message'      => trim($request->input('torobpay_cancelled_message', '')),
        ]);

        $this->savePaymentGatewayIcon($request, 'torobpay_icon', 'torobpay');

        return back()->with('success', 'تنظیمات درگاه ترب‌پی با موفقیت ذخیره شد.');
    }

    public function digipay()
    {
        $config = [
            'digipay_enabled'                => in_array((string) Setting::get('digipay_enabled', '0'), ['1', 'true'], true),
            'digipay_display_name'           => Setting::get('digipay_display_name', 'پرداخت اقساطی دیجی‌پی'),
            'digipay_base_url'               => Setting::get('digipay_base_url', 'https://api.mydigipay.com/digipay/api'),
            'digipay_client_id'              => Setting::get('digipay_client_id', ''),
            'digipay_client_secret'          => Setting::get('digipay_client_secret', ''),
            'digipay_username'               => Setting::get('digipay_username', ''),
            'digipay_password'               => Setting::get('digipay_password', ''),
            'digipay_seller_id'              => Setting::get('digipay_seller_id', ''),
            'digipay_supplier_id'            => Setting::get('digipay_supplier_id', ''),
            'digipay_default_product_type'   => (int) Setting::get('digipay_default_product_type', 1),
            'digipay_overselling_prevention' => in_array((string) Setting::get('digipay_overselling_prevention', '0'), ['1', 'true'], true),
            'digipay_success_message'        => Setting::get('digipay_success_message', 'با تشکر از شما . سفارش شما با موفقیت پرداخت شد .'),
            'digipay_failed_message'         => Setting::get('digipay_failed_message', 'پرداخت شما ناموفق بوده است . لطفا مجددا تلاش نمایید یا در صورت بروز اشکال با مدیر سایت تماس بگیرید .'),
            'digipay_cancelled_message'      => Setting::get('digipay_cancelled_message', 'پرداخت به دلیل انصراف شما ناتمام باقی ماند .'),
            'digipay_icon'                   => Setting::get('digipay_icon', ''),
            'callback_url'                   => url('/checkout/callback/digipay'),
        ];

        return view('admin.settings.digipay', compact('config'));
    }

    public function digipaySave(Request $request)
    {
        if ($request->has('_enable_only')) {
            Setting::set('digipay_enabled', $request->boolean('digipay_enabled') ? '1' : '0');
            return back()->with('success', $request->boolean('digipay_enabled')
                ? 'درگاه دیجی‌پی فعال شد.'
                : 'درگاه دیجی‌پی غیرفعال شد.');
        }

        $request->validate([
            'digipay_display_name'         => 'nullable|string|max:60',
            'digipay_base_url'             => 'required|url|max:255',
            'digipay_client_id'            => 'required|string|max:255',
            'digipay_client_secret'        => 'required|string|max:255',
            'digipay_username'             => 'required|string|max:255',
            'digipay_password'             => 'required|string|max:255',
            'digipay_seller_id'            => 'required|string|max:255',
            'digipay_supplier_id'          => 'nullable|string|max:255',
            'digipay_default_product_type' => 'required|integer|in:1,2,3,4',
            'digipay_success_message'      => 'nullable|string|max:1000',
            'digipay_failed_message'       => 'nullable|string|max:1000',
            'digipay_cancelled_message'    => 'nullable|string|max:1000',
            'digipay_icon'                 => 'nullable|image|mimes:jpeg,jpg,png,gif,svg,webp|max:1024',
        ], [
            'digipay_base_url.required'      => 'آدرس درگاه الزامی است.',
            'digipay_client_id.required'     => 'Client ID الزامی است.',
            'digipay_client_secret.required' => 'Client Secret الزامی است.',
            'digipay_username.required'      => 'نام کاربری الزامی است.',
            'digipay_password.required'      => 'رمز عبور الزامی است.',
            'digipay_seller_id.required'     => 'شناسه فروشنده (sellerId) الزامی است.',
        ]);

        $baseUrl = rtrim(trim($request->input('digipay_base_url', '')), '/');

        Setting::setMany([
            'digipay_display_name'           => trim($request->input('digipay_display_name', '')),
            'digipay_base_url'               => $baseUrl,
            'digipay_client_id'              => trim($request->input('digipay_client_id', '')),
            'digipay_client_secret'          => trim($request->input('digipay_client_secret', '')),
            'digipay_username'               => trim($request->input('digipay_username', '')),
            'digipay_password'               => trim($request->input('digipay_password', '')),
            'digipay_seller_id'              => trim($request->input('digipay_seller_id', '')),
            'digipay_supplier_id'            => trim($request->input('digipay_supplier_id', '')),
            'digipay_default_product_type'   => (string) (int) $request->input('digipay_default_product_type', 1),
            'digipay_overselling_prevention' => $request->boolean('digipay_overselling_prevention') ? '1' : '0',
            'digipay_success_message'        => trim($request->input('digipay_success_message', '')),
            'digipay_failed_message'         => trim($request->input('digipay_failed_message', '')),
            'digipay_cancelled_message'      => trim($request->input('digipay_cancelled_message', '')),
        ]);

        $this->savePaymentGatewayIcon($request, 'digipay_icon', 'digipay');

        \Illuminate\Support\Facades\Cache::forget('digipay_oauth');

        return back()->with('success', 'تنظیمات درگاه دیجی‌پی با موفقیت ذخیره شد.');
    }

    /**
     * Upload / remove checkout icon for a payment gateway.
     */
    private function savePaymentGatewayIcon(Request $request, string $settingKey, string $prefix): void
    {
        $dir = public_path('uploads/payment-icons');
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        if ($request->boolean('remove_' . $settingKey)) {
            $old = Setting::get($settingKey, '');
            if ($old && file_exists($dir . DIRECTORY_SEPARATOR . $old)) {
                @unlink($dir . DIRECTORY_SEPARATOR . $old);
            }
            Setting::set($settingKey, '');
            return;
        }

        if (!$request->hasFile($settingKey)) {
            return;
        }

        $old = Setting::get($settingKey, '');
        if ($old && file_exists($dir . DIRECTORY_SEPARATOR . $old)) {
            @unlink($dir . DIRECTORY_SEPARATOR . $old);
        }

        $ext = strtolower($request->file($settingKey)->getClientOriginalExtension() ?: 'png');
        $filename = $prefix . '-icon-' . time() . '.' . $ext;
        $request->file($settingKey)->move($dir, $filename);
        Setting::set($settingKey, $filename);
    }

    public function torobpayCampaignSubmit(Request $request, TorobPayService $torobPay)
    {
        $request->validate([
            'torobpay_campaign_agree' => 'accepted',
        ], [
            'torobpay_campaign_agree.accepted' => 'پذیرش شرایط و ضوابط کمپین الزامی است.',
        ]);

        $campaign = $this->buildTorobpayCampaignState($torobPay);

        if (!$campaign['configured']) {
            return back()->with('error', 'ابتدا اطلاعات اتصال ترب‌پی را ذخیره کنید.');
        }

        if (!$campaign['can_submit']) {
            $msg = 'شما اخیراً اطلاعات ارسال کرده‌اید.';
            if ($campaign['days_remaining'] > 0) {
                $msg .= ' ' . $campaign['days_remaining'] . ' روز تا امکان ارسال مجدد باقی مانده است.';
            }
            return back()->with('error', $msg);
        }

        $result = $torobPay->exportAndUploadCampaignOrders();

        if (!($result['success'] ?? false)) {
            return back()->with('error', $result['error_message'] ?? 'خطا در ارسال اطلاعات سفارش‌ها.');
        }

        $now = time();
        Setting::set('torobpay_last_campaign_submission', (string) $now);

        if (!empty($result['campaign_id'])) {
            Setting::set('torobpay_pending_campaign_id', (string) $result['campaign_id']);
            Setting::set('torobpay_pending_campaign_start_time', (string) $now);
        }

        $submissions = json_decode(Setting::get('torobpay_campaign_submissions', '[]'), true) ?? [];
        $submissions[] = [
            'timestamp'    => $now,
            'campaign_id'  => $result['campaign_id'] ?? null,
            'description'  => 'Orders from ' . (Setting::get('site_title', config('app.name')) ?: 'BiatoShop') . ' - ' . date('Y-m-d H:i:s', $now),
        ];
        Setting::set('torobpay_campaign_submissions', json_encode(array_slice($submissions, -20)));

        return back()->with('success', 'اطلاعات سفارش‌های تکمیل‌شده با موفقیت به ترب‌پی ارسال شد.');
    }

    public function torobpayCampaignReset()
    {
        Setting::forget('torobpay_pending_campaign_id');
        Setting::forget('torobpay_pending_campaign_start_time');
        Setting::forget('torobpay_last_campaign_submission');
        Setting::forget('torobpay_campaign_submissions');

        return back()->with('success', 'وضعیت کمپین بازنشانی شد. اکنون می‌توانید مجدداً ارسال کنید.');
    }

    /**
     * @return array<string, mixed>
     */
    private function buildTorobpayCampaignState(TorobPayService $torobPay): array
    {
        $configured = $torobPay->isConfigured();
        $apiData    = $configured ? $torobPay->getCampaignResults() : ['success' => false, 'results' => []];
        $results    = $apiData['results'] ?? [];
        $latest     = $results[0] ?? null;

        $pendingId  = (int) Setting::get('torobpay_pending_campaign_id', 0);
        $pendingItem = null;
        if ($pendingId && !empty($results)) {
            foreach ($results as $row) {
                if ((int) ($row['id'] ?? 0) === $pendingId) {
                    $pendingItem = $row;
                    break;
                }
            }
        }

        $waitingForApi  = false;
        $waitingForFile = false;
        if ($pendingId) {
            if (!$pendingItem) {
                $waitingForApi = true;
            } elseif (empty($pendingItem['result_url'])) {
                $waitingForFile = true;
            } else {
                Setting::forget('torobpay_pending_campaign_id');
                Setting::forget('torobpay_pending_campaign_start_time');
                $pendingId = 0;
            }
        }

        $intervalSeconds = 30 * 24 * 60 * 60;
        $canSubmit       = true;
        $daysRemaining   = 0;
        $lastSubmission  = 0;

        if ($latest && !empty($latest['created_at'])) {
            $lastSubmission = strtotime($latest['created_at']) ?: 0;
            Setting::set('torobpay_last_campaign_submission', (string) $lastSubmission);
        } else {
            $lastSubmission = (int) Setting::get('torobpay_last_campaign_submission', 0);
        }

        if ($lastSubmission > 0) {
            $elapsed = time() - $lastSubmission;
            if ($elapsed < $intervalSeconds) {
                $canSubmit     = false;
                $daysRemaining = (int) ceil(($intervalSeconds - $elapsed) / 86400);
            }
        }

        $allocationReady = !$waitingForApi && !$waitingForFile && $latest && !empty($latest['result_url']);

        $showForceReset = false;
        if ($waitingForApi || $waitingForFile) {
            $pendingStart = (int) Setting::get('torobpay_pending_campaign_start_time', 0);
            if ($pendingStart === 0 && $pendingId > 0) {
                $pendingStart = time();
                Setting::set('torobpay_pending_campaign_start_time', (string) $pendingStart);
            }
            if ($pendingStart > 0 && (time() - $pendingStart) > (24 * 3600)) {
                $showForceReset = true;
            }
        } else {
            Setting::forget('torobpay_pending_campaign_start_time');
        }

        return [
            'configured'       => $configured,
            'api_error'        => $apiData['error'] ?? null,
            'results'          => $results,
            'latest'           => $latest,
            'can_submit'       => $canSubmit && !$waitingForApi && !$waitingForFile,
            'days_remaining'   => $daysRemaining,
            'last_submission'  => $lastSubmission,
            'waiting_for_api'  => $waitingForApi,
            'waiting_for_file' => $waitingForFile,
            'allocation_ready' => $allocationReady,
            'show_force_reset' => $showForceReset,
            'pending_id'       => $pendingId,
        ];
    }

    public function amadast()
    {
        $auth      = $this->getAuthStatus();
        $allCities = AmadastCities::allCitiesWithFullName();

        $config = [
            'amadast_enabled'         => (bool) Setting::get('amadast_enabled', false),
            'from_city_id'            => Setting::get('amadast_from_city_id', ''),
            'from_city_name'          => Setting::get('amadast_from_city_name', ''),
            'from_province'           => Setting::get('amadast_from_province', ''),
            'from_province_amadast_id'=> Setting::get('amadast_from_province_amadast_id', ''),
            'enabled_couriers'        => json_decode(Setting::get('amadast_enabled_couriers', '[13,4,18]'), true) ?? [13, 4, 18],
            'default_weight'          => Setting::get('amadast_default_weight', '500'),
            'default_pkg_type'        => Setting::get('amadast_default_pkg_type', '1'),
            'extra_cost'              => Setting::get('amadast_extra_cost', '0'),
            'extra_cost_percent'      => Setting::get('amadast_extra_cost_percent', '0'),
            'fallback_cost'           => Setting::get('amadast_fallback_cost', '0'),
            'peyk_price'              => Setting::get('amadast_peyk_price', '0'),
            'peyk_enabled'            => Setting::get('amadast_peyk_enabled', '0'),
            'amadast_store_id'              => Setting::get('amadast_store_id', ''),
            'amadast_store_name'            => Setting::get('amadast_store_name', ''),
            'amadast_sender_name'           => Setting::get('amadast_sender_name', ''),
            'amadast_sender_mobile'         => Setting::get('amadast_sender_mobile', ''),
        ];

        return view('admin.settings.amadast', compact('auth', 'config', 'allCities'));
    }

    public function amadastSave(Request $request)
    {
        if ($request->boolean('_enable_only')) {
            Setting::set('amadast_enabled', $request->boolean('amadast_enabled') ? '1' : '0');
            return back()->with('success', 'وضعیت سرویس آمادست ذخیره شد.');
        }

        $request->validate([
            'from_city_id'       => 'required|integer|min:1',
            'from_city_name'     => 'required|string|max:100',
            'from_province'      => 'required|string|max:100',
            'default_weight'     => 'required|integer|min:10',
            'default_pkg_type'   => 'required|integer|between:1,14',
            'extra_cost'         => 'required|integer|min:0',
            'extra_cost_percent' => 'required|numeric|min:0|max:100',
            'fallback_cost'      => 'required|integer|min:0',
            'peyk_price'         => 'required|integer|min:0',
            'amadast_sender_name'             => 'nullable|string|max:100',
            'amadast_sender_mobile'           => ['nullable', 'regex:/^09[0-9]{9}$/'],
        ], [
            'from_city_id.required'                => 'شناسه شهر مبدأ الزامی است.',
            'from_city_id.integer'                 => 'شناسه شهر مبدأ باید عدد باشد.',
            'default_weight.min'                   => 'وزن پیش‌فرض حداقل ۱۰ گرم است.',
            'extra_cost_percent.max'               => 'درصد اضافه نمی‌تواند بیشتر از ۱۰۰ باشد.',
            'amadast_sender_mobile.regex'          => 'موبایل فرستنده معتبر نیست (فرمت: 09xxxxxxxxx).',
            'amadast_default_product_type_id.required' => 'شناسه نوع مرسوله پیش‌فرض الزامی است.',
        ]);

        $couriers = array_values(array_filter(
            array_map('intval', (array) $request->input('couriers', [])),
            fn (int $id) => \App\Data\AmadastCouriers::isValid($id)
        ));

        Setting::setMany([
            'amadast_from_city_id'            => $request->from_city_id,
            'amadast_from_city_name'          => $request->from_city_name,
            'amadast_from_province'           => $request->from_province,
            'amadast_from_province_amadast_id'=> $request->input('from_province_amadast_id', ''),
            'amadast_enabled_couriers'        => json_encode($couriers),
            'amadast_default_weight'     => $request->default_weight,
            'amadast_default_pkg_type'   => $request->default_pkg_type,
            'amadast_extra_cost'         => $request->extra_cost,
            'amadast_extra_cost_percent' => $request->extra_cost_percent,
            'amadast_fallback_cost'      => $request->fallback_cost,
            'amadast_peyk_price'         => $request->peyk_price,
            'amadast_peyk_enabled'       => $request->boolean('peyk_enabled') ? '1' : '0',
            'amadast_sender_name'                 => trim($request->input('amadast_sender_name', '')),
            'amadast_sender_mobile'               => trim($request->input('amadast_sender_mobile', '')),
        ]);

        return back()->with('success', 'تنظیمات ارسال با موفقیت ذخیره شد.');
    }

    // ── AJAX: OTP Request ─────────────────────────────────────────────────────

    public function amadastOtpRequest(Request $request)
    {
        $request->validate([
            'mobile' => ['required', 'regex:/^09[0-9]{9}$/'],
        ], [
            'mobile.required' => 'شماره موبایل الزامی است.',
            'mobile.regex'    => 'شماره موبایل معتبر نیست (فرمت: 09xxxxxxxxx).',
        ]);

        try {
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'Accept'       => 'application/json',
                'User-Agent'   => 'Amadast-WP-Plugin/3.1.1',
            ])->timeout(30)->post(self::AMADAST_AUTH_BASE . '/otp-request', [
                'mobile' => $request->mobile,
            ]);

            $body = $response->json();

            if ($response->failed() || !($body['result'] ?? false)) {
                $msg = is_array($body['message'] ?? null)
                    ? implode(' ', $body['message'])
                    : ($body['message'] ?? 'خطا در ارسال کد تأیید.');
                return response()->json(['success' => false, 'message' => $msg], 422);
            }

            session(['amadast_otp_mobile' => $request->mobile]);

            return response()->json(['success' => true, 'message' => 'کد تأیید ارسال شد.']);

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'خطا در اتصال به سرور آمادست: ' . $e->getMessage()], 500);
        }
    }

    // ── AJAX: OTP Verify ─────────────────────────────────────────────────────

    public function amadastOtpVerify(Request $request)
    {
        $request->validate([
            'code' => 'required|digits:5',
        ], [
            'code.required' => 'کد تأیید الزامی است.',
            'code.digits'   => 'کد تأیید باید ۵ رقم باشد.',
        ]);

        $mobile = session('amadast_otp_mobile');

        if (!$mobile) {
            return response()->json(['success' => false, 'message' => 'جلسه منقضی شده. دوباره کد ارسال کنید.'], 422);
        }

        try {
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'Accept'       => 'application/json',
                'User-Agent'   => 'Amadast-WP-Plugin/3.1.1',
            ])->timeout(30)->post(self::AMADAST_AUTH_BASE . '/otp-verify', [
                'client_id' => self::AMADAST_CLIENT_ID,
                'mobile'    => $mobile,
                'code'      => $request->code,
                'meta_data' => [
                    'source' => config('app.url'),
                    'action' => 'Login Into Plugin.',
                ],
            ]);

            $body = $response->json();

            if ($response->failed() || !($body['result'] ?? false)) {
                $msg = is_array($body['message'] ?? null)
                    ? implode(' ', $body['message'])
                    : ($body['message'] ?? 'کد وارد شده اشتباه است.');
                return response()->json(['success' => false, 'message' => $msg], 422);
            }

            $data = $body['data'] ?? [];
            $user = $data['user'] ?? [];

            Setting::setMany([
                'amadast_access_token'    => $data['access_token'] ?? '',
                'amadast_refresh_token'   => $data['refresh_token'] ?? '',
                'amadast_token_expires_at'=> now()->addSeconds((int)($data['expires_in'] ?? 3600))->timestamp,
                'amadast_mobile'          => $mobile,
                'amadast_user_name'       => $user['name'] ?? '',
                'amadast_user_balance'    => $user['financial']['balance'] ?? 0,
            ]);

            session()->forget('amadast_otp_mobile');

            return response()->json([
                'success' => true,
                'user'    => [
                    'mobile'  => $mobile,
                    'name'    => $user['name'] ?? '',
                    'balance' => number_format((float)($user['financial']['balance'] ?? 0)),
                ],
            ]);

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'خطا در اتصال به سرور آمادست: ' . $e->getMessage()], 500);
        }
    }

    // ── AJAX: Logout ─────────────────────────────────────────────────────────

    public function amadastLogout()
    {
        foreach (self::AUTH_KEYS as $key) {
            Setting::forget($key);
        }
        session()->forget('amadast_otp_mobile');

        return response()->json(['success' => true]);
    }

    // ── AJAX: Resend OTP ─────────────────────────────────────────────────────

    public function amadastOtpResend(Request $request)
    {
        $mobile = session('amadast_otp_mobile');

        if (!$mobile) {
            return response()->json(['success' => false, 'message' => 'جلسه منقضی شده. شماره موبایل را دوباره وارد کنید.'], 422);
        }

        try {
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'Accept'       => 'application/json',
                'User-Agent'   => 'Amadast-WP-Plugin/3.1.1',
            ])->timeout(30)->post(self::AMADAST_AUTH_BASE . '/otp-request', [
                'mobile' => $mobile,
            ]);

            $body = $response->json();

            if ($response->failed() || !($body['result'] ?? false)) {
                $msg = is_array($body['message'] ?? null)
                    ? implode(' ', $body['message'])
                    : ($body['message'] ?? 'خطا در ارسال مجدد کد.');
                return response()->json(['success' => false, 'message' => $msg], 422);
            }

            return response()->json(['success' => true]);

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'خطا در اتصال: ' . $e->getMessage()], 500);
        }
    }

    // ── AJAX: Sync Cities ────────────────────────────────────────────────────

    public function syncCities()
    {
        $token = Setting::get('amadast_access_token');

        $headers = [
            'Accept'       => 'application/json',
            'X-Client-Code'=> (string) self::AMADAST_CLIENT_ID,
        ];

        if ($token) {
            $headers['Authorization'] = 'Bearer ' . $token;
        }

        try {
            $response = Http::withHeaders($headers)->timeout(30)->get(self::AMADAST_CITIES_URL);

            if ($response->failed()) {
                return response()->json([
                    'success' => false,
                    'message' => 'خطا در دریافت لیست شهرها (HTTP ' . $response->status() . ').',
                ], 422);
            }

            $body  = $response->json();
            $items = $body['data'] ?? (is_array($body) ? $body : []);

            if (empty($items)) {
                return response()->json(['success' => false, 'message' => 'داده‌ای از سرور آمادست دریافت نشد.'], 422);
            }

            $provinces = array_filter($items, fn($i) => is_null($i['parent'] ?? null));
            $cities    = array_filter($items, fn($i) => !is_null($i['parent'] ?? null));

            AmadastCity::truncate();

            $provRows = array_map(fn($p) => [
                'id'         => (int) $p['id'],
                'title'      => $p['title'],
                'parent_id'  => null,
                'created_at' => now(),
                'updated_at' => now(),
            ], array_values($provinces));

            $cityRows = array_map(fn($c) => [
                'id'         => (int) $c['id'],
                'title'      => $c['title'],
                'parent_id'  => (int) $c['parent'],
                'created_at' => now(),
                'updated_at' => now(),
            ], array_values($cities));

            foreach (array_chunk($provRows, 500) as $chunk) {
                AmadastCity::insert($chunk);
            }
            foreach (array_chunk($cityRows, 500) as $chunk) {
                AmadastCity::insert($chunk);
            }

            $pc = count($provRows);
            $cc = count($cityRows);

            Setting::set('amadast_cities_synced_at', now()->timestamp);

            return response()->json([
                'success'       => true,
                'province_count'=> $pc,
                'city_count'    => $cc,
                'message'       => "سینک موفق: {$pc} استان و {$cc} شهر دریافت و ذخیره شد.",
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'خطا در اتصال به سرور آمادست: ' . $e->getMessage(),
            ], 500);
        }
    }

    // ── AJAX: Amadast API proxy — Provinces ──────────────────────────────────

    public function apiProvinces()
    {
        try {
            $response = Http::withoutVerifying()
                ->withHeaders([
                    'Accept'        => 'application/json',
                    'X-Client-Code' => (string) self::AMADAST_CLIENT_ID,
                ])->timeout(30)->get(self::AMADAST_CITIES_URL);

            $items     = $response->json('data') ?? [];
            $provinces = array_values(array_filter($items, fn($i) => is_null($i['parent'] ?? null)));
            usort($provinces, fn($a, $b) => strcmp($a['title'], $b['title']));

            return response()->json(['success' => true, 'data' => $provinces]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── AJAX: Amadast API proxy — Cities by province ──────────────────────────

    public function apiCities(int $provinceId)
    {
        try {
            $response = Http::withoutVerifying()
                ->withHeaders([
                    'Accept'        => 'application/json',
                    'X-Client-Code' => (string) self::AMADAST_CLIENT_ID,
                ])->timeout(30)->get(self::AMADAST_CITIES_URL, ['province_id' => $provinceId]);

            $items  = $response->json('data') ?? [];
            $cities = array_values(array_filter($items, fn($i) => !is_null($i['parent'] ?? null)));

            return response()->json(['success' => true, 'data' => $cities]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    // ── AJAX: Province Cities ────────────────────────────────────────────────

    public function getProvinceCities(int $provinceId)
    {
        $cities = AmadastCity::where('parent_id', $provinceId)
            ->orderBy('title')
            ->get(['id', 'title']);

        return response()->json(['success' => true, 'cities' => $cities]);
    }

    // ── AJAX: City Search (Select2) ──────────────────────────────────────────

    public function searchCities(Request $request)
    {
        $q          = trim($request->input('q', ''));
        $provinceId = (int) $request->input('province_id', 0);

        $query = AmadastCity::whereNotNull('parent_id')->orderBy('title');

        if ($provinceId) {
            $query->where('parent_id', $provinceId);
        }

        if ($q !== '') {
            $query->where('title', 'like', '%' . $q . '%');
        }

        $cities = $query->limit(100)->get(['id', 'title', 'parent_id']);

        $results = $cities->map(fn($c) => [
            'id'          => $c->id,
            'text'        => $c->title,
            'province_id' => $c->parent_id,
        ]);

        return response()->json(['results' => $results]);
    }

    // ── AJAX: Amadast Stores ─────────────────────────────────────────────────

    public function apiStores()
    {
        $token     = Setting::get('amadast_access_token');
        $expiresAt = (int) Setting::get('amadast_token_expires_at', 0);

        if (!$token || $expiresAt <= now()->timestamp) {
            return response()->json(['success' => false, 'message' => 'ابتدا وارد حساب آمادست شوید.'], 401);
        }

        try {
            $response = Http::withHeaders([
                'Accept'        => 'application/json',
                'X-Client-Code' => (string) self::AMADAST_CLIENT_ID,
                'Authorization' => 'Bearer ' . $token,
            ])->timeout(15)->get('https://shop-integration.amadast.com/v1/stores');

            if ($response->failed()) {
                return response()->json([
                    'success' => false,
                    'message' => 'خطا در دریافت فروشگاه‌ها (HTTP ' . $response->status() . ').',
                ], 422);
            }

            $body   = $response->json();
            $stores = $body['data'] ?? (is_array($body) ? $body : []);

            return response()->json(['success' => true, 'stores' => $stores]);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'خطا: ' . $e->getMessage()], 500);
        }
    }

    // ── AJAX: Save Store ──────────────────────────────────────────────────────

    public function saveStore(Request $request)
    {
        $request->validate([
            'store_id'   => 'required|integer|min:1',
            'store_name' => 'nullable|string|max:255',
        ], [
            'store_id.required' => 'فروشگاه را انتخاب کنید.',
        ]);

        Setting::setMany([
            'amadast_store_id'   => $request->store_id,
            'amadast_store_name' => $request->store_name ?? '',
        ]);

        return response()->json(['success' => true, 'message' => 'فروشگاه با موفقیت ذخیره شد.']);
    }

    // ── AJAX: Amadast Product Types ──────────────────────────────────────────

    public function getProductTypes()
    {
        $token     = Setting::get('amadast_access_token');
        $expiresAt = (int) Setting::get('amadast_token_expires_at', 0);

        if (!$token || $expiresAt <= now()->timestamp) {
            return response()->json(['success' => false, 'message' => 'ابتدا وارد حساب آمادست شوید.'], 401);
        }

        try {
            $response = Http::withHeaders([
                'Accept'        => 'application/json',
                'X-Client-Code' => (string) self::AMADAST_CLIENT_ID,
                'Authorization' => 'Bearer ' . $token,
            ])->timeout(15)->get('https://shop-integration.amadast.com/v1/product-types', [
                'per_page' => 100,
            ]);

            if ($response->failed()) {
                return response()->json([
                    'success' => false,
                    'message' => 'خطا در دریافت انواع مرسوله (HTTP ' . $response->status() . ').',
                ], 422);
            }

            $body  = $response->json();
            $types = $body['data'] ?? (is_array($body) ? $body : []);

            return response()->json(['success' => true, 'types' => $types]);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'خطا: ' . $e->getMessage()], 500);
        }
    }

    // ── Appearance ────────────────────────────────────────────────────────────

    public function appearance()
    {
        $logoFile   = Setting::get('site_logo', '');
        $currentLogo = $logoFile
            ? asset('uploads/site/' . $logoFile)
            : asset('theme/assets/image/logo.png');

        $features = [];
        for ($i = 1; $i <= 4; $i++) {
            $features[] = [
                'icon'     => Setting::get("feature_box_{$i}_icon", ''),
                'title'    => Setting::get("feature_box_{$i}_title", ''),
                'subtitle' => Setting::get("feature_box_{$i}_subtitle", ''),
            ];
        }

        $savedCatIds = array_slice(array_values(array_filter(array_map('intval',
            explode(',', Setting::get('homepage_category_ids', ''))
        ))), 0, 4);

        $slider = [];
        for ($i = 1; $i <= 5; $i++) {
            $slider[$i] = [
                'image' => Setting::get("slider_{$i}_image", ''),
                'link'  => Setting::get("slider_{$i}_link", ''),
            ];
        }

        $banners = [];
        for ($i = 1; $i <= 4; $i++) {
            $banners[$i] = [
                'image' => Setting::get("banner_{$i}_image", ''),
                'link'  => Setting::get("banner_{$i}_link", ''),
            ];
        }

        $footer = [
            'about'            => Setting::get('footer_about', ''),
            'social_instagram' => Setting::get('footer_social_instagram', ''),
            'social_telegram'  => Setting::get('footer_social_telegram', ''),
            'social_whatsapp'  => Setting::get('footer_social_whatsapp', ''),
            'social_youtube'   => Setting::get('footer_social_youtube', ''),
            'social_twitter'   => Setting::get('footer_social_twitter', ''),
            'enamad_code'      => Setting::get('footer_enamad_code', ''),
            'samandehi_code'   => Setting::get('footer_samandehi_code', ''),
            'quick_links'      => json_decode(Setting::get('footer_quick_links', ''), true) ?: [],
            'services'         => json_decode(Setting::get('footer_services', ''), true) ?: [],
            'copyright'        => Setting::get('footer_copyright', ''),
            'terms_link'       => Setting::get('footer_terms_link', ''),
            'privacy_link'     => Setting::get('footer_privacy_link', ''),
        ];

        $categoryTree = ProductCategory::flatTree();

        $config = [
            'current_logo'          => $currentLogo,
            'has_custom_logo'       => (bool) $logoFile,
            'header_phone_text'     => Setting::get('header_phone_text', ''),
            'header_phone_link'     => Setting::get('header_phone_link', ''),
            'header_nav_links'      => json_decode(Setting::get('header_nav_links', ''), true) ?: [],
            'features'              => $features,
            'homepage_category_ids' => $savedCatIds,
            'slider'                => $slider,
            'banners'               => $banners,
            'footer'                => $footer,
        ];

        return view('admin.settings.appearance', compact('config', 'categoryTree'));
    }

    public function appearanceSave(Request $request)
    {
        $section = $request->input('_section');

        if ($section === 'logo') {
            if ($request->has('_reset_logo')) {
                $old = Setting::get('site_logo', '');
                if ($old && file_exists(public_path('uploads/site/' . $old))) {
                    @unlink(public_path('uploads/site/' . $old));
                }
                Setting::set('site_logo', '');
                return back()->with('success', 'لوگو به حالت پیش‌فرض بازگشت.');
            }

            $request->validate([
                'logo' => 'required|image|mimes:jpeg,jpg,png,gif,svg,webp|max:2048',
            ], [
                'logo.required' => 'لطفاً یک تصویر انتخاب کنید.',
                'logo.image'    => 'فایل انتخابی باید تصویر باشد.',
                'logo.mimes'    => 'فرمت مجاز: PNG، JPG، GIF، SVG، WebP.',
                'logo.max'      => 'حداکثر حجم فایل ۲ مگابایت است.',
            ]);

            $old = Setting::get('site_logo', '');
            if ($old && file_exists(public_path('uploads/site/' . $old))) {
                @unlink(public_path('uploads/site/' . $old));
            }

            $ext      = $request->file('logo')->getClientOriginalExtension();
            $filename = 'site-logo-' . time() . '.' . $ext;
            $request->file('logo')->move(public_path('uploads/site'), $filename);

            Setting::set('site_logo', $filename);
            return back()->with('success', 'لوگوی سایت با موفقیت آپلود شد.');
        }

        if ($section === 'phone') {
            $request->validate([
                'header_phone_text' => 'nullable|string|max:50',
                'header_phone_link' => 'nullable|string|max:200',
            ]);

            Setting::setMany([
                'header_phone_text' => trim($request->input('header_phone_text', '')),
                'header_phone_link' => trim($request->input('header_phone_link', '')),
            ]);
            return back()->with('success', 'اطلاعات دکمه تلفن ذخیره شد.');
        }

        if ($section === 'features') {
            $icons     = (array) $request->input('feature_icon', []);
            $titles    = (array) $request->input('feature_title', []);
            $subtitles = (array) $request->input('feature_subtitle', []);
            $data = [];
            for ($i = 1; $i <= 4; $i++) {
                $idx = $i - 1;
                $data["feature_box_{$i}_icon"]     = strip_tags(trim($icons[$idx] ?? ''));
                $data["feature_box_{$i}_title"]    = strip_tags(trim($titles[$idx] ?? ''));
                $data["feature_box_{$i}_subtitle"] = strip_tags(trim($subtitles[$idx] ?? ''));
            }
            $data['feature_box_5_icon']     = '';
            $data['feature_box_5_title']    = '';
            $data['feature_box_5_subtitle'] = '';
            Setting::setMany($data);
            return back()->with('success', 'باکس‌های ویژگی ذخیره شدند.');
        }

        if ($section === 'homepage_categories') {
            $ids = array_filter(array_map('intval', (array) $request->input('homepage_category_ids', [])));
            $ids = array_slice(array_values($ids), 0, 4);
            Setting::set('homepage_category_ids', implode(',', $ids));
            return back()->with('success', 'دسته‌بندی‌های صفحه اصلی ذخیره شدند.');
        }

        if ($section === 'header_nav') {
            $titles = (array) $request->input('nav_title', []);
            $urls   = (array) $request->input('nav_url', []);
            $icons  = (array) $request->input('nav_icon', []);
            $items  = [];
            foreach ($titles as $idx => $title) {
                $title = strip_tags(trim($title));
                if ($title) {
                    $items[] = [
                        'title' => $title,
                        'url'   => trim($urls[$idx] ?? ''),
                        'icon'  => preg_replace('/[^a-z0-9\-]/', '', strtolower($icons[$idx] ?? '')),
                    ];
                }
            }
            Setting::set('header_nav_links', json_encode($items, JSON_UNESCAPED_UNICODE));
            return back()->with('success', 'منوی هدر ذخیره شد.');
        }

        if ($section === 'footer') {
            $titles = (array) $request->input('quick_link_title', []);
            $urls   = (array) $request->input('quick_link_url', []);
            $quickLinks = [];
            foreach ($titles as $idx => $title) {
                $title = strip_tags(trim($title));
                $url   = trim($urls[$idx] ?? '');
                if ($title) {
                    $quickLinks[] = ['title' => $title, 'url' => $url];
                }
            }

            $sTitles  = (array) $request->input('service_title', []);
            $sUrls    = (array) $request->input('service_url', []);
            $services = [];
            foreach ($sTitles as $idx => $title) {
                $title = strip_tags(trim($title));
                $url   = trim($sUrls[$idx] ?? '');
                if ($title) {
                    $services[] = ['title' => $title, 'url' => $url];
                }
            }

            Setting::setMany([
                'footer_about'            => trim($request->input('footer_about', '')),
                'footer_social_instagram' => trim($request->input('footer_social_instagram', '')),
                'footer_social_telegram'  => trim($request->input('footer_social_telegram', '')),
                'footer_social_whatsapp'  => trim($request->input('footer_social_whatsapp', '')),
                'footer_social_youtube'   => trim($request->input('footer_social_youtube', '')),
                'footer_social_twitter'   => trim($request->input('footer_social_twitter', '')),
                'footer_enamad_code'      => $request->input('footer_enamad_code', ''),
                'footer_samandehi_code'   => $request->input('footer_samandehi_code', ''),
                'footer_quick_links'      => json_encode($quickLinks, JSON_UNESCAPED_UNICODE),
                'footer_services'         => json_encode($services, JSON_UNESCAPED_UNICODE),
                'footer_copyright'        => trim($request->input('footer_copyright', '')),
                'footer_terms_link'       => trim($request->input('footer_terms_link', '')),
                'footer_privacy_link'     => trim($request->input('footer_privacy_link', '')),
            ]);
            return back()->with('success', 'تنظیمات فوتر ذخیره شدند.');
        }

        if ($section === 'slider') {
            if (!is_dir(public_path('uploads/slider'))) {
                mkdir(public_path('uploads/slider'), 0755, true);
            }
            for ($i = 1; $i <= 5; $i++) {
                if ($request->boolean("slider_remove_{$i}")) {
                    $old = Setting::get("slider_{$i}_image", '');
                    if ($old && file_exists(public_path('uploads/slider/' . $old))) {
                        @unlink(public_path('uploads/slider/' . $old));
                    }
                    Setting::set("slider_{$i}_image", '');
                } elseif ($request->hasFile("slider_image_{$i}")) {
                    $request->validate([
                        "slider_image_{$i}" => 'image|mimes:jpeg,jpg,png,gif,webp|max:3072',
                    ]);
                    $old = Setting::get("slider_{$i}_image", '');
                    if ($old && file_exists(public_path('uploads/slider/' . $old))) {
                        @unlink(public_path('uploads/slider/' . $old));
                    }
                    $ext      = $request->file("slider_image_{$i}")->getClientOriginalExtension();
                    $filename = "slide-{$i}-" . time() . '.' . $ext;
                    $request->file("slider_image_{$i}")->move(public_path('uploads/slider'), $filename);
                    Setting::set("slider_{$i}_image", $filename);
                }
                Setting::set("slider_{$i}_link", trim($request->input("slider_link_{$i}", '')));
            }
            return back()->with('success', 'تنظیمات اسلایدر ذخیره شدند.');
        }

        if ($section === 'banners') {
            if (!is_dir(public_path('uploads/banners'))) {
                mkdir(public_path('uploads/banners'), 0755, true);
            }
            for ($i = 1; $i <= 4; $i++) {
                if ($request->boolean("banner_remove_{$i}")) {
                    $old = Setting::get("banner_{$i}_image", '');
                    if ($old && file_exists(public_path('uploads/banners/' . $old))) {
                        @unlink(public_path('uploads/banners/' . $old));
                    }
                    Setting::set("banner_{$i}_image", '');
                } elseif ($request->hasFile("banner_image_{$i}")) {
                    $request->validate([
                        "banner_image_{$i}" => 'image|mimes:jpeg,jpg,png,gif,webp|max:3072',
                    ]);
                    $old = Setting::get("banner_{$i}_image", '');
                    if ($old && file_exists(public_path('uploads/banners/' . $old))) {
                        @unlink(public_path('uploads/banners/' . $old));
                    }
                    $ext      = $request->file("banner_image_{$i}")->getClientOriginalExtension();
                    $filename = "banner-{$i}-" . time() . '.' . $ext;
                    $request->file("banner_image_{$i}")->move(public_path('uploads/banners'), $filename);
                    Setting::set("banner_{$i}_image", $filename);
                }
                Setting::set("banner_{$i}_link", trim($request->input("banner_link_{$i}", '')));
            }
            return back()->with('success', 'تنظیمات بنرهای صفحه اصلی ذخیره شدند.');
        }

        return back();
    }

    // ── SMS Sending Templates ─────────────────────────────────────────────────

    public function smsSending()
    {
        $providers   = [];
        if (Setting::get('sms_enabled')) {
            $providers['payammatni'] = 'پیام متنی';
        }

        $config = [
            'sms_provider'                 => Setting::get('sms_provider', 'payammatni'),
            'sms_otp_text'                 => Setting::get('sms_otp_text', 'کد تأیید شما: {code}'),
            'sms_new_order_user_enabled'   => (bool) Setting::get('sms_new_order_user_enabled', false),
            'sms_new_order_user_text'      => Setting::get('sms_new_order_user_text', ''),
            'sms_new_order_admin_enabled'  => (bool) Setting::get('sms_new_order_admin_enabled', false),
            'sms_new_order_admin_text'     => Setting::get('sms_new_order_admin_text', ''),
            'sms_admin_mobile'             => Setting::get('sms_admin_mobile', ''),
            'sms_order_sent_user_enabled'  => (bool) Setting::get('sms_order_sent_user_enabled', false),
            'sms_order_sent_user_text'     => Setting::get('sms_order_sent_user_text', ''),
        ];

        $smsActive = !empty($providers);

        return view('admin.settings.sms-sending', compact('config', 'providers', 'smsActive'));
    }

    public function smsSendingSave(Request $request)
    {
        $request->validate([
            'sms_otp_text'                => 'required|string|max:500',
            'sms_new_order_user_text'     => 'nullable|string|max:500',
            'sms_new_order_admin_text'    => 'nullable|string|max:500',
            'sms_admin_mobile'            => 'nullable|string|max:500',
            'sms_order_sent_user_text'    => 'nullable|string|max:500',
        ], [
            'sms_otp_text.required'       => 'متن پیامک OTP الزامی است.',
        ]);

        $rawAdminMobiles = trim($request->input('sms_admin_mobile', ''));
        if ($rawAdminMobiles !== '') {
            foreach (array_map('trim', explode(',', $rawAdminMobiles)) as $num) {
                if ($num !== '' && !preg_match('/^09[0-9]{9}$/', $num)) {
                    return back()->withErrors(['sms_admin_mobile' => "شماره «{$num}» معتبر نیست (فرمت: 09xxxxxxxxx)."])->withInput();
                }
            }
        }

        Setting::setMany([
            'sms_provider'                 => $request->input('sms_provider', 'payammatni'),
            'sms_otp_text'                 => trim($request->sms_otp_text),
            'sms_new_order_user_enabled'   => $request->boolean('sms_new_order_user_enabled') ? '1' : '0',
            'sms_new_order_user_text'      => trim($request->input('sms_new_order_user_text', '')),
            'sms_new_order_admin_enabled'  => $request->boolean('sms_new_order_admin_enabled') ? '1' : '0',
            'sms_new_order_admin_text'     => trim($request->input('sms_new_order_admin_text', '')),
            'sms_admin_mobile'             => trim($request->input('sms_admin_mobile', '')),
            'sms_order_sent_user_enabled'  => $request->boolean('sms_order_sent_user_enabled') ? '1' : '0',
            'sms_order_sent_user_text'     => trim($request->input('sms_order_sent_user_text', '')),
        ]);

        return back()->with('success', 'تنظیمات ارسال پیامک با موفقیت ذخیره شد.');
    }

    // ── SMS (PayamMatni) ──────────────────────────────────────────────────────

    public function sms()
    {
        $config = [
            'sms_enabled'     => (bool) Setting::get('sms_enabled', false),
            'sms_username'    => Setting::get('sms_username', ''),
            'sms_password'    => Setting::get('sms_password', ''),
            'sms_from_number' => Setting::get('sms_from_number', ''),
        ];

        return view('admin.settings.sms', compact('config'));
    }

    public function smsSave(Request $request)
    {
        if ($request->boolean('_enable_only')) {
            Setting::set('sms_enabled', $request->boolean('sms_enabled') ? '1' : '0');
            return back()->with('success', 'وضعیت سرویس پیام متنی ذخیره شد.');
        }

        $request->validate([
            'sms_username'    => 'required|string|max:100',
            'sms_password'    => 'required|string|max:100',
            'sms_from_number' => 'required|string|max:20',
        ], [
            'sms_username.required'    => 'نام کاربری الزامی است.',
            'sms_password.required'    => 'رمز عبور الزامی است.',
            'sms_from_number.required' => 'شماره فرستنده الزامی است.',
        ]);

        Setting::setMany([
            'sms_username'    => $request->sms_username,
            'sms_password'    => $request->sms_password,
            'sms_from_number' => $request->sms_from_number,
        ]);

        return back()->with('success', 'تنظیمات پیام متنی ذخیره شد.');
    }

    public function smsCredit()
    {
        $credit = \App\Services\PayamMatni::getCredit();

        if ($credit === null) {
            return response()->json(['success' => false, 'message' => 'خطا در دریافت اعتبار. اطمینان حاصل کنید نام کاربری و رمز عبور تنظیم شده باشند.']);
        }

        return response()->json(['success' => true, 'credit' => $credit]);
    }

    // ── About Page ───────────────────────────────────────────────────────────

    public function aboutPage()
    {
        $config = [
            'about_page_title'       => Setting::get('about_page_title', ''),
            'about_intro'            => Setting::get('about_intro', ''),
            'about_body'             => Setting::get('about_body', ''),
            'about_mission'          => Setting::get('about_mission', ''),
            'about_vision'           => Setting::get('about_vision', ''),
            'about_stat_1_number'    => Setting::get('about_stat_1_number', ''),
            'about_stat_1_label'     => Setting::get('about_stat_1_label', ''),
            'about_stat_2_number'    => Setting::get('about_stat_2_number', ''),
            'about_stat_2_label'     => Setting::get('about_stat_2_label', ''),
            'about_stat_3_number'    => Setting::get('about_stat_3_number', ''),
            'about_stat_3_label'     => Setting::get('about_stat_3_label', ''),
            'about_stat_4_number'    => Setting::get('about_stat_4_number', ''),
            'about_stat_4_label'     => Setting::get('about_stat_4_label', ''),
            'about_seo_title'        => Setting::get('about_seo_title', ''),
            'about_seo_description'  => Setting::get('about_seo_description', ''),
            'about_seo_keywords'     => Setting::get('about_seo_keywords', ''),
            'about_seo_schema'       => Setting::get('about_seo_schema', ''),
        ];

        return view('admin.settings.about-page', compact('config'));
    }

    public function aboutPageSave(Request $request)
    {
        $request->validate([
            'about_page_title'      => 'nullable|string|max:255',
            'about_intro'           => 'nullable|string|max:1000',
            'about_body'            => 'nullable|string|max:10000',
            'about_mission'         => 'nullable|string|max:2000',
            'about_vision'          => 'nullable|string|max:2000',
            'about_stat_1_number'   => 'nullable|string|max:50',
            'about_stat_1_label'    => 'nullable|string|max:100',
            'about_stat_2_number'   => 'nullable|string|max:50',
            'about_stat_2_label'    => 'nullable|string|max:100',
            'about_stat_3_number'   => 'nullable|string|max:50',
            'about_stat_3_label'    => 'nullable|string|max:100',
            'about_stat_4_number'   => 'nullable|string|max:50',
            'about_stat_4_label'    => 'nullable|string|max:100',
            'about_seo_title'       => 'nullable|string|max:255',
            'about_seo_description' => 'nullable|string|max:500',
            'about_seo_keywords'    => 'nullable|string|max:500',
            'about_seo_schema'      => 'nullable|string|max:5000',
        ]);

        Setting::setMany([
            'about_page_title'      => trim($request->input('about_page_title', '')),
            'about_intro'           => trim($request->input('about_intro', '')),
            'about_body'            => trim($request->input('about_body', '')),
            'about_mission'         => trim($request->input('about_mission', '')),
            'about_vision'          => trim($request->input('about_vision', '')),
            'about_stat_1_number'   => trim($request->input('about_stat_1_number', '')),
            'about_stat_1_label'    => trim($request->input('about_stat_1_label', '')),
            'about_stat_2_number'   => trim($request->input('about_stat_2_number', '')),
            'about_stat_2_label'    => trim($request->input('about_stat_2_label', '')),
            'about_stat_3_number'   => trim($request->input('about_stat_3_number', '')),
            'about_stat_3_label'    => trim($request->input('about_stat_3_label', '')),
            'about_stat_4_number'   => trim($request->input('about_stat_4_number', '')),
            'about_stat_4_label'    => trim($request->input('about_stat_4_label', '')),
            'about_seo_title'       => trim($request->input('about_seo_title', '')),
            'about_seo_description' => trim($request->input('about_seo_description', '')),
            'about_seo_keywords'    => trim($request->input('about_seo_keywords', '')),
            'about_seo_schema'      => trim($request->input('about_seo_schema', '')),
        ]);

        return back()->with('success', 'تنظیمات صفحه درباره ما با موفقیت ذخیره شد.');
    }

    // ── Terms Page ───────────────────────────────────────────────────────────

    public function termsPage()
    {
        $config = [
            'terms_page_title'      => Setting::get('terms_page_title', 'قوانین و مقررات'),
            'terms_body'            => Setting::get('terms_body', ''),
            'terms_seo_title'       => Setting::get('terms_seo_title', ''),
            'terms_seo_description' => Setting::get('terms_seo_description', ''),
            'terms_seo_keywords'    => Setting::get('terms_seo_keywords', ''),
            'terms_seo_schema'      => Setting::get('terms_seo_schema', ''),
        ];

        return view('admin.settings.terms-page', compact('config'));
    }

    public function termsPageSave(Request $request)
    {
        $request->validate([
            'terms_page_title'      => 'nullable|string|max:255',
            'terms_body'            => 'nullable|string|max:100000',
            'terms_seo_title'       => 'nullable|string|max:255',
            'terms_seo_description' => 'nullable|string|max:500',
            'terms_seo_keywords'    => 'nullable|string|max:500',
            'terms_seo_schema'      => 'nullable|string|max:5000',
        ]);

        Setting::setMany([
            'terms_page_title'      => trim($request->input('terms_page_title', '')),
            'terms_body'            => (string) $request->input('terms_body', ''),
            'terms_seo_title'       => trim($request->input('terms_seo_title', '')),
            'terms_seo_description' => trim($request->input('terms_seo_description', '')),
            'terms_seo_keywords'    => trim($request->input('terms_seo_keywords', '')),
            'terms_seo_schema'      => trim($request->input('terms_seo_schema', '')),
        ]);

        return back()->with('success', 'تنظیمات صفحه قوانین و مقررات با موفقیت ذخیره شد.');
    }

    public function termsPageMediaUpload(Request $request)
    {
        $request->validate([
            'file' => 'required|image|mimes:jpeg,jpg,png,gif,webp|max:2048',
        ]);

        $dir = public_path('uploads/terms/content');
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        $filename = 'terms-' . time() . '-' . uniqid() . '.' . $request->file('file')->getClientOriginalExtension();
        $request->file('file')->move($dir, $filename);

        return response()->json([
            'location' => url('uploads/terms/content/' . $filename),
        ]);
    }

    // ── SEO ──────────────────────────────────────────────────────────────────

    public function seo()
    {
        $ogFile = Setting::get('seo_og_image', '');

        $config = [
            'seo_default_description'   => Setting::get('seo_default_description', ''),
            'seo_default_keywords'      => Setting::get('seo_default_keywords', ''),
            'seo_robots_default'        => Setting::get('seo_robots_default', 'index,follow'),
            'seo_force_noindex'         => (bool) Setting::get('seo_force_noindex', false),
            'seo_auto_canonical'        => (bool) Setting::get('seo_auto_canonical', true),
            'seo_google_verification'   => Setting::get('seo_google_verification', ''),
            'seo_bing_verification'     => Setting::get('seo_bing_verification', ''),
            'seo_yandex_verification'   => Setting::get('seo_yandex_verification', ''),
            'seo_ga4_id'                => Setting::get('seo_ga4_id', ''),
            'seo_gtm_id'                => Setting::get('seo_gtm_id', ''),
            'seo_og_image'              => $ogFile,
            'seo_og_image_url'          => $ogFile ? asset('uploads/seo/' . $ogFile) : null,
            'seo_twitter_site'          => Setting::get('seo_twitter_site', ''),
            'seo_facebook_app_id'       => Setting::get('seo_facebook_app_id', ''),
            'seo_organization_name'     => Setting::get('seo_organization_name', Setting::get('site_name', '')),
            'seo_organization_same_as'  => Setting::get('seo_organization_same_as', ''),
            'seo_organization_schema'   => Setting::get('seo_organization_schema', ''),
            'seo_head_scripts'          => Setting::get('seo_head_scripts', ''),
            'seo_body_scripts'          => Setting::get('seo_body_scripts', ''),
        ];

        return view('admin.settings.seo', compact('config'));
    }

    public function seoSave(Request $request)
    {
        $section = $request->input('_section', 'general');

        if ($section === 'general') {
            $request->validate([
                'seo_default_description' => 'nullable|string|max:500',
                'seo_default_keywords'    => 'nullable|string|max:500',
                'seo_robots_default'      => ['required', Rule::in(['index,follow', 'index,nofollow', 'noindex,follow', 'noindex,nofollow'])],
            ]);

            Setting::setMany([
                'seo_default_description' => trim($request->input('seo_default_description', '')),
                'seo_default_keywords'    => trim($request->input('seo_default_keywords', '')),
                'seo_robots_default'      => $request->input('seo_robots_default', 'index,follow'),
                'seo_force_noindex'       => $request->boolean('seo_force_noindex') ? '1' : '0',
                'seo_auto_canonical'      => $request->boolean('seo_auto_canonical') ? '1' : '0',
            ]);

            return back()->with('success', 'تنظیمات عمومی سئو ذخیره شد.')->with('settings_seo_tab', 'general');
        }

        if ($section === 'verification') {
            $request->validate([
                'seo_google_verification' => 'nullable|string|max:120',
                'seo_bing_verification'   => 'nullable|string|max:120',
                'seo_yandex_verification' => 'nullable|string|max:120',
            ]);

            Setting::setMany([
                'seo_google_verification' => trim($request->input('seo_google_verification', '')),
                'seo_bing_verification'   => trim($request->input('seo_bing_verification', '')),
                'seo_yandex_verification' => trim($request->input('seo_yandex_verification', '')),
            ]);

            return back()->with('success', 'کدهای تأیید موتورهای جستجو ذخیره شد.')->with('settings_seo_tab', 'verification');
        }

        if ($section === 'analytics') {
            $request->validate([
                'seo_ga4_id' => ['nullable', 'string', 'max:40', 'regex:/^(G-[A-Z0-9]+)?$/i'],
                'seo_gtm_id' => ['nullable', 'string', 'max:40', 'regex:/^(GTM-[A-Z0-9]+)?$/i'],
            ], [
                'seo_ga4_id.regex' => 'شناسه GA4 باید شبیه G-XXXXXXXX باشد.',
                'seo_gtm_id.regex' => 'شناسه GTM باید شبیه GTM-XXXXXXX باشد.',
            ]);

            Setting::setMany([
                'seo_ga4_id' => strtoupper(trim($request->input('seo_ga4_id', ''))),
                'seo_gtm_id' => strtoupper(trim($request->input('seo_gtm_id', ''))),
            ]);

            return back()->with('success', 'تنظیمات آنالیتیکس ذخیره شد.')->with('settings_seo_tab', 'analytics');
        }

        if ($section === 'social') {
            $request->validate([
                'seo_twitter_site'    => 'nullable|string|max:60',
                'seo_facebook_app_id' => 'nullable|string|max:40',
                'seo_og_image'        => 'nullable|image|mimes:jpeg,jpg,png,gif,webp|max:2048',
            ], [
                'seo_og_image.image' => 'فایل تصویر معتبر نیست.',
                'seo_og_image.max'   => 'حجم تصویر حداکثر ۲ مگابایت باشد.',
            ]);

            $twitter = trim($request->input('seo_twitter_site', ''));
            if ($twitter !== '' && !str_starts_with($twitter, '@')) {
                $twitter = '@' . ltrim($twitter, '@');
            }

            Setting::setMany([
                'seo_twitter_site'    => $twitter,
                'seo_facebook_app_id' => trim($request->input('seo_facebook_app_id', '')),
            ]);

            if ($request->boolean('_remove_og_image')) {
                $this->deleteSeoOgImage();
                Setting::set('seo_og_image', '');
            } elseif ($request->hasFile('seo_og_image')) {
                $this->deleteSeoOgImage();
                $file = $request->file('seo_og_image');
                $dir  = public_path('uploads/seo');
                if (!is_dir($dir)) {
                    mkdir($dir, 0755, true);
                }
                $name = 'og-' . time() . '.' . $file->getClientOriginalExtension();
                $file->move($dir, $name);
                Setting::set('seo_og_image', $name);
            }

            return back()->with('success', 'تنظیمات شبکه‌های اجتماعی ذخیره شد.')->with('settings_seo_tab', 'social');
        }

        if ($section === 'organization') {
            $request->validate([
                'seo_organization_name'    => 'nullable|string|max:120',
                'seo_organization_same_as' => 'nullable|string|max:2000',
                'seo_organization_schema'  => 'nullable|string|max:8000',
            ]);

            Setting::setMany([
                'seo_organization_name'    => trim($request->input('seo_organization_name', '')),
                'seo_organization_same_as' => trim($request->input('seo_organization_same_as', '')),
                'seo_organization_schema'  => trim($request->input('seo_organization_schema', '')),
            ]);

            return back()->with('success', 'اسکیمای سازمان ذخیره شد.')->with('settings_seo_tab', 'organization');
        }

        if ($section === 'scripts') {
            $request->validate([
                'seo_head_scripts' => 'nullable|string|max:20000',
                'seo_body_scripts' => 'nullable|string|max:20000',
            ]);

            Setting::setMany([
                'seo_head_scripts' => trim($request->input('seo_head_scripts', '')),
                'seo_body_scripts' => trim($request->input('seo_body_scripts', '')),
            ]);

            return back()->with('success', 'کدهای سفارشی ذخیره شد.')->with('settings_seo_tab', 'scripts');
        }

        return back()->withErrors(['_section' => 'بخش نامعتبر است.']);
    }

    private function deleteSeoOgImage(): void
    {
        $current = Setting::get('seo_og_image', '');
        if ($current === '') {
            return;
        }
        $path = public_path('uploads/seo/' . $current);
        if (is_file($path)) {
            @unlink($path);
        }
    }

    // ── Contact Page ─────────────────────────────────────────────────────────

    public function contactPage()
    {
        $config = [
            'contact_phones'          => Setting::get('contact_phones', ''),
            'contact_email'           => Setting::get('contact_email', ''),
            'contact_address'         => Setting::get('contact_address', ''),
            'contact_working_hours'   => Setting::get('contact_working_hours', ''),
            'contact_map_embed'       => Setting::get('contact_map_embed', ''),
            'contact_seo_title'       => Setting::get('contact_seo_title', ''),
            'contact_seo_description' => Setting::get('contact_seo_description', ''),
            'contact_seo_keywords'    => Setting::get('contact_seo_keywords', ''),
            'contact_seo_schema'      => Setting::get('contact_seo_schema', ''),
        ];

        return view('admin.settings.contact-page', compact('config'));
    }

    public function contactPageSave(Request $request)
    {
        $request->validate([
            'contact_email'           => 'nullable|email|max:255',
            'contact_phones'          => 'nullable|string|max:1000',
            'contact_address'         => 'nullable|string|max:500',
            'contact_working_hours'   => 'nullable|string|max:200',
            'contact_map_embed'       => 'nullable|string|max:2000',
            'contact_seo_title'       => 'nullable|string|max:255',
            'contact_seo_description' => 'nullable|string|max:500',
            'contact_seo_keywords'    => 'nullable|string|max:500',
            'contact_seo_schema'      => 'nullable|string|max:5000',
        ], [
            'contact_email.email' => 'فرمت ایمیل معتبر نیست.',
        ]);

        Setting::setMany([
            'contact_phones'          => trim($request->input('contact_phones', '')),
            'contact_email'           => trim($request->input('contact_email', '')),
            'contact_address'         => trim($request->input('contact_address', '')),
            'contact_working_hours'   => trim($request->input('contact_working_hours', '')),
            'contact_map_embed'       => trim($request->input('contact_map_embed', '')),
            'contact_seo_title'       => trim($request->input('contact_seo_title', '')),
            'contact_seo_description' => trim($request->input('contact_seo_description', '')),
            'contact_seo_keywords'    => trim($request->input('contact_seo_keywords', '')),
            'contact_seo_schema'      => trim($request->input('contact_seo_schema', '')),
        ]);

        \Illuminate\Support\Facades\Cache::forget('biata_bot_contact_json');

        return back()->with('success', 'تنظیمات صفحه تماس با ما با موفقیت ذخیره شد.');
    }

    // ── AI Models (GapGPT) ──────────────────────────────────────────────────

    public function aiModels()
    {
        $gapgpt = new \App\Services\GapGptService();
        $modelsResult = $gapgpt->listModels();

        $config = [
            'api_key' => \App\Services\GapGptService::apiKey(),
            'model'   => \App\Services\GapGptService::model(),
        ];

        return view('admin.settings.ai-models', [
            'config'       => $config,
            'models'       => $modelsResult['models'] ?? [],
            'modelsError'  => $modelsResult['success'] ? null : ($modelsResult['message'] ?? 'خطا در دریافت مدل‌ها'),
            'modelsCount'  => count($modelsResult['models'] ?? []),
        ]);
    }

    public function aiModelsSave(Request $request)
    {
        $request->validate([
            'api_key' => 'required|string|min:10|max:500',
            'model'   => 'required|string|max:150',
        ], [
            'api_key.required' => 'توکن GapGPT الزامی است.',
            'api_key.min'      => 'توکن GapGPT معتبر نیست.',
            'model.required'   => 'انتخاب مدل پیش‌فرض الزامی است.',
        ]);

        Setting::setMany([
            'gapgpt_api_key' => trim($request->input('api_key')),
            'gapgpt_model'   => trim($request->input('model')),
        ]);

        return back()->with('success', 'تنظیمات مدل‌های هوش مصنوعی ذخیره شد.');
    }

    public function aiModelsCredit()
    {
        $billing = (new \App\Services\GapGptService())->getBilling();

        if (!($billing['success'] ?? false)) {
            return response()->json([
                'success' => false,
                'message' => $billing['message'] ?? 'خطا در دریافت اعتبار.',
            ]);
        }

        return response()->json([
            'success'            => true,
            'remaining_usd'      => $billing['remaining_usd'],
            'used_usd'           => $billing['used_usd'],
            'hard_limit_usd'     => $billing['hard_limit_usd'],
            'soft_limit_usd'     => $billing['soft_limit_usd'],
            'has_payment_method' => $billing['has_payment_method'],
        ]);
    }

    // ── Content Generation (AI Blog) ────────────────────────────────────────

    public function contentGeneration()
    {
        \App\Services\AiBlogGenerator::applyRecommendedDefaultsIfNeeded();

        $modelsResult = (new \App\Services\GapGptService())->listModels();
        $config = \App\Services\AiBlogGenerator::settings();

        return view('admin.settings.content-generation', [
            'config'      => $config,
            'models'      => $modelsResult['models'] ?? [],
            'modelsError' => $modelsResult['success'] ? null : ($modelsResult['message'] ?? 'خطا در دریافت مدل‌ها'),
            'apiCategoriesUrl' => url('/api/categories'),
            'apiProductsUrl'   => url('/api/products'),
        ]);
    }

    public function contentGenerationSave(Request $request)
    {
        if ($request->boolean('_apply_recommended')) {
            Setting::setMany(\App\Services\AiBlogGenerator::recommendedDefaults());
            Setting::set('content_generation_seo_defaults_v4', '1');
            return back()->with('success', 'مقادیر پیشنهادی پایپلاین چندایجنتی اعمال شد.');
        }

        $request->validate([
            'model'              => 'required|string|max:150',
            'temperature'        => 'required|numeric|min:0|max:2',
            'max_tokens'         => 'required|integer|min:2000|max:100000',
            'language'           => 'required|string|max:50',
            'audience'           => 'required|string|max:255',
            'audience_level'     => 'required|in:beginner,intermediate,professional',
            'image_count'        => 'required|integer|min:2|max:12',
            'min_words'          => 'required|integer|min:100|max:10000',
            'max_words'          => 'required|integer|min:100|max:20000|gte:min_words',
            'seo_title_min'      => 'required|integer|min:10|max:120',
            'seo_title_max'      => 'required|integer|min:10|max:120|gte:seo_title_min',
            'seo_desc_min'       => 'required|integer|min:40|max:320',
            'seo_desc_max'       => 'required|integer|min:40|max:320|gte:seo_desc_min',
            'products_limit'     => 'required|integer|min:10|max:150',
            'extra_instructions' => 'nullable|string|max:5000',
        ], [
            'model.required' => 'انتخاب مدل الزامی است.',
            'max_words.gte'  => 'حداکثر کلمات نباید کمتر از حداقل کلمات باشد.',
        ]);

        Setting::setMany([
            'content_generation_model'              => trim($request->input('model')),
            'content_generation_temperature'        => (string) $request->input('temperature'),
            'content_generation_max_tokens'         => (string) ((int) $request->input('max_tokens')),
            'content_generation_language'           => trim($request->input('language')),
            'content_generation_audience'           => trim($request->input('audience')),
            'content_generation_audience_level'     => $request->input('audience_level'),
            'content_generation_image_count'        => (string) ((int) $request->input('image_count')),
            'content_generation_min_words'          => (string) ((int) $request->input('min_words')),
            'content_generation_max_words'          => (string) ((int) $request->input('max_words')),
            'content_generation_seo_title_min'      => (string) ((int) $request->input('seo_title_min')),
            'content_generation_seo_title_max'      => (string) ((int) $request->input('seo_title_max')),
            'content_generation_seo_desc_min'       => (string) ((int) $request->input('seo_desc_min')),
            'content_generation_seo_desc_max'       => (string) ((int) $request->input('seo_desc_max')),
            'content_generation_include_catalog'    => $request->boolean('include_catalog') ? '1' : '0',
            'content_generation_products_limit'     => (string) ((int) $request->input('products_limit')),
            'content_generation_extra_instructions' => trim((string) $request->input('extra_instructions', '')),
            'content_generation_seo_defaults_v4'    => '1',
        ]);

        return back()->with('success', 'تنظیمات تولید محتوا ذخیره شد.');
    }

    // ── Biata Bot ───────────────────────────────────────────────────────────

    public function biataBot()
    {
        $modelsResult = (new \App\Services\GapGptService())->listModels();

        $config = [
            'enabled'            => (bool) Setting::get('biata_bot_enabled', false),
            'name'               => Setting::get('biata_bot_name', 'بیاتو بات'),
            'welcome'            => Setting::get('biata_bot_welcome', 'سلام! 😊 من بیاتو بات هستم. چه چیزی می‌تونم کمکت کنم؟'),
            'model'              => \App\Services\GapGptService::biataBotModel(),
            'include_categories' => (bool) Setting::get('biata_bot_include_categories', true),
            'include_products'   => (bool) Setting::get('biata_bot_include_products', true),
            'products_limit'     => (int) Setting::get('biata_bot_products_limit', 30),
            'system_prompt'      => Setting::get('biata_bot_system_prompt', $this->defaultBiataPrompt()),
        ];

        return view('admin.settings.biata-bot', [
            'config'      => $config,
            'models'      => $modelsResult['models'] ?? [],
            'modelsError' => $modelsResult['success'] ? null : ($modelsResult['message'] ?? 'خطا در دریافت مدل‌ها'),
        ]);
    }

    public function biataBotSave(Request $request)
    {
        $request->validate([
            'name'           => 'required|string|max:60',
            'welcome'        => 'required|string|max:500',
            'model'          => 'required|string|max:150',
            'products_limit' => 'required|integer|min:0|max:100',
            'system_prompt'  => 'required|string|min:20',
        ], [
            'name.required'           => 'نام بات الزامی است.',
            'welcome.required'        => 'پیام خوش‌آمد الزامی است.',
            'model.required'          => 'انتخاب مدل الزامی است.',
            'products_limit.required' => 'حداکثر تعداد محصولات الزامی است.',
            'products_limit.max'      => 'حداکثر تعداد محصولات نمی‌تواند بیشتر از ۱۰۰ باشد.',
            'system_prompt.required'  => 'پرامت سیستمی الزامی است.',
            'system_prompt.min'       => 'پرامت سیستمی خیلی کوتاه است.',
        ]);

        Setting::setMany([
            'biata_bot_enabled'            => $request->boolean('enabled') ? '1' : '0',
            'biata_bot_name'               => $request->input('name'),
            'biata_bot_welcome'            => $request->input('welcome'),
            'biata_bot_model'              => trim($request->input('model')),
            'biata_bot_include_categories' => $request->boolean('include_categories') ? '1' : '0',
            'biata_bot_include_products'   => $request->boolean('include_products') ? '1' : '0',
            'biata_bot_products_limit'     => (int) $request->input('products_limit'),
            'biata_bot_system_prompt'      => $request->input('system_prompt'),
        ]);

        // Bust cached catalog snippets so changes (or fresh data) reach the bot immediately.
        \Illuminate\Support\Facades\Cache::forget('biata_bot_categories_json');
        \Illuminate\Support\Facades\Cache::forget('biata_bot_products_json_' . (int) $request->input('products_limit'));

        return back()->with('success', 'تنظیمات بیاتو بات ذخیره شد.');
    }

    private function defaultBiataPrompt(): string
    {
        return <<<TXT
تو "بیاتا" هستی — دستیار هوشمند و صمیمی فروشگاه اینترنتی بیاتو شاپ.

## هویت تو
- اسمت بیاتاست، یه دستیار خرید باهوش و خوش‌برخورد
- لحنت صمیمی، گرم، و دوستانه‌ست — مثل یه دوست که توی خرید کمک می‌کنه
- از کلمات ساده و روزمره استفاده می‌کنی، نه جملات خشک و رسمی
- همیشه با انرژی مثبت و حوصله جواب می‌دی
- فقط به زبان فارسی جواب می‌دی مگر اینکه مشتری به زبان دیگه‌ای بنویسه

## درباره بیاتو شاپ
بیاتو شاپ یه فروشگاه اینترنتی متنوعه که طیف گسترده‌ای از محصولات رو ارائه می‌ده:
- 📱 الکترونیک و موبایل (گوشی، لپ‌تاپ، لوازم جانبی و ...)
- 🏠 لوازم خانگی (آشپزخانه، دکوراسیون، ابزار و ...)
- 💄 آرایشی و بهداشتی (اسکین‌کر، آرایش، مراقبت و ...)
- 🍎 غذا و خوراکی (محصولات ارگانیک، خشکبار، نوشیدنی و ...)
- و دسته‌بندی‌های بیشتری که مرتب در حال اضافه شدن هستن

## وظایف اصلی تو
1. **راهنمایی خرید**: کمک به انتخاب محصول مناسب بر اساس نیاز و بودجه مشتری
2. **پیشنهاد محصول**: اگه مشتری نمی‌دونه چی بخره، باهاش صحبت کن و بهترین گزینه رو پیشنهاد بده
3. **پاسخ به سوالات**: درباره محصولات، ارسال، گارانتی، و سیاست‌های فروشگاه
4. **ثبت شکایت**: اگه مشتری مشکلی داشت، با احترام بشنو و راهنماییش کن

## سیاست‌های فروشگاه
- ✅ ارسال به سراسر ایران
- ✅ ضمانت اصالت کالا
- ✅ امکان مرجوعی تا ۷ روز پس از دریافت (در صورت نداشتن عیب)
- ✅ پشتیبانی از طریق چت، تلفن، و ایمیل
- ⏰ ساعت پشتیبانی انسانی: ۹ صبح تا ۶ عصر — روزهای کاری

## قوانین مهم
- ❌ هیچ‌وقت قیمت دقیق ندی مگر اینکه اطلاعات به‌روز داشته باشی — بگو "برای قیمت دقیق به صفحه محصول مراجعه کن"
- ❌ اطلاعاتی که مطمئن نیستی رو نگو — بگو "نمی‌دونم، بذار با پشتیبانی چک کنم"
- ❌ اگه سوال خارج از حوزه فروشگاه بود بگو: "این خارج از تخصص منه ولی برای خرید هر چیزی که نیاز داری خوشحال می‌شم کمک کنم! 😊"
- ✅ همیشه با لحن گرم و صمیمی جواب بده
- ✅ از ایموجی‌های مناسب استفاده کن تا مکالمه جذاب‌تر بشه
- ✅ اگه مشتری ناراحت یا شاکی بود، اول همدلی نشون بده بعد راه‌حل بده

## نمونه لحن صحیح
❌ اشتباه: "چه کمکی از دست اینجانب برمی‌آید؟"
✅ درست: "سلام! خوش اومدی 😊 چه چیزی می‌تونم کمکت کنم؟"

❌ اشتباه: "متأسفانه از قیمت این محصول اطلاع ندارم."
✅ درست: "برای قیمت دقیق بهتره یه سر به صفحه محصول بزنی تا آخرین قیمت رو ببینی! 🛍️"
TXT;
    }

    public function clubWheel()
    {
        $prizes = \App\Services\CustomerClubService::wheelPrizes();

        return view('admin.settings.club-wheel', [
            'prizes' => collect($prizes)->map(fn ($p) => [
                'amount'  => (int) $p['amount'],
                'percent' => (float) $p['percent'],
                'color'   => $p['color'],
            ])->values()->all(),
        ]);
    }

    public function clubWheelSave(Request $request)
    {
        $amounts  = array_values((array) $request->input('amount', []));
        $percents = array_values((array) $request->input('percent', []));
        $colors   = array_values((array) $request->input('color', []));

        $count = max(count($amounts), count($percents));
        if ($count < 2) {
            return back()->withErrors(['prizes' => 'حداقل ۲ جایزه برای گردونه لازم است.'])->withInput();
        }
        if ($count > 12) {
            return back()->withErrors(['prizes' => 'حداکثر ۱۲ جایزه می‌توانید تعریف کنید.'])->withInput();
        }

        $defaults = \App\Services\CustomerClubService::defaultWheelPrizes();
        $prizes = [];
        $percentSum = 0.0;

        for ($i = 0; $i < $count; $i++) {
            $amount  = (int) preg_replace('/\D/', '', (string) ($amounts[$i] ?? 0));
            $percent = (float) str_replace(',', '.', (string) ($percents[$i] ?? 0));
            $color   = trim((string) ($colors[$i] ?? ''));

            if ($amount < 0) {
                return back()->withErrors(["amount.$i" => 'مبلغ جایزه نمی‌تواند منفی باشد.'])->withInput();
            }
            if ($percent < 0) {
                return back()->withErrors(["percent.$i" => 'درصد احتمال نمی‌تواند منفی باشد.'])->withInput();
            }

            if ($color === '' || !preg_match('/^#[0-9A-Fa-f]{6}$/', $color)) {
                $color = $defaults[$i]['color'] ?? '#94a3b8';
            }

            $prizes[] = [
                'amount'  => $amount,
                'percent' => round($percent, 2),
                'color'   => $color,
            ];
            $percentSum += $percent;
        }

        if ($percentSum <= 0) {
            return back()->withErrors(['percent' => 'جمع درصد احتمال باید بیشتر از صفر باشد.'])->withInput();
        }

        if (abs($percentSum - 100) > 0.05) {
            return back()
                ->withErrors(['percent' => 'جمع درصد احتمال باید دقیقاً ۱۰۰ باشد. جمع فعلی: ' . round($percentSum, 2) . '%'])
                ->withInput();
        }

        Setting::set('club_wheel_prizes', json_encode($prizes, JSON_UNESCAPED_UNICODE));

        return back()->with('success', 'تنظیمات گردونه شانس ذخیره شد.');
    }

    // ── Helper ───────────────────────────────────────────────────────────────

    private function getAuthStatus(): array
    {
        $token     = Setting::get('amadast_access_token');
        $expiresAt = (int) Setting::get('amadast_token_expires_at', 0);
        $isValid   = $token && $expiresAt > now()->timestamp;

        return [
            'logged_in' => $isValid,
            'mobile'    => Setting::get('amadast_mobile', ''),
            'name'      => Setting::get('amadast_user_name', ''),
            'balance'   => number_format((float) Setting::get('amadast_user_balance', 0)),
            'expires_at'=> $expiresAt ? now()->createFromTimestamp($expiresAt)->format('Y/m/d H:i') : null,
        ];
    }
}
