<?php

namespace App\Http\Controllers\Api\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\NotificationPreferencesRequest;
use App\Http\Requests\Tenant\SettingsStoreRequest;
use App\Models\Tenant;
use App\Services\Packages\TenantNotificationPreferences;
use App\Support\ApiError;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class SettingsController extends Controller
{
    /**
     * Get the tenant's settings.
     */
    public function index(Request $request): JsonResponse
    {
        $tenant = $this->resolveTenant($request);

        return response()->json([
            'message' => 'Settings erfolgreich abgerufen.',
            'data' => [
                'id' => $tenant->id,
                'settings' => $tenant->settings ?? [],
                'updated_at' => $tenant->settings_updated_at?->toISOString(),
            ],
        ]);
    }

    public function notificationPreferences(
        Request $request,
        TenantNotificationPreferences $preferencesService
    ): JsonResponse {
        $tenant = $this->resolveTenant($request);
        $defaults = TenantNotificationPreferences::defaults();
        $resolved = [];

        foreach (array_keys($defaults) as $key) {
            $resolved[$key] = $preferencesService->shouldNotify($tenant, $key);
        }

        return response()->json([
            'data' => [
                'defaults' => $defaults,
                'preferences' => $resolved,
                'overrides' => $tenant->notification_preferences ?? null,
            ],
        ]);
    }

    public function updateNotificationPreferences(
        NotificationPreferencesRequest $request,
        TenantNotificationPreferences $preferencesService
    ): JsonResponse {
        $tenant = $this->resolveTenant($request);
        $payload = $request->validated()['preferences'];

        $tenant->update([
            'notification_preferences' => $payload,
        ]);

        $tenant->refresh();

        $resolved = [];
        foreach (array_keys(TenantNotificationPreferences::defaults()) as $key) {
            $resolved[$key] = $preferencesService->shouldNotify($tenant->fresh(), $key);
        }

        return response()->json([
            'message' => 'Benachrichtigungseinstellungen aktualisiert.',
            'data' => [
                'preferences' => $resolved,
                'overrides' => $tenant->notification_preferences,
            ],
        ]);
    }

    /**
     * Update the tenant's settings.
     */
    public function update(SettingsStoreRequest $request): JsonResponse
    {
        $tenant = $this->resolveTenant($request);
        $settings = $request->validated()['settings'];

        $tenant->update([
            'settings' => $settings,
            'settings_updated_at' => now(),
        ]);

        return response()->json([
            'message' => 'Settings erfolgreich aktualisiert.',
            'data' => [
                'id' => $tenant->id,
                'settings' => $settings,
                'updated_at' => now()->toISOString(),
            ],
        ]);
    }

    /**
     * Reset tenant settings to defaults.
     */
    public function reset(Request $request): JsonResponse
    {
        $tenant = $this->resolveTenant($request);

        $defaultSettings = [
            'branding' => [
                'logo_url' => null,
                'primary_color' => '#FF5A5F',
                'secondary_color' => '#FFF8F5',
                'font_family' => 'Inter, sans-serif',
            ],
            'features' => [
                'photo_likes_enabled' => true,
                'event_checklist' => true,
                'custom_domain' => false,
                'advanced_analytics' => false,
            ],
            'custom_domain' => null,
            'contact_email' => $tenant->contact_email,
            'event_default_type' => 'general',
        ];

        $tenant->update([
            'settings' => $defaultSettings,
            'settings_updated_at' => now(),
        ]);

        return response()->json([
            'message' => 'Settings auf Standardwerte zurueckgesetzt.',
            'data' => [
                'id' => $tenant->id,
                'settings' => $defaultSettings,
                'updated_at' => now()->toISOString(),
            ],
        ]);
    }

    private function resolveTenant(Request $request): Tenant
    {
        $tenant = $request->attributes->get('tenant');

        if ($tenant instanceof Tenant) {
            return $tenant;
        }

        $tenantId = $request->attributes->get('tenant_id')
            ?? $request->attributes->get('current_tenant_id')
            ?? $request->user()?->tenant_id;

        if ($tenantId) {
            $tenant = Tenant::query()->find($tenantId);
            if ($tenant) {
                $request->attributes->set('tenant', $tenant);

                return $tenant;
            }
        }

        throw new HttpResponseException(ApiError::response(
            'tenant_context_missing',
            'Tenant context missing',
            'Unable to determine tenant for the current request.',
            Response::HTTP_UNAUTHORIZED
        ));
    }

    /**
     * Validate custom domain availability.
     */
    public function validateDomain(Request $request): JsonResponse
    {
        $domain = $request->input('domain');

        if (! $domain) {
            return ApiError::response(
                'domain_missing',
                'Domain erforderlich',
                'Bitte gib eine Domain an.',
                Response::HTTP_BAD_REQUEST
            );
        }

        if (! $this->isValidDomain($domain)) {
            return response()->json([
                'available' => false,
                'message' => 'Ungueltiges Domain-Format.',
            ]);
        }

        $taken = Tenant::where('custom_domain', $domain)
            ->where('id', '!=', $this->resolveTenant($request)->id)
            ->exists();

        return response()->json([
            'available' => ! $taken,
            'message' => $taken ? 'Domain ist bereits vergeben.' : 'Domain ist verfuegbar.',
        ]);
    }

    private function isValidDomain(string $domain): bool
    {
        return filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) !== false;
    }
}
