<?php

namespace App\Controllers\Api;

use App\Libraries\AuditLogger;
use App\Libraries\ResponseHelper;
use App\Libraries\UuidHelper;
use App\Models\PrayerRequestModel;
use App\Models\PrayerResponseModel;

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

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

        $user    = $this->currentUser();
        $canMgr  = \App\Libraries\PermissionService::has('manage_prayer');

        if (!$canMgr) {
            // Regular users: see public requests + their own private ones
            $this->model->groupStart()
                         ->where('is_public', 1)
                         ->orWhere('user_id', $user['id'])
                         ->groupEnd();
        }

        $result         = $this->model->scopedPaginate($this->getPerPage());
        $result['data'] = array_map(fn($r) => $this->format($r, $canMgr, $user['id']), $result['data']);

        return ResponseHelper::paginated($result);
    }

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

        $data = $this->getJson();
        $v    = service('validation');
        $v->setRules(['title' => 'required|min_length[3]', 'body' => '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(),
            'user_id'      => $user['id'],
            'title'        => $data['title'],
            'body'         => $data['body'],
            'is_public'    => (int) ($data['is_public'] ?? 1),
            'is_anonymous' => (int) ($data['is_anonymous'] ?? 0),
            'status'       => 'pending',
        ]);

        $pr = $this->model->findByUuid($uuid);
        AuditLogger::log('prayer.created', 'prayer_requests', $uuid, null, $pr);

        return ResponseHelper::created($this->format($pr, false, $user['id']));
    }

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

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

        $user   = $this->currentUser();
        $canMgr = \App\Libraries\PermissionService::has('manage_prayer');

        if (!$canMgr && !$pr['is_public'] && $pr['user_id'] != $user['id']) {
            return ResponseHelper::notFound();
        }

        $respModel        = new PrayerResponseModel();
        $pr['responses']  = $respModel->where('prayer_request_id', $pr['id'])->findAll();

        return ResponseHelper::success($this->format($pr, $canMgr, $user['id']));
    }

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

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

        $user   = $this->currentUser();
        $canMgr = \App\Libraries\PermissionService::has('manage_prayer');

        if (!$canMgr && $pr['user_id'] != $user['id']) {
            return ResponseHelper::forbidden();
        }

        $data    = $this->getJson();
        $allowed = ['title', 'body', 'is_public', 'is_anonymous'];
        $update  = array_intersect_key($data, array_flip($allowed));

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

        AuditLogger::log('prayer.updated', 'prayer_requests', $uuid, $old, $new);

        return ResponseHelper::success($this->format($new, $canMgr, $user['id']));
    }

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

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

        $user   = $this->currentUser();
        $canMgr = \App\Libraries\PermissionService::has('manage_prayer');

        if (!$canMgr && $pr['user_id'] != $user['id']) {
            return ResponseHelper::forbidden();
        }

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

        return ResponseHelper::success(null);
    }

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

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

        $data = $this->getJson();
        if (empty($data['response'])) {
            return ResponseHelper::validationError(['response' => 'Response is required']);
        }

        $user      = $this->currentUser();
        $respModel = new PrayerResponseModel();
        $respModel->insert([
            'prayer_request_id' => $pr['id'],
            'user_id'           => $user['id'],
            'response'          => $data['response'],
        ]);

        AuditLogger::log('prayer.responded', 'prayer_responses', $uuid, null, $data);

        return ResponseHelper::created(null);
    }

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

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

        $data   = $this->getJson();
        $status = $data['status'] ?? '';
        $valid  = ['pending', 'acknowledged', 'answered'];

        if (!in_array($status, $valid, true)) {
            return ResponseHelper::validationError(['status' => 'Must be one of: ' . implode(', ', $valid)]);
        }

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

        AuditLogger::log('prayer.status_updated', 'prayer_requests', $uuid, $old, $new);

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

    private function format(array $pr, bool $showUserId, int $currentUserId): array
    {
        $isOwn = ($pr['user_id'] == $currentUserId);
        return [
            'uuid'         => $pr['uuid'],
            'title'        => $pr['title'],
            'body'         => $pr['body'],
            'is_public'    => (bool) $pr['is_public'],
            'is_anonymous' => (bool) $pr['is_anonymous'],
            'status'       => $pr['status'],
            'is_own'       => $isOwn,
            'responses'    => $pr['responses'] ?? [],
            'created_at'   => $pr['created_at'],
        ];
    }
}
