<?php

namespace App\Http\Controllers\Admin;

use App\Enums\ContentStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\BulkActionRequest;
use App\Http\Requests\Admin\StoreGalleryItemRequest;
use App\Http\Requests\Admin\UpdateGalleryItemRequest;
use App\Models\GalleryItem;
use App\Services\ActivityLogger;
use App\Services\ContentCacheService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;

class GalleryController extends Controller
{
    public function index(): View
    {
        Gate::authorize('viewAny', GalleryItem::class);

        $query = GalleryItem::query()->with('media')->where('status', '!=', ContentStatus::Archived->value)->ordered();
        if ($search = request('q')) {
            $query->where('title', 'like', "%{$search}%");
        }
        if ($category = request('category')) {
            $query->where('category', $category);
        }
        if ($status = request('status')) {
            $query->where('status', $status);
        }

        return view('admin.gallery.index', ['items' => $query->get()]);
    }

    public function archiveIndex(): View
    {
        Gate::authorize('viewAny', GalleryItem::class);

        return view('admin.gallery.archive', [
            'items' => GalleryItem::query()->with('media')->archived()->ordered()->get(),
        ]);
    }

    public function create(): View
    {
        Gate::authorize('create', GalleryItem::class);

        return view('admin.gallery.form', ['item' => null]);
    }

    public function store(StoreGalleryItemRequest $request, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('create', GalleryItem::class);
        if ($request->input('_action') === 'publish') {
            Gate::authorize('publish', new GalleryItem());
        }

        $item = GalleryItem::create($this->data($request->validated(), $request->input('_action')) + ['created_by' => auth()->id(), 'updated_by' => auth()->id()]);
        if ($request->input('_action') === 'publish') {
            Gate::authorize('publish', $item);
        }
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.created', $item, "Réalisation créée: {$item->title}");

        return redirect()->route('admin.gallery.edit', $item)->with('status', 'Réalisation créée.');
    }

    public function edit(GalleryItem $item): View
    {
        Gate::authorize('update', $item);

        return view('admin.gallery.form', ['item' => $item->load('media')]);
    }

    public function update(UpdateGalleryItemRequest $request, GalleryItem $item, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('update', $item);
        if ($request->input('_action') === 'publish') {
            Gate::authorize('publish', $item);
        }

        $item->update($this->data($request->validated(), $request->input('_action')) + ['updated_by' => auth()->id()]);
        if ($request->input('_action') === 'publish') {
            Gate::authorize('publish', $item);
        }
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.updated', $item, "Réalisation modifiée: {$item->title}");

        return back()->with('status', 'Réalisation enregistrée.');
    }

    public function publish(GalleryItem $item, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('publish', $item);

        $item->forceFill(['status' => ContentStatus::Published->value, 'is_active' => true, 'published_at' => now()])->save();
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.published', $item, "Réalisation publiée: {$item->title}");

        return back()->with('status', 'Réalisation publiée.');
    }

    public function toggle(GalleryItem $item): RedirectResponse
    {
        Gate::authorize('update', $item);
        $item->forceFill([
            'status' => $item->status === ContentStatus::Published->value ? ContentStatus::Draft->value : ContentStatus::Published->value,
            'is_active' => $item->status !== ContentStatus::Published->value,
            'published_at' => $item->status !== ContentStatus::Published->value ? now() : $item->published_at,
        ])->save();
        app(ContentCacheService::class)->flush();

        return back()->with('status', 'Statut modifié.');
    }

    public function archive(GalleryItem $item, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('delete', $item);
        $item->forceFill(['status' => ContentStatus::Archived->value, 'is_active' => false])->save();
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.archived', $item, "Réalisation archivée: {$item->title}");

        return back()->with('status', 'Réalisation archivée.');
    }

    public function restore(GalleryItem $item, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('update', $item);
        $item->forceFill(['status' => ContentStatus::Draft->value, 'is_active' => false])->save();
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.restored', $item, "Réalisation restaurée: {$item->title}");

        return back()->with('status', 'Réalisation restaurée en brouillon.');
    }

    public function forceDestroy(GalleryItem $item, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('forceDelete', $item);
        $title = $item->title;
        $item->forceDelete();
        app(ContentCacheService::class)->flush();
        $logger->log('gallery.force_deleted', $item, "Réalisation supprimée définitivement: {$title}");

        return back()->with('status', 'Réalisation supprimée définitivement.');
    }

    public function bulk(BulkActionRequest $request): RedirectResponse
    {
        $items = GalleryItem::whereIn('id', $request->input('ids'))->get();

        DB::transaction(fn () => $items->each(function (GalleryItem $item) use ($request): void {
            Gate::authorize('update', $item);
            match ($request->input('action')) {
                'archive' => $item->forceFill(['status' => ContentStatus::Archived->value, 'is_active' => false])->save(),
                'publish', 'toggle-status' => $item->forceFill(['status' => ContentStatus::Published->value, 'is_active' => true, 'published_at' => now()])->save(),
                default => null,
            };
        }));

        app(ContentCacheService::class)->flush();

        return back()->with('status', $items->count().' réalisation(s) traitée(s).');
    }

    private function data(array $data, ?string $action = null): array
    {
        $status = $action === 'publish'
            ? ContentStatus::Published->value
            : ($data['status'] ?? ContentStatus::Draft->value);

        return [
            'title' => $data['title'],
            'media_id' => $data['image'] ?? null,
            'image_alt' => $data['image_alt'] ?? null,
            'category' => $data['category'] ?? null,
            'description' => $data['description'] ?? null,
            'location' => $data['location'] ?? null,
            'completed_at' => $data['completed_at'] ?? null,
            'sort_order' => $data['sort_order'] ?? 0,
            'status' => $status,
            'is_active' => $action === 'publish' || (bool) ($data['is_active'] ?? false),
            'published_at' => $status === ContentStatus::Published->value ? now() : null,
        ];
    }
}
