<?php

namespace App\Controllers\Api;

use App\Libraries\AuditLogger;
use App\Libraries\ResponseHelper;
use App\Libraries\UuidHelper;
use App\Models\EventAttendanceModel;
use App\Models\EventModel;

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

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

        $type     = $this->request->getGet('type');
        $audience = $this->request->getGet('audience');
        $month    = $this->request->getGet('month'); // YYYY-MM
        $upcoming = $this->request->getGet('upcoming');
        $past     = $this->request->getGet('past');

        if ($type)     $this->model->where('event_type', $type);
        if ($audience) $this->model->where('audience', $audience);
        if ($month)    $this->model->like('starts_at', $month, 'after');
        if ($upcoming) $this->model->where('starts_at >', date('Y-m-d H:i:s'));
        if ($past)     $this->model->where('ends_at <', date('Y-m-d H:i:s'));

        $this->model->orderBy('starts_at', 'ASC');
        $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('manage_events')) return $err;

        $data = $this->getJson();
        $v    = service('validation');
        $v->setRules([
            'title'      => 'required|min_length[3]',
            'starts_at'  => 'required',
        ]);

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

        $user = $this->currentUser();
        $uuid = UuidHelper::generate();
        $this->model->insert([
            'uuid'               => $uuid,
            'church_id'          => $this->churchId(),
            'title'              => $data['title'],
            'description'        => $data['description'] ?? null,
            'location'           => $data['location'] ?? null,
            'event_type'         => $data['event_type'] ?? 'general',
            'audience'           => $data['audience'] ?? 'all',
            'starts_at'          => $data['starts_at'],
            'ends_at'            => $data['ends_at'] ?? null,
            'is_recurring'       => (int) ($data['is_recurring'] ?? 0),
            'recurrence_rule'    => $data['recurrence_rule'] ?? null,
            'donation_request_id'=> $data['donation_request_id'] ?? null,
            'created_by'         => $user['id'] ?? null,
        ]);

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

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

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

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

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

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

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

        $data    = $this->getJson();
        $allowed = ['title', 'description', 'location', 'event_type', 'audience', 'starts_at', 'ends_at', 'is_recurring', 'recurrence_rule'];
        $update  = array_intersect_key($data, array_flip($allowed));

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

        AuditLogger::log('event.updated', 'events', $uuid, $old, $new);

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

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

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

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

        return ResponseHelper::success(null);
    }

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

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

        $user         = $this->currentUser();
        $attendModel  = new EventAttendanceModel();

        $existing = $attendModel->where('event_id', $event['id'])
                                ->where('user_id', $user['id'])
                                ->first();

        if ($existing) {
            return ResponseHelper::error('Already marked as attending', 409);
        }

        $attendModel->insert([
            'event_id'  => $event['id'],
            'user_id'   => $user['id'],
            'church_id' => $this->churchId(),
            'status'    => 'attending',
        ]);

        return ResponseHelper::created(['message' => 'Attendance marked']);
    }

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

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

        $attendModel = new EventAttendanceModel();
        $records     = $attendModel->where('event_id', $event['id'])->findAll();

        return ResponseHelper::success($records);
    }

    private function format(array $e): array
    {
        return [
            'uuid'             => $e['uuid'],
            'title'            => $e['title'],
            'description'      => $e['description'],
            'location'         => $e['location'],
            'event_type'       => $e['event_type'],
            'audience'         => $e['audience'],
            'starts_at'        => $e['starts_at'],
            'ends_at'          => $e['ends_at'],
            'is_recurring'     => (bool) $e['is_recurring'],
            'recurrence_rule'  => $e['recurrence_rule'],
            'created_at'       => $e['created_at'],
        ];
    }
}
