<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Concerns\ResolvesPlatformAdminContext;
use App\Http\Controllers\Controller;
use App\Models\ChannelConfig;
use App\Models\PaymentConfig;
use App\Models\SystemConfig;
use App\Models\Merchant;
use App\Support\CacheKeys;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class PlatformSettingController extends Controller
{
    use ResolvesPlatformAdminContext;

    public function system(Request $request): View
    {
        $this->ensurePlatformAdmin($request);

        $configs = Cache::remember(
            CacheKeys::platformSystemConfigs(),
            now()->addMinutes(10),
            fn () => SystemConfig::query()
                ->orderBy('group')
                ->orderBy('id')
                ->get()
        );

        return view('admin.settings.system', [
            'systemSettings' => $configs,
            'groupedCount' => $configs->groupBy('group')->count(),
            'valueTypeOptions' => ['string', 'boolean', 'number', 'json'],
            'editingConfigId' => (int) session('editing_config_id', 0),
        ]);
    }

    public function updateSystem(Request $request, int $id): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $config = SystemConfig::query()->findOrFail($id);

        $data = $request->validate([
            'config_name' => ['required', 'string'],
            'config_value' => ['nullable', 'string'],
            'group' => ['required', 'string'],
            'value_type' => ['required', 'string'],
            'autoload' => ['nullable', 'boolean'],
            'remark' => ['nullable', 'string'],
        ]);

        try {
            $normalizedValue = match ($data['value_type']) {
                'boolean' => in_array(strtolower((string) ($data['config_value'] ?? '')), ['1', 'true', 'yes', 'on'], true) ? '1' : '0',
                'number' => (string) (is_numeric($data['config_value'] ?? null) ? $data['config_value'] : 0),
                'json' => $this->normalizeJsonConfigValue($data['config_value'] ?? null),
                default => $data['config_value'] ?? null,
            };
        } catch (ValidationException $exception) {
            return redirect('/admin/settings/system')
                ->withErrors($exception->errors())
                ->withInput()
                ->with('editing_config_id', $config->id);
        }

        $config->update([
            'config_name' => $data['config_name'],
            'config_value' => $normalizedValue,
            'group' => $data['group'],
            'value_type' => $data['value_type'],
            'autoload' => (bool) ($data['autoload'] ?? false),
            'remark' => $data['remark'] ?? null,
        ]);

        Cache::forget(CacheKeys::platformSystemConfigs());

        return redirect('/admin/settings/system')->with('success', '系统配置更新成功');
    }

    public function channels(Request $request): View
    {
        $this->ensurePlatformAdmin($request);

        $payload = Cache::remember(
            CacheKeys::platformChannelsOverview(),
            now()->addMinutes(10),
            fn () => [
                'channels' => ChannelConfig::query()
                    ->orderBy('sort')
                    ->orderBy('id')
                    ->get(),
                'paymentConfigs' => PaymentConfig::query()->orderBy('id')->get(),
                'merchantCount' => Merchant::count(),
            ]
        );

        return view('admin.settings.channels', $payload);
    }

    public function updateChannel(Request $request, int $id): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $channel = ChannelConfig::query()->findOrFail($id);

        $data = $request->validate([
            'channel_name' => ['required', 'string'],
            'channel_type' => ['required', 'string'],
            'status' => ['required', 'string'],
            'entry_path' => ['nullable', 'string'],
            'supports_login' => ['nullable', 'boolean'],
            'supports_payment' => ['nullable', 'boolean'],
            'supports_share' => ['nullable', 'boolean'],
            'remark' => ['nullable', 'string'],
        ]);

        $channel->update([
            'channel_name' => $data['channel_name'],
            'channel_type' => $data['channel_type'],
            'status' => $data['status'],
            'entry_path' => $data['entry_path'] ?? null,
            'supports_login' => (bool) ($data['supports_login'] ?? false),
            'supports_payment' => (bool) ($data['supports_payment'] ?? false),
            'supports_share' => (bool) ($data['supports_share'] ?? false),
            'remark' => $data['remark'] ?? null,
        ]);

        Cache::forget(CacheKeys::platformChannelsOverview());

        return redirect('/admin/settings/channels')->with('success', '渠道配置更新成功');
    }

    public function updatePayment(Request $request, int $id): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $payment = PaymentConfig::query()->findOrFail($id);

        $data = $request->validate([
            'payment_name' => ['required', 'string'],
            'provider' => ['required', 'string'],
            'status' => ['required', 'string'],
            'is_sandbox' => ['nullable', 'boolean'],
            'supports_refund' => ['nullable', 'boolean'],
            'remark' => ['nullable', 'string'],
        ]);

        $payment->update([
            'payment_name' => $data['payment_name'],
            'provider' => $data['provider'],
            'status' => $data['status'],
            'is_sandbox' => (bool) ($data['is_sandbox'] ?? false),
            'supports_refund' => (bool) ($data['supports_refund'] ?? false),
            'remark' => $data['remark'] ?? null,
        ]);

        Cache::forget(CacheKeys::platformChannelsOverview());

        return redirect('/admin/settings/channels')->with('success', '支付配置更新成功');
    }

    protected function normalizeJsonConfigValue(?string $value): string
    {
        if ($value === null || trim($value) === '') {
            return '{}';
        }

        $decoded = json_decode($value, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw ValidationException::withMessages([
                'config_value' => 'JSON 配置值格式不正确，请检查后重试。',
            ]);
        }

        return json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }
}
