<?php

namespace App\Controllers\Api;

use App\Libraries\AuditLogger;
use App\Libraries\ResponseHelper;
use App\Libraries\UuidHelper;
use App\Models\FamilyMemberModel;
use App\Models\FamilyUnitModel;
use App\Models\MemberModel;

class FamilyController extends BaseApiController
{
    private FamilyUnitModel $model;

    public function initController(
        \CodeIgniter\HTTP\RequestInterface $request,
        \CodeIgniter\HTTP\ResponseInterface $response,
        \Psr\Log\LoggerInterface $logger
    ): void {
        parent::initController($request, $response, $logger);
        $this->model = $this->scopedModel(new FamilyUnitModel());
    }

    public function index()
    {
        if ($err = $this->requirePermission('view_families')) return $err;

        $db = \Config\Database::connect();
        $perPage = $this->getPerPage();
        $page    = (int) ($this->request->getGet('page') ?? 1);
        $offset  = ($page - 1) * $perPage;

        $total = $db->table('family_units')
                    ->where('church_id', $this->churchId())
                    ->where('deleted_at IS NULL')
                    ->countAllResults();

        $families = $db->table('family_units')
                       ->where('church_id', $this->churchId())
                       ->where('deleted_at IS NULL')
                       ->limit($perPage, $offset)
                       ->get()->getResultArray();

        $fmModel = new FamilyMemberModel();
        $mmModel = $this->scopedModel(new MemberModel());

        foreach ($families as &$fam) {
            $fmRows = $fmModel->where('family_unit_id', $fam['id'])->findAll();
            $fam['member_count'] = count($fmRows);
            $names = [];
            foreach ($fmRows as $fm) {
                if ($fm['member_id']) {
                    $m = $mmModel->find($fm['member_id']);
                    if ($m) $names[] = $m['first_name'] . ' ' . $m['last_name'];
                } else {
                    $names[] = ($fm['first_name'] ?? '') . ' ' . ($fm['last_name'] ?? '');
                }
            }
            $fam['member_names'] = $names;
        }

        return ResponseHelper::paginated([
            'data' => array_map([$this, 'format'], $families),
            'meta' => [
                'total'        => $total,
                'per_page'     => $perPage,
                'current_page' => $page,
                'last_page'    => (int) ceil($total / $perPage),
            ],
        ]);
    }

    public function create()
    {
        if ($err = $this->requirePermission('manage_families')) return $err;

        $data = $this->getJson();
        $v    = service('validation');
        $v->setRules(['name' => 'required|min_length[2]']);

        if (!$v->run($data)) {
            return ResponseHelper::validationError($v->getErrors());
        }

        $headId = null;
        if (!empty($data['head_member_uuid'])) {
            $head = $this->scopedModel(new MemberModel())->findByUuid($data['head_member_uuid']);
            if (!$head) return ResponseHelper::notFound('Head member not found');
            $headId = $head['id'];
        }

        $uuid = UuidHelper::generate();
        $this->model->insert([
            'uuid'           => $uuid,
            'church_id'      => $this->churchId(),
            'name'           => $data['name'],
            'head_member_id' => $headId,
        ]);

        $family = $this->model->findByUuid($uuid);
        AuditLogger::log('family.created', 'family_units', $uuid, null, $family);

        return ResponseHelper::created($this->format($family));
    }

    public function show(string $uuid)
    {
        if ($err = $this->requirePermission('view_families')) return $err;

        $family = $this->model->findByUuid($uuid);
        if (!$family) return ResponseHelper::notFound();

        $fmModel = new FamilyMemberModel();
        $members = $fmModel->where('family_unit_id', $family['id'])->findAll();
        $family['members'] = $members;

        return ResponseHelper::success($this->format($family));
    }

    public function update(string $uuid)
    {
        if ($err = $this->requirePermission('manage_families')) return $err;

        $family = $this->model->findByUuid($uuid);
        if (!$family) return ResponseHelper::notFound();

        $data    = $this->getJson();
        $allowed = ['name'];
        $update  = array_intersect_key($data, array_flip($allowed));

        if (!empty($data['head_member_uuid'])) {
            $head = $this->scopedModel(new MemberModel())->findByUuid($data['head_member_uuid']);
            if (!$head) return ResponseHelper::notFound('Head member not found');
            $update['head_member_id'] = $head['id'];
        }

        $old = $family;
        $this->model->update($family['id'], $update);
        $new = $this->model->findByUuid($uuid);

        AuditLogger::log('family.updated', 'family_units', $uuid, $old, $new);

        return ResponseHelper::success($this->format($new));
    }

    public function delete(string $uuid)
    {
        if ($err = $this->requirePermission('manage_families')) return $err;

        $family = $this->model->findByUuid($uuid);
        if (!$family) return ResponseHelper::notFound();

        $this->model->delete($family['id']);
        AuditLogger::log('family.deleted', 'family_units', $uuid, $family, null);

        return ResponseHelper::success(null);
    }

    public function addMember(string $uuid)
    {
        if ($err = $this->requirePermission('manage_families')) return $err;

        $family = $this->model->findByUuid($uuid);
        if (!$family) return ResponseHelper::notFound();

        $data    = $this->getJson();
        $fmModel = new FamilyMemberModel();
        $row     = ['family_unit_id' => $family['id'], 'relationship' => $data['relationship'] ?? null];

        if (!empty($data['member_uuid'])) {
            $member = $this->scopedModel(new MemberModel())->findByUuid($data['member_uuid']);
            if (!$member) return ResponseHelper::notFound('Member not found');
            $row['member_id']          = $member['id'];
            $row['is_registered_member'] = 1;
        } else {
            $row['first_name']           = $data['first_name'] ?? null;
            $row['last_name']            = $data['last_name'] ?? null;
            $row['date_of_birth']        = $data['date_of_birth'] ?? null;
            $row['gender']               = $data['gender'] ?? null;
            $row['is_registered_member'] = 0;
        }

        $fmModel->insert($row);

        AuditLogger::log('family.member_added', 'family_members', $uuid, null, $row);

        return ResponseHelper::created(['message' => 'Member added to family']);
    }

    public function removeMember(string $uuid, string $memberUuid)
    {
        if ($err = $this->requirePermission('manage_families')) return $err;

        $family = $this->model->findByUuid($uuid);
        if (!$family) return ResponseHelper::notFound();

        $memberModel = $this->scopedModel(new MemberModel());
        $member      = $memberModel->findByUuid($memberUuid);

        if (!$member) return ResponseHelper::notFound('Member not found');

        $fmModel = new FamilyMemberModel();
        $fmModel->where('family_unit_id', $family['id'])
                ->where('member_id', $member['id'])
                ->delete();

        AuditLogger::log('family.member_removed', 'family_members', $uuid, ['member_uuid' => $memberUuid], null);

        return ResponseHelper::success(null);
    }

    private function format(array $f): array
    {
        return [
            'uuid'           => $f['uuid'],
            'name'           => $f['name'],
            'head_member_id' => $f['head_member_id'],
            'member_count'   => $f['member_count'] ?? null,
            'member_names'   => $f['member_names'] ?? [],
            'members'        => $f['members'] ?? [],
            'created_at'     => $f['created_at'],
        ];
    }
}
