<?php

declare(strict_types=1);

namespace App\Http\Controllers\Settings;

use App\Http\Controllers\Controller;
use App\Models\ArtworkFeature;
use App\Services\FeaturedArtworkAdminService;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;

class FeaturedArtworkAdminController extends Controller
{
    public function __construct(private readonly FeaturedArtworkAdminService $featuredArtworks)
    {
    }

    public function index(Request $request): Response
    {
        $isAdminSurface = $request->routeIs('admin.artworks.featured.*');
        $routePrefix = $isAdminSurface ? 'admin.artworks.featured.' : 'admin.cp.artworks.featured.';

        return Inertia::render($isAdminSurface ? 'Admin/FeaturedArtworks' : 'Collection/FeaturedArtworksAdmin', array_merge(
            $this->featuredArtworks->pageProps(),
            [
                'endpoints' => [
                    'search' => route($routePrefix . 'search'),
                    'store' => route($routePrefix . 'store'),
                    'updatePattern' => route($routePrefix . 'update', ['feature' => '__FEATURE__']),
                    'togglePattern' => route($routePrefix . 'toggle', ['feature' => '__FEATURE__']),
                    'forceHeroPattern' => route($routePrefix . 'force-hero', ['feature' => '__FEATURE__']),
                    'destroyPattern' => route($routePrefix . 'delete', ['feature' => '__FEATURE__']),
                ],
                'capabilities' => [
                    'forceHeroEnabled' => $this->hasForceHeroColumn(),
                ],
                'seo' => [
                    'title' => 'Featured Artworks — Skinbase',
                    'description' => 'Editorial controls for homepage featured artworks and the current hero winner.',
                    'canonical' => route($routePrefix . 'main'),
                    'robots' => 'index,follow',
                ],
            ],
        ))->rootView($isAdminSurface ? 'admin' : 'collections');
    }

    public function search(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'q' => ['required', 'string', 'min:1', 'max:120'],
        ]);

        return response()->json([
            'ok' => true,
            'results' => $this->featuredArtworks->searchArtworks((string) $validated['q']),
        ]);
    }

    public function store(Request $request): JsonResponse
    {
        $validated = $this->validateStore($request);
        $actor = $this->currentActor($request);

        ArtworkFeature::query()->create([
            'artwork_id' => (int) $validated['artwork_id'],
            'priority' => (int) $validated['priority'],
            'featured_at' => Carbon::parse((string) $validated['featured_at']),
            'expires_at' => filled($validated['expires_at'] ?? null) ? Carbon::parse((string) $validated['expires_at']) : null,
            'is_active' => (bool) $validated['is_active'],
            'created_by' => (int) $actor->id,
        ]);

        return $this->mutationResponse('Featured artwork added.');
    }

    public function update(Request $request, ArtworkFeature $feature): JsonResponse
    {
        $validated = $this->validateUpdate($request);
        $this->ensureStateAvailable($feature, (bool) $validated['is_active']);

        $feature->fill([
            'priority' => (int) $validated['priority'],
            'featured_at' => Carbon::parse((string) $validated['featured_at']),
            'expires_at' => filled($validated['expires_at'] ?? null) ? Carbon::parse((string) $validated['expires_at']) : null,
            'is_active' => (bool) $validated['is_active'],
        ]);
        $feature->save();

        return $this->mutationResponse('Featured artwork updated.');
    }

    public function toggle(ArtworkFeature $feature): JsonResponse
    {
        $nextState = ! (bool) $feature->is_active;
        $this->ensureStateAvailable($feature, $nextState);

        $feature->forceFill([
            'is_active' => $nextState,
        ])->save();

        return $this->mutationResponse($nextState ? 'Featured artwork activated.' : 'Featured artwork deactivated.');
    }

    public function toggleForceHero(ArtworkFeature $feature): JsonResponse
    {
        $this->ensureForceHeroAvailable();

        $nextState = ! (bool) $feature->force_hero;

        DB::transaction(function () use ($feature, $nextState): void {
            if ($nextState) {
                ArtworkFeature::query()
                    ->where('force_hero', true)
                    ->whereNull('deleted_at')
                    ->whereKeyNot($feature->id)
                    ->update(['force_hero' => false]);
            }

            $feature->forceFill([
                'force_hero' => $nextState,
            ])->save();
        });

        return $this->mutationResponse($nextState ? 'Force hero enabled.' : 'Force hero disabled.');
    }

    public function destroy(ArtworkFeature $feature): JsonResponse
    {
        $feature->delete();

        return $this->mutationResponse('Featured artwork entry deleted.');
    }

    /**
     * @return array<string, mixed>
     */
    private function validateStore(Request $request): array
    {
        return $request->validate([
            'artwork_id' => [
                'required',
                'integer',
                Rule::exists('artworks', 'id'),
                Rule::unique('artwork_features', 'artwork_id')->where(fn ($query) => $query->whereNull('deleted_at')),
            ],
            'priority' => ['required', 'integer', 'min:0', 'max:65535'],
            'featured_at' => ['required', 'date'],
            'expires_at' => ['nullable', 'date', 'after:featured_at'],
            'is_active' => ['required', 'boolean'],
        ], [
            'artwork_id.unique' => 'This artwork already has a featured entry. Edit the existing row instead.',
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function validateUpdate(Request $request): array
    {
        return $request->validate([
            'priority' => ['required', 'integer', 'min:0', 'max:65535'],
            'featured_at' => ['required', 'date'],
            'expires_at' => ['nullable', 'date', 'after:featured_at'],
            'is_active' => ['required', 'boolean'],
        ]);
    }

    private function ensureStateAvailable(ArtworkFeature $feature, bool $isActive): void
    {
        $conflictExists = ArtworkFeature::query()
            ->where('artwork_id', $feature->artwork_id)
            ->where('is_active', $isActive)
            ->whereNull('deleted_at')
            ->whereKeyNot($feature->id)
            ->exists();

        if ($conflictExists) {
            throw ValidationException::withMessages([
                'is_active' => 'Another featured entry for this artwork already uses that active state.',
            ]);
        }
    }

    private function mutationResponse(string $message): JsonResponse
    {
        return response()->json(array_merge([
            'ok' => true,
            'message' => $message,
        ], $this->featuredArtworks->pageProps()));
    }

    private function currentActor(Request $request): object
    {
        return $request->user('controlpanel') ?? $request->user() ?? abort(403, 'Admin access required.');
    }

    private function ensureForceHeroAvailable(): void
    {
        if (! $this->hasForceHeroColumn()) {
            throw ValidationException::withMessages([
                'force_hero' => 'Run php artisan migrate to enable force hero controls.',
            ]);
        }
    }

    private function hasForceHeroColumn(): bool
    {
        return Schema::hasColumn('artwork_features', 'force_hero');
    }
}