<?php

namespace App\Http\Controllers;

use App\Models\Family;
use App\Models\Relationship;
use App\Services\ActivityLogger;
use App\Services\RelationshipService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class RelationshipController extends Controller
{
    private RelationshipService $relationships;
    private ActivityLogger $activityLogger;

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

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

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

        $relationships = $this->relationships->listForFamily($family, $perPage);

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

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

        $data = $request->validate([
            'person_id' => ['required', 'integer', 'exists:people,id'],
            'related_person_id' => ['required', 'integer', 'different:person_id', 'exists:people,id'],
            'type' => ['required', Rule::in(['parent', 'child', 'spouse', 'sibling', 'guardian', 'ward', 'other'])],
            'start_date' => ['nullable', 'date'],
            'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
            'notes' => ['nullable', 'string'],
        ]);

        $relationship = $this->relationships->create($family, $data);

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

        return response()->json($relationship, 201);
    }

    public function update(Request $request, Family $family, Relationship $relationship)
    {
        $this->authorizeManage($request, $family);

        if ($relationship->family_id !== $family->id) {
            abort(404);
        }

        $data = $request->validate([
            'type' => ['sometimes', Rule::in(['parent', 'child', 'spouse', 'sibling', 'guardian', 'ward', 'other'])],
            'start_date' => ['nullable', 'date'],
            'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
            'notes' => ['nullable', 'string'],
        ]);

        $updated = $this->relationships->update($relationship, $data);

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

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

    public function destroy(Request $request, Family $family, Relationship $relationship)
    {
        $this->authorizeManage($request, $family);

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

        $this->relationships->delete($relationship);

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

        return response()->json(['message' => 'Relationship removed']);
    }

    private function authorizeManage(Request $request, Family $family): void
    {
        $user = $request->user();
        $isOwner = $user && $family->members()
            ->wherePivot('role', 'owner')
            ->where('people.user_id', $user->id)
            ->exists();

        abort_unless($user && ($user->can('relationships.manage') || $isOwner), 403);
    }
}
