<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Content;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class ContentController extends Controller
{
    public function index(Request $request): View
    {
        $type = $request->query('type');

        $query = Content::query()->ordered();
        if (is_string($type) && $type !== '' && array_key_exists($type, Content::types())) {
            $query->ofType($type);
        }

        return view('admin.contents.index', [
            'contents' => $query->simplePaginate(30)->withQueryString(),
            'types' => Content::types(),
            'filterType' => $type,
        ]);
    }

    public function create(Request $request): View
    {
        $type = $request->query('type', Content::TYPE_BLOG);
        if (! array_key_exists($type, Content::types())) {
            $type = Content::TYPE_BLOG;
        }

        return view('admin.contents.create', [
            'content' => new Content(['type' => $type, 'is_published' => false]),
            'types' => Content::types(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $data = $this->validated($request);
        $data['is_published'] = $request->boolean('is_published');
        if (empty($data['sort_order'])) {
            $data['sort_order'] = 0;
        }
        $data['published_at'] = ! empty($data['published_at']) ? $data['published_at'] : null;
        $data['slug'] = isset($data['slug']) && trim((string) $data['slug']) !== '' ? $data['slug'] : null;

        Content::query()->create($data);

        return redirect()->route('admin.contents.index', ['type' => $data['type']])->with('ok', 'Contenu cree.');
    }

    public function edit(Content $content): View
    {
        return view('admin.contents.edit', [
            'content' => $content,
            'types' => Content::types(),
        ]);
    }

    public function update(Request $request, Content $content): RedirectResponse
    {
        $data = $this->validated($request, $content->id);
        $data['is_published'] = $request->boolean('is_published');
        if (! isset($data['sort_order']) || $data['sort_order'] === null) {
            $data['sort_order'] = 0;
        }
        $data['published_at'] = ! empty($data['published_at']) ? $data['published_at'] : null;
        $data['slug'] = isset($data['slug']) && trim((string) $data['slug']) !== '' ? $data['slug'] : null;

        $content->update($data);

        return redirect()->route('admin.contents.index', ['type' => $data['type']])->with('ok', 'Contenu mis a jour.');
    }

    public function destroy(Content $content): RedirectResponse
    {
        $type = $content->type;
        $content->delete();

        return redirect()->route('admin.contents.index', ['type' => $type])->with('ok', 'Contenu supprime.');
    }

    /**
     * @return array<string, mixed>
     */
    private function validated(Request $request, ?int $id = null): array
    {
        $types = implode(',', array_keys(Content::types()));

        return $request->validate([
            'type' => ['required', Rule::in(array_keys(Content::types()))],
            'title' => ['required', 'string', 'max:255'],
            'slug' => [
                'nullable',
                'string',
                'max:255',
                Rule::unique('contents', 'slug')->ignore($id),
            ],
            'excerpt' => ['nullable', 'string'],
            'body' => ['nullable', 'string'],
            'meta_title' => ['nullable', 'string', 'max:255'],
            'meta_description' => ['nullable', 'string', 'max:512'],
            'tag' => ['nullable', 'string', 'max:120'],
            'cta_label' => ['nullable', 'string', 'max:120'],
            'cta_url' => ['nullable', 'string', 'max:2048'],
            'sort_order' => ['nullable', 'integer', 'min:0', 'max:9999'],
            'published_at' => ['nullable', 'date'],
        ]);
    }
}
