<?php

declare(strict_types=1);

namespace App\Http\Controllers\Studio;

use App\Http\Controllers\Controller;
use App\Http\Requests\Groups\StoreGroupPostRequest;
use App\Http\Requests\Groups\UpdateGroupPostRequest;
use App\Models\Group;
use App\Models\GroupPost;
use App\Services\GroupPostService;
use App\Services\GroupService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class GroupPostStudioController extends Controller
{
    public function __construct(
        private readonly GroupService $groups,
        private readonly GroupPostService $posts,
    ) {
    }

    public function index(Request $request, Group $group): Response
    {
        $this->authorize('managePosts', $group);

        return Inertia::render('Studio/StudioGroupPosts', [
            'title' => $group->name . ' Posts',
            'description' => 'Publish announcements, releases, recruitment calls, and pinned updates from the group.',
            'studioGroup' => $this->groups->mapGroupDetail($group, $request->user()),
            'listing' => $this->posts->studioListing($group, $request->only(['bucket', 'page', 'per_page'])),
            'recentHistory' => $this->groups->recentHistory($group),
            'createUrl' => route('studio.groups.posts.create', ['group' => $group]),
        ]);
    }

    public function create(Request $request, Group $group): Response
    {
        $this->authorize('managePosts', $group);

        return Inertia::render('Studio/StudioGroupPostEditor', [
            'title' => 'Create post',
            'description' => 'Draft a new public announcement for the group.',
            'studioGroup' => $this->groups->mapGroupDetail($group, $request->user()),
            'post' => null,
            'typeOptions' => $this->typeOptions(),
            'storeUrl' => route('studio.groups.posts.store', ['group' => $group]),
        ]);
    }

    public function store(StoreGroupPostRequest $request, Group $group): RedirectResponse
    {
        $this->authorize('managePosts', $group);

        $post = $this->posts->create($group, $request->user(), $request->validated());

        return redirect()->route('studio.groups.posts.edit', ['group' => $group, 'post' => $post])
            ->with('success', 'Draft created.');
    }

    public function edit(Request $request, Group $group, GroupPost $post): Response
    {
        $this->authorize('managePosts', $group);
        abort_unless((int) $post->group_id === (int) $group->id, 404);

        return Inertia::render('Studio/StudioGroupPostEditor', [
            'title' => 'Edit post',
            'description' => 'Update copy, publish state, and pinned status for this group post.',
            'studioGroup' => $this->groups->mapGroupDetail($group, $request->user()),
            'post' => $this->posts->mapStudioPost($group, $post),
            'typeOptions' => $this->typeOptions(),
            'storeUrl' => null,
            'updateUrl' => route('studio.groups.posts.update', ['group' => $group, 'post' => $post]),
            'publishUrl' => route('studio.groups.posts.publish', ['group' => $group, 'post' => $post]),
            'pinUrl' => route('studio.groups.posts.pin', ['group' => $group, 'post' => $post]),
            'archiveUrl' => route('studio.groups.posts.archive', ['group' => $group, 'post' => $post]),
        ]);
    }

    public function update(UpdateGroupPostRequest $request, Group $group, GroupPost $post): RedirectResponse
    {
        $this->authorize('managePosts', $group);
        abort_unless((int) $post->group_id === (int) $group->id, 404);

        $this->posts->update($post, $request->user(), $request->validated());

        return back()->with('success', 'Post updated.');
    }

    public function publish(Request $request, Group $group, GroupPost $post): RedirectResponse
    {
        $this->authorize('publishPosts', $group);
        abort_unless((int) $post->group_id === (int) $group->id, 404);

        $this->posts->publish($post, $request->user());

        return back()->with('success', 'Post published.');
    }

    public function pin(Request $request, Group $group, GroupPost $post): RedirectResponse
    {
        $this->authorize('pinPosts', $group);
        abort_unless((int) $post->group_id === (int) $group->id, 404);

        $this->posts->pin($post, $request->user(), ! $post->is_pinned);

        return back()->with('success', $post->is_pinned ? 'Post unpinned.' : 'Post pinned.');
    }

    public function archive(Request $request, Group $group, GroupPost $post): RedirectResponse
    {
        $this->authorize('managePosts', $group);
        abort_unless((int) $post->group_id === (int) $group->id, 404);

        $this->posts->archive($post, $request->user());

        return back()->with('success', 'Post archived.');
    }

    private function typeOptions(): array
    {
        return [
            ['value' => GroupPost::TYPE_ANNOUNCEMENT, 'label' => 'Announcement'],
            ['value' => GroupPost::TYPE_RELEASE, 'label' => 'Release'],
            ['value' => GroupPost::TYPE_RECRUITMENT, 'label' => 'Recruitment'],
            ['value' => GroupPost::TYPE_UPDATE, 'label' => 'Update'],
        ];
    }
}