<?php

declare(strict_types=1);

namespace App\Http\Controllers\Barangay;

use App\Enums\UserActions;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Http\Controllers\Helpers\ResponseHelper;
use App\Models\Barangay\Household;
use App\Models\Barangay\HouseholdMember;
use App\Models\Barangay\Resident;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
use Hypervel\Support\Facades\Validator;

class HouseholdController
{
    private function checkRead(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ViewResidents);
    }

    private function checkWrite(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ManageResidents);
    }

    public function index(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $query = Household::with(['head', 'members.resident'])->orderByDesc('id');

        if ($purok = $request->input('purok')) $query->where('purok', $purok);
        if ($request->input('active_only')) $query->active();

        $households = $query->paginate((int) $request->input('per_page', 20));

        return response()->json(['success' => true, 'data' => $households]);
    }

    public function show(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $household = Household::with(['head', 'members.resident'])
            ->where('hashkey', $request->input('target'))
            ->first();

        if (!$household) return ResponseHelper::returnError('Household not found', 404);

        return response()->json(['success' => true, 'data' => $household]);
    }

    public function store(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'head_resident_id' => 'required|integer|exists:barangay_residents,id',
            'address'          => 'required|string|max:500',
            'purok'            => 'nullable|string|max:100',
            'barangay'         => 'nullable|string|max:100',
            'city'             => 'nullable|string|max:100',
            'province'         => 'nullable|string|max:100',
            'ownership_type'   => 'nullable|in:OWNED,RENTED,SHARED',
            'monthly_rental'   => 'nullable|numeric|min:0',
            'has_electricity'  => 'nullable|boolean',
            'has_water'        => 'nullable|boolean',
            'housing_material' => 'nullable|string|max:100',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        $data = $validator->validated();
        $year = date('Y');
        $count = Household::whereYear('created_at', $year)->count() + 1;
        $data['household_no'] = sprintf('HH-%s-%04d', $year, $count);
        $data['hashkey'] = hash('sha256', uniqid((string) now(), true));
        $data['member_count'] = 1;
        $data['is_active'] = true;
        $data['created_by'] = Auth::id();
        $data['updated_by'] = Auth::id();

        $household = Household::create($data);

        // Add head as first member
        HouseholdMember::create([
            'household_id'         => $household->id,
            'resident_id'          => $data['head_resident_id'],
            'relationship_to_head' => 'HEAD',
            'is_active'            => true,
        ]);

        return response()->json(['success' => true, 'data' => $household, 'message' => 'Household created']);
    }

    public function addMember(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'target'               => 'required|string',
            'resident_id'          => 'required|integer|exists:barangay_residents,id',
            'relationship_to_head' => 'required|string|max:100',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        $household = Household::where('hashkey', $request->input('target'))->first();
        if (!$household) return ResponseHelper::returnError('Household not found', 404);

        $existing = HouseholdMember::where('household_id', $household->id)
            ->where('resident_id', $request->input('resident_id'))
            ->first();
        if ($existing) return ResponseHelper::returnError('Resident is already a member', 422);

        $member = HouseholdMember::create([
            'household_id'         => $household->id,
            'resident_id'          => $request->input('resident_id'),
            'relationship_to_head' => $request->input('relationship_to_head'),
            'is_active'            => true,
        ]);

        $household->increment('member_count');

        return response()->json(['success' => true, 'data' => $member, 'message' => 'Member added']);
    }

    public function removeMember(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $household = Household::where('hashkey', $request->input('target'))->first();
        if (!$household) return ResponseHelper::returnError('Household not found', 404);

        $deleted = HouseholdMember::where('household_id', $household->id)
            ->where('resident_id', $request->input('resident_id'))
            ->delete();

        if ($deleted) $household->decrement('member_count');

        return response()->json(['success' => true, 'message' => 'Member removed']);
    }

    public function update(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $household = Household::where('hashkey', $request->input('target'))->first();
        if (!$household) return ResponseHelper::returnError('Household not found', 404);

        $data = $request->except(['target', 'hashkey', 'household_no', 'created_by']);
        $data['updated_by'] = Auth::id();
        $household->update($data);

        return response()->json(['success' => true, 'data' => $household, 'message' => 'Household updated']);
    }
}
