<?php

namespace App\Controllers\Api;

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

class MemberController extends BaseApiController
{
    private MemberModel $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 MemberModel());
    }

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

        return ResponseHelper::success(
            (new MemberModel())->getStats($this->churchId())
        );
    }

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

        $isActive  = $this->request->getGet('is_active');
        $isCommittee = $this->request->getGet('is_committee');
        $type      = $this->request->getGet('membership_type');
        $search    = $this->request->getGet('search');

        if ($isActive !== null) {
            $this->model->where('is_active', (int) $isActive);
        }
        if ($isCommittee !== null) {
            $this->model->where('is_committee', (int) $isCommittee);
        }
        if ($type) {
            $this->model->where('membership_type', $type);
        }
        if ($search) {
            $s = $this->model->db->escapeLikeString($search);
            $this->model->groupStart()
                         ->like('first_name', $s)
                         ->orLike('last_name', $s)
                         ->orLike('email', $s)
                         ->groupEnd();
        }

        $result          = $this->model->scopedPaginate($this->getPerPage());
        $result['data']  = array_map([$this, 'format'], $result['data']);

        return ResponseHelper::paginated($result);
    }

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

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

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

        $uuid = UuidHelper::generate();
        $this->model->insert(array_merge(
            array_intersect_key($data, array_flip([
                'user_id', 'first_name', 'last_name', 'email', 'phone', 'address',
                'date_of_birth', 'gender', 'marital_status', 'membership_type',
                'membership_date', 'is_active', 'is_committee', 'occupation', 'notes',
            ])),
            ['uuid' => $uuid, 'church_id' => $this->churchId()]
        ));

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

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

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

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

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

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

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

        $data    = $this->getJson();
        $allowed = [
            'first_name', 'last_name', 'email', 'phone', 'address', 'date_of_birth',
            'gender', 'marital_status', 'membership_type', 'membership_date',
            'is_active', 'is_committee', 'occupation', 'notes',
        ];
        $update = array_intersect_key($data, array_flip($allowed));

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

        AuditLogger::log('member.updated', 'members', $uuid, $old, $new);

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

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

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

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

        return ResponseHelper::success(null);
    }

    private function format(array $m): array
    {
        return [
            'uuid'            => $m['uuid'],
            'first_name'      => $m['first_name'],
            'last_name'       => $m['last_name'],
            'email'           => $m['email'],
            'phone'           => $m['phone'],
            'address'         => $m['address'],
            'date_of_birth'   => $m['date_of_birth'],
            'gender'          => $m['gender'],
            'marital_status'  => $m['marital_status'],
            'membership_type' => $m['membership_type'],
            'membership_date' => $m['membership_date'],
            'is_active'       => (bool) $m['is_active'],
            'is_committee'    => (bool) $m['is_committee'],
            'occupation'      => $m['occupation'],
            'notes'           => $m['notes'],
            'created_at'      => $m['created_at'],
        ];
    }
}
