<?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\StorePartnerRequest;
use App\Http\Requests\Admin\UpdatePartnerRequest;
use App\Models\Partner;
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 PartnerController extends Controller
{
    public function index(): View
    {
        Gate::authorize('viewAny', Partner::class);

        $query = Partner::query()->with('media')->ordered();
        if ($search = request('q')) {
            $query->where('name', 'like', "%{$search}%");
        }
        if ($status = request('status')) {
            $query->where('status', $status);
        }

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

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

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

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

        $partner = Partner::create($this->data($request->validated(), $request->input('_action')) + ['created_by' => auth()->id(), 'updated_by' => auth()->id()]);
        if ($request->input('_action') === 'publish') {
            Gate::authorize('publish', $partner);
        }
        app(ContentCacheService::class)->flush();
        $logger->log('partner.created', $partner, "Partenaire créé: {$partner->name}");

        return redirect()->route('admin.partners.edit', $partner)->with('status', 'Partenaire créé.');
    }

    public function edit(Partner $partner): View
    {
        Gate::authorize('update', $partner);

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

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

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

        return back()->with('status', 'Partenaire enregistré.');
    }

    public function toggle(Partner $partner): RedirectResponse
    {
        Gate::authorize('update', $partner);
        $partner->forceFill(['is_active' => ! $partner->is_active])->save();
        app(ContentCacheService::class)->flush();

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

    public function archive(Partner $partner, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('delete', $partner);
        $partner->forceFill(['status' => ContentStatus::Archived->value, 'is_active' => false])->save();
        app(ContentCacheService::class)->flush();
        $logger->log('partner.archived', $partner, "Partenaire archivé: {$partner->name}");

        return back()->with('status', 'Partenaire archivé.');
    }

    public function destroy(Partner $partner, ActivityLogger $logger): RedirectResponse
    {
        Gate::authorize('delete', $partner);
        $partner->delete();
        app(ContentCacheService::class)->flush();
        $logger->log('partner.deleted', $partner, "Partenaire supprimé: {$partner->name}");

        return back()->with('status', 'Partenaire supprimé.');
    }

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

        DB::transaction(fn () => $items->each(function (Partner $partner) use ($request): void {
            Gate::authorize('update', $partner);
            match ($request->input('action')) {
                'archive' => $partner->forceFill(['status' => ContentStatus::Archived->value, 'is_active' => false])->save(),
                'activate' => $partner->forceFill(['is_active' => true])->save(),
                'deactivate' => $partner->forceFill(['is_active' => false])->save(),
                'toggle-status' => $partner->forceFill(['is_active' => ! $partner->is_active])->save(),
                default => null,
            };
        }));

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

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

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

        return [
            'name' => $data['name'],
            'media_id' => $data['logo'] ?? null,
            'logo_alt' => $data['logo_alt'] ?? null,
            'website_url' => $data['website_url'] ?? null,
            'sort_order' => $data['sort_order'] ?? 0,
            'status' => $status,
            'is_active' => $action === 'publish' || (bool) ($data['is_active'] ?? false),
        ];
    }
}
