<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Banner;
use App\Models\Carrier;
use App\Models\Setting;
use App\Models\ShippingMethod;
use App\Models\Unit;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;

class SettingController extends Controller
{
    public function index(Request $request): View
    {
        // Get tab from query string or hash, default to 'general'
        $tab = $request->get('tab', 'general');
        
        // Validate tab
        if (!in_array($tab, ['general', 'banners', 'shipping', 'payment', 'sms', 'ticket', 'units', 'taxes', 'carriers'])) {
            $tab = 'general';
        }

        $banners = Banner::orderBy('sort_order')->latest()->get();
        
        // Get shipping methods (with fallback if table doesn't exist)
        try {
            $shippingMethods = ShippingMethod::ordered()->get();
        } catch (\Exception $e) {
            $shippingMethods = \Illuminate\Support\Collection::make([]);
        }
        
        // Get payment settings
        $razorpayEnabled = Setting::get('payment_razorpay_enabled', '1') === '1';
        $codEnabled = Setting::get('payment_cod_enabled', '1') === '1';
        
        // Get webhook URLs (construct directly to avoid route resolution issues)
        $webhookUrl = url('/api/webhooks/razorpay');
        $ekartWebhookUrl = url('/api/webhooks/ekart');
        
        // Get Razorpay settings from database
        $razorpaySettings = [
            'key_id' => Setting::get('payment_razorpay_key_id', ''),
            'secret_key' => Setting::get('payment_razorpay_secret_key', ''),
            'webhook_secret' => Setting::get('payment_razorpay_webhook_secret', ''),
        ];

        // Stock reservation TTL for checkout (seconds). Default 900 = 15 min. Used so payment verify can capture before expiry.
        $stockReservationTtlSeconds = Setting::get('stock_reservation_ttl_seconds', '900');
        
        // Get SMS settings
        $smsSettings = [
            'sms_url' => Setting::get('sms_fast2sms_url', 'https://www.fast2sms.com/dev/bulkV2'),
            'api_key' => Setting::get('sms_fast2sms_api_key', ''),
            'sender' => Setting::get('sms_fast2sms_sender', 'KIYO'),
            'route' => Setting::get('sms_fast2sms_route', 'q'),
            'entity_id' => Setting::get('sms_fast2sms_entity_id', ''),
            'store_manager_mobile' => Setting::get('sms_store_manager_mobile', ''),
        ];

        $ticketSettings = [
            'notify_web' => Setting::get('tickets_notify_web', '1') === '1',
            'notify_sms' => Setting::get('tickets_notify_sms', '1') === '1',
            'notify_whatsapp' => Setting::get('tickets_notify_whatsapp', '0') === '1',
            'notify_on_reply' => Setting::get('tickets_notify_on_reply', '1') === '1',
            'notify_on_status' => Setting::get('tickets_notify_on_status', '1') === '1',
            'auto_close_enabled' => Setting::get('tickets_auto_close_enabled', '1') === '1',
            'customer_reply_timeout_days' => (int) Setting::get('tickets_customer_reply_timeout_days', '3'),
            'auto_close_grace_days' => (int) Setting::get('tickets_auto_close_grace_days', '1'),
        ];
        
        // Get units (with fallback if table doesn't exist)
        try {
            $units = Unit::orderBy('name')->get();
        } catch (\Exception $e) {
            $units = \Illuminate\Support\Collection::make([]);
        }
        
        // Get carrier settings
        $selectedCarrier = $request->get('carrier', '');
        $delhiverySettings = ['enabled' => '0', 'process_type' => 'automatic'];
        $expressbeesSettings = ['enabled' => '0', 'process_type' => 'automatic'];
        $ekartSettings = ['enabled' => '0', 'process_type' => 'automatic'];
        $indiapostSettings = ['enabled' => '0', 'process_type' => 'automatic'];
        $otherSettings = ['enabled' => '0', 'process_type' => 'manual'];
        
        try {
            $delhivery = Carrier::where('slug', 'delhivery')->first();
            if ($delhivery) {
                $delhiveryKeys = $delhivery->getDecryptedApiKeys();
                $delhiverySettings = [
                    'enabled' => $delhivery->enabled ? '1' : '0',
                    'process_type' => $delhivery->process_type ?? Carrier::PROCESS_TYPE_AUTOMATIC,
                    'api_url' => $delhiveryKeys['api_url'] ?? config('services.delhivery.api_url', 'https://staging-express.delhivery.com'),
                    'api_key' => $delhiveryKeys['api_token'] ?? config('services.delhivery.api_token', ''),
                ];
            }
            
            $expressbees = Carrier::where('slug', 'expressbees')->first();
            if ($expressbees) {
                $expressbeesKeys = $expressbees->getDecryptedApiKeys();
                $expressbeesSettings = [
                    'enabled' => $expressbees->enabled ? '1' : '0',
                    'process_type' => $expressbees->process_type ?? Carrier::PROCESS_TYPE_AUTOMATIC,
                    'api_url' => $expressbeesKeys['api_url'] ?? 'https://apiv2.expressbees.com',
                    'api_key' => $expressbeesKeys['api_token'] ?? '',
                    'email' => $expressbeesKeys['email'] ?? '',
                    'password' => $expressbeesKeys['password'] ?? '',
                ];
            }
            
            $ekart = Carrier::where('slug', 'ekart')->first();
            if ($ekart) {
                $ekartKeys = $ekart->getDecryptedApiKeys();
                $ekartSettings = [
                    'enabled' => $ekart->enabled ? '1' : '0',
                    'process_type' => $ekart->process_type ?? Carrier::PROCESS_TYPE_AUTOMATIC,
                    'api_url' => $ekartKeys['api_url'] ?? 'https://app.elite.ekartlogistics.in',
                    'username' => $ekartKeys['username'] ?? '',
                    'password' => $ekartKeys['password'] ?? '',
                    'client_id' => $ekartKeys['client_id'] ?? '',
                    'api_key' => $ekartKeys['api_token'] ?? '',
                    'webhook_secret' => $ekartKeys['webhook_secret'] ?? '',
                ];
            }

            $indiapost = Carrier::where('slug', 'indiapost')->first();
            if ($indiapost) {
                $indiapostKeys = $indiapost->getDecryptedApiKeys();
                $indiapostSettings = [
                    'enabled' => $indiapost->enabled ? '1' : '0',
                    'process_type' => $indiapost->process_type ?? Carrier::PROCESS_TYPE_AUTOMATIC,
                    'api_url' => $indiapostKeys['api_url'] ?? 'https://api.indiapost.gov.in',
                    'api_token' => $indiapostKeys['api_token'] ?? '',
                    'from_pincode' => $indiapostKeys['from_pincode'] ?? '',
                    'from_name' => $indiapostKeys['from_name'] ?? '',
                    'from_address' => $indiapostKeys['from_address'] ?? '',
                    'from_city' => $indiapostKeys['from_city'] ?? '',
                    'from_state' => $indiapostKeys['from_state'] ?? '',
                    'from_phone' => $indiapostKeys['from_phone'] ?? '',
                ];
            }

            $other = Carrier::where('slug', 'other')->first();
            if ($other) {
                $otherSettings = [
                    'enabled' => $other->enabled ? '1' : '0',
                    'process_type' => 'manual',
                ];
            }
        } catch (\Exception $e) {
            // Carrier table might not exist
        }

        return view('admin.settings.index', compact('tab', 'banners', 'shippingMethods', 'razorpayEnabled', 'codEnabled', 'units', 'webhookUrl', 'ekartWebhookUrl', 'razorpaySettings', 'smsSettings', 'ticketSettings', 'selectedCarrier', 'delhiverySettings', 'expressbeesSettings', 'ekartSettings', 'indiapostSettings', 'otherSettings', 'stockReservationTtlSeconds'));
    }

    public function update(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'site_name' => 'nullable|string|max:255',
            'site_email' => 'nullable|email|max:255',
            'site_phone' => 'nullable|string|max:20',
            'site_address' => 'nullable|string|max:500',
            'site_logo' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
            'site_logo_dark' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string|max:500',
            'meta_keywords' => 'nullable|string|max:255',
            'default_shipping_days' => 'nullable|integer|min:0|max:365',
            'site_gstin' => ['nullable', 'string', 'max:15', 'regex:/^[0-9A-Z]{15}$/'],
        ]);

        // Handle logo upload
        if ($request->hasFile('site_logo')) {
            // Delete old logo if exists
            $oldLogo = Setting::get('site_logo');
            if ($oldLogo && Storage::disk('public')->exists($oldLogo)) {
                Storage::disk('public')->delete($oldLogo);
            }
            
            // Store new logo
            $logoPath = $request->file('site_logo')->store('settings', 'public');
            Setting::set('site_logo', $logoPath);
        }

        // Handle dark logo upload
        if ($request->hasFile('site_logo_dark')) {
            // Delete old dark logo if exists
            $oldDarkLogo = Setting::get('site_logo_dark');
            if ($oldDarkLogo && Storage::disk('public')->exists($oldDarkLogo)) {
                Storage::disk('public')->delete($oldDarkLogo);
            }
            
            // Store new dark logo
            $darkLogoPath = $request->file('site_logo_dark')->store('settings', 'public');
            Setting::set('site_logo_dark', $darkLogoPath);
        }

        // Handle logo removal
        if ($request->has('remove_logo')) {
            $oldLogo = Setting::get('site_logo');
            if ($oldLogo && Storage::disk('public')->exists($oldLogo)) {
                Storage::disk('public')->delete($oldLogo);
            }
            Setting::set('site_logo', null);
        }

        if ($request->has('remove_logo_dark')) {
            $oldDarkLogo = Setting::get('site_logo_dark');
            if ($oldDarkLogo && Storage::disk('public')->exists($oldDarkLogo)) {
                Storage::disk('public')->delete($oldDarkLogo);
            }
            Setting::set('site_logo_dark', null);
        }

        if (isset($data['site_gstin'])) {
            $data['site_gstin'] = $data['site_gstin'] ? strtoupper($data['site_gstin']) : null;
        }

        // Save other settings
        foreach ($data as $key => $value) {
            if (!in_array($key, ['site_logo', 'site_logo_dark'])) {
                Setting::set($key, $value);
            }
        }

        return redirect()->route('admin.settings.index', ['tab' => 'general'])
            ->with('success', 'Settings updated successfully!');
    }

    public function updatePaymentSettings(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'payment_razorpay_enabled' => 'nullable|boolean',
            'payment_cod_enabled' => 'nullable|boolean',
            'payment_razorpay_key_id' => 'nullable|string|max:255',
            'payment_razorpay_secret_key' => 'nullable|string|max:255',
            'payment_razorpay_webhook_secret' => 'nullable|string|max:255',
            'stock_reservation_ttl_seconds' => 'nullable|integer|min:60|max:3600',
        ]);

        Setting::set('payment_razorpay_enabled', $request->has('payment_razorpay_enabled') ? '1' : '0');
        Setting::set('payment_cod_enabled', $request->has('payment_cod_enabled') ? '1' : '0');
        
        // Save Razorpay keys
        Setting::set('payment_razorpay_key_id', $data['payment_razorpay_key_id'] ?? '');
        Setting::set('payment_razorpay_secret_key', $data['payment_razorpay_secret_key'] ?? '');
        Setting::set('payment_razorpay_webhook_secret', $data['payment_razorpay_webhook_secret'] ?? '');

        // Stock reservation TTL (seconds). Default 900 = 15 min. Reduces failed captures when user pays after a few minutes.
        Setting::set('stock_reservation_ttl_seconds', (string) ($data['stock_reservation_ttl_seconds'] ?? 900));

        return redirect()->route('admin.settings.index', ['tab' => 'payment'])
            ->with('success', 'Payment settings updated successfully!');
    }

    public function updateSmsSettings(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'sms_fast2sms_url' =>  'nullable|string|max:255',
            'sms_fast2sms_api_key' => 'nullable|string|max:255',
            'sms_fast2sms_sender' => 'nullable|string|max:10',
            'sms_fast2sms_route' => 'nullable|string|max:50',
            'sms_fast2sms_entity_id' => 'nullable|string|max:255',
            'sms_store_manager_mobile' => 'nullable|string|max:20',
        ]);

        // Save SMS settings (template IDs are managed in Admin > SMS Templates)
        Setting::set('sms_fast2sms_url', $data['sms_fast2sms_url'] ?? 'https://www.fast2sms.com/dev/bulkV2');
        Setting::set('sms_fast2sms_api_key', $data['sms_fast2sms_api_key'] ?? '');
        Setting::set('sms_fast2sms_sender', $data['sms_fast2sms_sender'] ?? 'KIYO');
        Setting::set('sms_fast2sms_route', $data['sms_fast2sms_route'] ?? 'q');
        Setting::set('sms_fast2sms_entity_id', $data['sms_fast2sms_entity_id'] ?? '');
        Setting::set('sms_store_manager_mobile', trim($data['sms_store_manager_mobile'] ?? ''));

        return redirect()->route('admin.settings.index', ['tab' => 'sms'])
            ->with('success', 'SMS settings updated successfully!');
    }

    public function updateTicketSettings(Request $request): RedirectResponse
    {
        $request->validate([
            'tickets_notify_web' => 'nullable|boolean',
            'tickets_notify_sms' => 'nullable|boolean',
            'tickets_notify_whatsapp' => 'nullable|boolean',
            'tickets_notify_on_reply' => 'nullable|boolean',
            'tickets_notify_on_status' => 'nullable|boolean',
            'tickets_auto_close_enabled' => 'nullable|boolean',
            'tickets_customer_reply_timeout_days' => 'nullable|integer|min:1|max:30',
            'tickets_auto_close_grace_days' => 'nullable|integer|min:1|max:30',
        ]);

        Setting::set('tickets_notify_web', $request->has('tickets_notify_web') ? '1' : '0');
        Setting::set('tickets_notify_sms', $request->has('tickets_notify_sms') ? '1' : '0');
        Setting::set('tickets_notify_whatsapp', $request->has('tickets_notify_whatsapp') ? '1' : '0');
        Setting::set('tickets_notify_on_reply', $request->has('tickets_notify_on_reply') ? '1' : '0');
        Setting::set('tickets_notify_on_status', $request->has('tickets_notify_on_status') ? '1' : '0');
        Setting::set('tickets_auto_close_enabled', $request->has('tickets_auto_close_enabled') ? '1' : '0');
        Setting::set('tickets_customer_reply_timeout_days', (string) ((int) $request->input('tickets_customer_reply_timeout_days', 3)));
        Setting::set('tickets_auto_close_grace_days', (string) ((int) $request->input('tickets_auto_close_grace_days', 1)));

        return redirect()->route('admin.settings.index', ['tab' => 'ticket'])
            ->with('success', 'Ticket settings updated successfully!');
    }

    public function updateCarrierSettings(Request $request): RedirectResponse
    {
        $selectedCarrier = $request->input('selected_carrier');
        
        if ($selectedCarrier === 'delhivery') {
            $data = $request->validate([
                'selected_carrier' => 'required|in:delhivery',
                'delhivery_enabled' => 'required|in:0,1',
                'delhivery_process_type' => 'required|in:automatic,manual',
                'delhivery_api_url' => 'nullable|url|max:255',
                'delhivery_api_key' => 'nullable|string|max:255',
            ]);
            if (($data['delhivery_process_type'] ?? '') === 'automatic') {
                $request->validate([
                    'delhivery_api_url' => 'required|url|max:255',
                    'delhivery_api_key' => 'required|string|max:255',
                ]);
            }

            try {
                $carrier = Carrier::firstOrNew(['slug' => 'delhivery']);
                $carrier->name = 'Delhivery';
                $carrier->enabled = $data['delhivery_enabled'] === '1';
                $carrier->process_type = $data['delhivery_process_type'];
                if ($carrier->process_type === Carrier::PROCESS_TYPE_AUTOMATIC) {
                    $carrier->setApiKeys([
                        'api_token' => $data['delhivery_api_key'] ?? '',
                        'api_url' => $data['delhivery_api_url'] ?? '',
                    ]);
                } else {
                    $carrier->setApiKeys([]);
                }
                $carrier->save();

                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'delhivery'])
                    ->with('success', 'Delhivery settings updated successfully!');
            } catch (\Exception $e) {
                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'delhivery'])
                    ->withInput()
                    ->with('error', 'Failed to update Delhivery settings: ' . $e->getMessage());
            }
        } elseif ($selectedCarrier === 'expressbees') {
            $data = $request->validate([
                'selected_carrier' => 'required|in:expressbees',
                'expressbees_enabled' => 'required|in:0,1',
                'expressbees_process_type' => 'required|in:automatic,manual',
                'expressbees_api_url' => 'nullable|url|max:255',
                'expressbees_api_key' => 'nullable|string|max:255',
                'expressbees_email' => 'nullable|string|max:255',
                'expressbees_password' => 'nullable|string|max:255',
            ]);
            if (($data['expressbees_process_type'] ?? '') === 'automatic') {
                $request->validate([
                    'expressbees_api_url' => 'required|url|max:255',
                    'expressbees_email' => 'required|string|max:255',
                    'expressbees_password' => 'required|string|max:255',
                ]);
            }

            try {
                $carrier = Carrier::firstOrNew(['slug' => 'expressbees']);
                $carrier->name = 'XpressBees';
                $carrier->enabled = $data['expressbees_enabled'] === '1';
                $carrier->process_type = $data['expressbees_process_type'];
                if ($carrier->process_type === Carrier::PROCESS_TYPE_AUTOMATIC) {
                    $carrier->setApiKeys([
                        'api_token' => $data['expressbees_api_key'] ?? '',
                        'api_url' => $data['expressbees_api_url'] ?? '',
                        'email' => $data['expressbees_email'] ?? '',
                        'password' => $data['expressbees_password'] ?? '',
                    ]);
                } else {
                    $carrier->setApiKeys([]);
                }
                $carrier->save();

                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'expressbees'])
                    ->with('success', 'XpressBees settings updated successfully!');
            } catch (\Exception $e) {
                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'expressbees'])
                    ->withInput()
                    ->with('error', 'Failed to update XpressBees settings: ' . $e->getMessage());
            }
        } elseif ($selectedCarrier === 'ekart') {
            $data = $request->validate([
                'selected_carrier' => 'required|in:ekart',
                'ekart_enabled' => 'required|in:0,1',
                'ekart_process_type' => 'required|in:automatic,manual',
                'ekart_api_url' => 'nullable|url|max:255',
                'ekart_username' => 'nullable|string|max:255',
                'ekart_password' => 'nullable|string|max:255',
                'ekart_client_id' => 'nullable|string|max:255',
                'ekart_api_key' => 'nullable|string|max:255',
                'ekart_webhook_secret' => 'nullable|string|min:6|max:30',
            ]);
            if (($data['ekart_process_type'] ?? '') === 'automatic') {
                $request->validate([
                    'ekart_api_url' => 'required|url|max:255',
                    'ekart_username' => 'required|string|max:255',
                    'ekart_password' => 'required|string|max:255',
                    'ekart_client_id' => 'required|string|max:255',
                ]);
            }

            try {
                $carrier = Carrier::firstOrNew(['slug' => 'ekart']);
                $carrier->name = 'Ekart';
                $carrier->enabled = $data['ekart_enabled'] === '1';
                $carrier->process_type = $data['ekart_process_type'];
                if ($carrier->process_type === Carrier::PROCESS_TYPE_AUTOMATIC) {
                    $carrier->setApiKeys([
                        'username' => $data['ekart_username'] ?? '',
                        'password' => $data['ekart_password'] ?? '',
                        'client_id' => $data['ekart_client_id'] ?? '',
                        'api_url' => $data['ekart_api_url'] ?? '',
                        'api_token' => $data['ekart_api_key'] ?? '',
                        'webhook_secret' => $data['ekart_webhook_secret'] ?? '',
                    ]);
                } else {
                    $carrier->setApiKeys([]);
                }
                $carrier->save();

                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'ekart'])
                    ->with('success', 'Ekart settings updated successfully!');
            } catch (\Exception $e) {
                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'ekart'])
                    ->withInput()
                    ->with('error', 'Failed to update Ekart settings: ' . $e->getMessage());
            }
        } elseif ($selectedCarrier === 'indiapost') {
            $data = $request->validate([
                'selected_carrier' => 'required|in:indiapost',
                'indiapost_enabled' => 'required|in:0,1',
                'indiapost_process_type' => 'required|in:automatic,manual',
                'indiapost_api_url' => 'nullable|url|max:255',
                'indiapost_api_token' => 'nullable|string|max:255',
                'indiapost_from_pincode' => 'nullable|string|max:20',
                'indiapost_from_name' => 'nullable|string|max:255',
                'indiapost_from_address' => 'nullable|string|max:500',
                'indiapost_from_city' => 'nullable|string|max:100',
                'indiapost_from_state' => 'nullable|string|max:100',
                'indiapost_from_phone' => 'nullable|string|max:20',
            ]);
            if (($data['indiapost_process_type'] ?? '') === 'automatic') {
                $request->validate([
                    'indiapost_api_url' => 'required|url|max:255',
                ]);
            }

            try {
                $carrier = Carrier::firstOrNew(['slug' => 'indiapost']);
                $carrier->name = 'India Postal';
                $carrier->enabled = $data['indiapost_enabled'] === '1';
                $carrier->process_type = $data['indiapost_process_type'];
                if ($carrier->process_type === Carrier::PROCESS_TYPE_AUTOMATIC) {
                    $carrier->setApiKeys([
                        'api_url' => $data['indiapost_api_url'] ?? '',
                        'api_token' => $data['indiapost_api_token'] ?? '',
                        'from_pincode' => $data['indiapost_from_pincode'] ?? '',
                        'from_name' => $data['indiapost_from_name'] ?? '',
                        'from_address' => $data['indiapost_from_address'] ?? '',
                        'from_city' => $data['indiapost_from_city'] ?? '',
                        'from_state' => $data['indiapost_from_state'] ?? '',
                        'from_phone' => $data['indiapost_from_phone'] ?? '',
                    ]);
                } else {
                    $carrier->setApiKeys([]);
                }
                $carrier->save();

                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'indiapost'])
                    ->with('success', 'India Postal settings updated successfully!');
            } catch (\Exception $e) {
                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'indiapost'])
                    ->withInput()
                    ->with('error', 'Failed to update India Postal settings: ' . $e->getMessage());
            }
        } elseif ($selectedCarrier === 'other') {
            $data = $request->validate([
                'selected_carrier' => 'required|in:other',
                'other_enabled' => 'required|in:0,1',
            ]);

            try {
                $carrier = Carrier::firstOrNew(['slug' => 'other']);
                $carrier->name = 'Other';
                $carrier->enabled = $data['other_enabled'] === '1';
                $carrier->process_type = Carrier::PROCESS_TYPE_MANUAL;
                $carrier->setApiKeys([]);
                $carrier->save();

                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'other'])
                    ->with('success', 'Other carrier settings updated successfully!');
            } catch (\Exception $e) {
                return redirect()->route('admin.settings.index', ['tab' => 'carriers', 'carrier' => 'other'])
                    ->withInput()
                    ->with('error', 'Failed to update Other carrier settings: ' . $e->getMessage());
            }
        } else {
            return redirect()->route('admin.settings.index', ['tab' => 'carriers'])
                ->with('error', 'Please select a carrier');
        }
    }
}
