<?php

namespace App\Http\Controllers\Settings;

use App\Http\Controllers\Controller;
use App\Http\Requests\Settings\AdminSettingUpdateRequest;
use App\Models\Setting;
use App\Services\DuitkuService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Inertia\Inertia;
use Inertia\Response;

/**
 * Pengaturan sistem (SMTP, Duitku, rate billing) — admin/developer only.
 * Nilai disimpan di tabel settings & menimpa config() saat runtime.
 */
class AdminSettingController extends Controller
{
    public function __construct(
        private readonly DuitkuService $duitkuService,
    ) {}

    /**
     * Tampilkan halaman setting admin (3 tab).
     */
    public function edit(Request $request): Response
    {
        Gate::authorize('manage-all');

        return Inertia::render('settings/AdminSettings', [
            'smtp' => [
                'host' => config('mail.mailers.smtp.host'),
                'port' => config('mail.mailers.smtp.port'),
                'username' => config('mail.mailers.smtp.username'),
                'password' => $this->secretMask('mail.mailers.smtp.password'),
                'encryption' => config('mail.mailers.smtp.encryption'),
                'from_address' => config('mail.from.address'),
                'from_name' => config('mail.from.name'),
                'default' => config('mail.default'),
            ],
            'duitku' => [
                'enabled' => (bool) config('services.duitku.enabled'),
                'merchant_code' => config('services.duitku.merchant_code'),
                'api_key' => $this->secretMask('services.duitku.api_key'),
                'base_url' => config('services.duitku.base_url'),
                'inquiry_path' => config('services.duitku.inquiry_path'),
                'callback_url' => config('services.duitku.callback_url'),
                'return_url' => config('services.duitku.return_url'),
                'expiry_period' => config('services.duitku.expiry_period'),
                'configured' => $this->duitkuService->isConfigured(),
            ],
            'rate' => [
                'default_rate' => (int) config('ads.default_rate', 100),
                'empty_kategori_url' => (string) (config('ads.empty_kategori_url') ?? ''),
            ],
            'website' => [
                'logo_url' => $this->brandingUrl(config('ads.logo_path')),
                'favicon_url' => $this->brandingUrl(config('ads.favicon_path')),
            ],
            'status' => $request->session()->get('status'),
        ]);
    }

    /**
     * Simpan setting per tab.
     */
    public function update(AdminSettingUpdateRequest $request): RedirectResponse
    {
        Gate::authorize('manage-all');

        $data = $request->validated();
        $tab = $data['tab'];

        match ($tab) {
            'smtp' => $this->updateSmtp($data),
            'duitku' => $this->updateDuitku($data),
            'rate' => $this->updateRate($data),
            'website' => $this->updateWebsite($request),
        };

        return back()->with('status', 'Pengaturan disimpan.');
    }

    /**
     * Kirim email test pakai konfigurasi SMTP saat ini.
     */
    public function sendTestEmail(Request $request): RedirectResponse
    {
        Gate::authorize('manage-all');

        $validated = $request->validate([
            'recipient' => ['required', 'email', 'max:255'],
        ]);

        try {
            Mail::mailer('smtp')->raw(
                'Ini email uji coba dari '.config('app.name').'. SMTP terkonfigurasi dengan benar.',
                fn ($m) => $m->to($validated['recipient'])->subject('Uji Coba SMTP')
            );

            return back()->with('status', 'Email test terkirim ke '.$validated['recipient'].'.');
        } catch (\Throwable $e) {
            return back()->withErrors(['test_email' => 'Gagal mengirim email test: '.$e->getMessage()])->withInput();
        }
    }

    /**
     * Simpan setting SMTP.
     */
    protected function updateSmtp(array $data): void
    {
        Setting::set('mail.mailers.smtp.host', $data['mail_host'] ?? null);
        Setting::set('mail.mailers.smtp.port', isset($data['mail_port']) ? (int) $data['mail_port'] : null);
        Setting::set('mail.mailers.smtp.username', $data['mail_username'] ?? null);
        Setting::set('mail.mailers.smtp.password', $data['mail_password'] ?? null, secret: true);
        Setting::set('mail.mailers.smtp.encryption', $data['mail_encryption'] === 'none' ? null : ($data['mail_encryption'] ?? null));
        Setting::set('mail.from.address', $data['mail_from_address'] ?? null);
        Setting::set('mail.from.name', $data['mail_from_name'] ?? null);
        Setting::set('mail.default', $data['mail_default'] ?? null);
    }

    /**
     * Simpan setting Duitku.
     */
    protected function updateDuitku(array $data): void
    {
        Setting::set('services.duitku.enabled', (bool) ($data['duitku_enabled'] ?? false));
        Setting::set('services.duitku.merchant_code', $data['duitku_merchant_code'] ?? null);
        Setting::set('services.duitku.api_key', $data['duitku_api_key'] ?? null, secret: true);
        Setting::set('services.duitku.base_url', $data['duitku_base_url'] ?? null);
        Setting::set('services.duitku.inquiry_path', $data['duitku_inquiry_path'] ?? null);
        Setting::set('services.duitku.callback_url', $data['duitku_callback_url'] ?? null);
        Setting::set('services.duitku.return_url', $data['duitku_return_url'] ?? null);
        Setting::set('services.duitku.expiry_period', isset($data['duitku_expiry_period']) ? (int) $data['duitku_expiry_period'] : null);
    }

    /**
     * Simpan setting rate + link fallback kategori kosong.
     */
    protected function updateRate(array $data): void
    {
        Setting::set('ads.default_rate', (int) $data['default_rate']);
        Setting::set('ads.empty_kategori_url', $data['empty_kategori_url'] ?: null);
    }

    /**
     * Simpan branding website: upload/hapus logo & favicon (disk public).
     */
    protected function updateWebsite(AdminSettingUpdateRequest $request): void
    {
        if ($request->boolean('remove_logo')) {
            $this->deleteBranding(config('ads.logo_path'));
            Setting::set('ads.logo_path', null);
        }

        if ($request->boolean('remove_favicon')) {
            $this->deleteBranding(config('ads.favicon_path'));
            Setting::set('ads.favicon_path', null);
        }

        if ($request->hasFile('logo')) {
            $this->deleteBranding(config('ads.logo_path'));
            Setting::set('ads.logo_path', $request->file('logo')->store('branding', 'public'));
        }

        if ($request->hasFile('favicon')) {
            $this->deleteBranding(config('ads.favicon_path'));
            Setting::set('ads.favicon_path', $request->file('favicon')->store('branding', 'public'));
        }
    }

    /**
     * Hapus file branding lama dari disk public.
     */
    protected function deleteBranding(?string $path): void
    {
        if ($path && Storage::disk('public')->exists($path)) {
            Storage::disk('public')->delete($path);
        }
    }

    /**
     * Ubah path branding jadi URL publik; null bila belum diatur.
     */
    protected function brandingUrl(?string $path): ?string
    {
        return $path ? Storage::disk('public')->url($path) : null;
    }

    /**
     * Mask nilai secret untuk frontend: hanya kembalikan is_set, bukan nilai.
     */
    protected function secretMask(string $configKey): array
    {
        $value = config($configKey);

        return ['is_set' => filled($value), 'value' => null];
    }
}
