<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\AddHouseholdMemberRequest;
use App\Http\Requests\StoreHouseholdRequest;
use App\Http\Requests\UpdateHouseholdRequest;
use App\Http\Resources\HouseholdResource;
use App\Http\Resources\HouseholdRowResource;
use App\Models\Household;
use App\Models\Member;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class HouseholdController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $query = Household::visibleTo($request->user())
            ->with('branch:id,name,code')
            ->withCount('members')
            ->orderBy('name');

        if ($request->filled('branch_id')) {
            $query->where('branch_id', $request->integer('branch_id'));
        }

        if ($request->filled('q')) {
            $query->where('name', 'like', $request->string('q').'%');
        }

        $perPage = (int) ($request->integer('per_page') ?: 25);
        $households = $query->cursorPaginate($perPage)->withQueryString();

        return HouseholdRowResource::collection($households)->response();
    }

    public function store(StoreHouseholdRequest $request): JsonResponse
    {
        $household = Household::create($request->validated());

        return (new HouseholdResource($household->load('branch')))
            ->response()
            ->setStatusCode(201);
    }

    public function show(Household $household): HouseholdResource
    {
        $this->authorize('view', $household);

        $household->load(['branch', 'headMember', 'members' => fn ($q) => $q->orderBy('first_name')]);

        return new HouseholdResource($household);
    }

    public function update(UpdateHouseholdRequest $request, Household $household): HouseholdResource
    {
        $household->update($request->validated());

        return new HouseholdResource($household->load(['branch', 'headMember', 'members']));
    }

    public function destroy(Household $household): JsonResponse
    {
        $this->authorize('delete', $household);

        foreach ($household->members()->get() as $member) {
            $member->update(['household_id' => null, 'household_role' => null]);
        }

        $household->delete();

        return response()->json(null, 204);
    }

    public function addMember(AddHouseholdMemberRequest $request, Household $household): HouseholdResource
    {
        $member = Member::visibleTo($request->user())->findOrFail($request->input('member_id'));

        $member->update([
            'household_id' => $household->id,
            'household_role' => $request->input('household_role'),
        ]);

        return new HouseholdResource($household->fresh(['branch', 'headMember', 'members']));
    }

    public function removeMember(Request $request, Household $household, Member $member): HouseholdResource
    {
        $this->authorize('update', $household);

        if ((int) $member->household_id !== (int) $household->id) {
            abort(404);
        }

        $member->update(['household_id' => null, 'household_role' => null]);

        if ((int) $household->head_member_id === (int) $member->id) {
            $household->update(['head_member_id' => null]);
        }

        return new HouseholdResource($household->fresh(['branch', 'headMember', 'members']));
    }
}
