<?php

namespace App\Http\Controllers;

use App\Models\Family;
use App\Models\FamilyWallPost;
use App\Services\ActivityLogger;
use App\Models\User;
use App\Notifications\UserMentionedInPost;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class FamilyWallPostController extends Controller
{
    private ActivityLogger $activityLogger;

    public function __construct(ActivityLogger $activityLogger)
    {
        $this->activityLogger = $activityLogger;
    }

    public function index(Request $request, Family $family)
    {
        $this->authorizeView($request, $family);

        $perPage = (int) $request->integer('per_page', 15);
        $perPage = $perPage > 0 ? min($perPage, 100) : 15;

        $posts = $family->wallPosts()
            ->with(['author', 'comments.author'])
            ->withCount(['comments', 'reactions'])
            ->latest()
            ->paginate($perPage);

        return response()->json($posts);
    }

    public function store(Request $request, Family $family)
    {
        $this->authorizePost($request, $family);

        $data = $request->validate([
            'content' => ['required', 'string'],
            'media' => ['nullable', 'array'],
            'media.*.type' => ['required_with:media', Rule::in(['image', 'video', 'file'])],
            'media.*.url' => ['required_with:media', 'url'],
            'meta' => ['nullable', 'array'],
        ]);

        $post = $family->wallPosts()->create([
            'author_id' => $request->user()->id,
            'content' => $data['content'],
            'media' => $data['media'] ?? null,
            'meta' => $data['meta'] ?? null,
        ]);

        $this->activityLogger->log('wall_post.created', $post, [
            'family_id' => $family->id,
        ], $request, $family->id);

        // Notify mentioned users
        $mentions = (array) data_get($data, 'meta.mentions', []);
        if (!empty($mentions)) {
            $users = User::query()->whereIn('id', $mentions)->get();
            foreach ($users as $u) {
                if ($u->id === $request->user()->id) continue;
                $u->notify(new UserMentionedInPost($post));
            }
        }

        return response()->json($post->load('author'), 201);
    }

    public function show(Request $request, Family $family, FamilyWallPost $wallPost)
    {
        $this->authorizeView($request, $family);
        abort_unless($wallPost->family_id === $family->id, 404);

        $wallPost->load(['author.person', 'family'])
            ->loadCount(['comments', 'reactions']);

        return view('posts.show', [
            'post' => $wallPost,
        ]);
    }

    public function update(Request $request, Family $family, FamilyWallPost $familyWallPost)
    {
        $this->authorizeEdit($request, $family, $familyWallPost);

        $data = $request->validate([
            'content' => ['sometimes', 'string'],
            'media' => ['nullable', 'array'],
            'media.*.type' => ['required_with:media', Rule::in(['image', 'video', 'file'])],
            'media.*.url' => ['required_with:media', 'url'],
            'meta' => ['nullable', 'array'],
        ]);

        $familyWallPost->update($data);

        $this->activityLogger->log('wall_post.updated', $familyWallPost, [
            'family_id' => $family->id,
        ], $request, $family->id);

        return response()->json($familyWallPost->fresh('author'));
    }

    public function destroy(Request $request, Family $family, FamilyWallPost $familyWallPost)
    {
        $this->authorizeEdit($request, $family, $familyWallPost);

        $familyWallPost->delete();

        $this->activityLogger->log('wall_post.deleted', $familyWallPost, [
            'family_id' => $family->id,
        ], $request, $family->id);

        return response()->json(['message' => 'Post deleted']);
    }

    private function authorizeView(Request $request, Family $family): void
    {
        abort_unless($request->user()?->can('families.manage') || $family->members()->where('person_id', optional($request->user()->person)->id)->exists(), 403);
    }

    private function authorizePost(Request $request, Family $family): void
    {
        $user = $request->user();
        $canManage = $user?->can('families.manage');
        $isMember = $family->members()->where('person_id', optional($user->person)->id)->exists();

        abort_unless($canManage || $isMember, 403);
    }

    private function authorizeEdit(Request $request, Family $family, FamilyWallPost $post): void
    {
        $user = $request->user();
        $isOwner = $post->author_id === $user?->id;
        $canManage = $user?->can('families.manage');

        abort_unless($canManage || $isOwner, 403);

        abort_unless($post->family_id === $family->id, 404);
    }
}
