<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

abstract class BaseController extends Controller
{
    protected $helpers = ['url','form','text'];

    protected int   $companyId  = 0;
    protected int   $userId     = 0;
    protected array $user       = [];
    protected array $permissions= [];
    protected array $settings   = [];

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);

        if (session()->get('user_id')) {
            $this->companyId   = (int)session()->get('company_id');
            $this->userId      = (int)session()->get('user_id');
            $this->user        = session()->get('user') ?? [];
            $this->permissions = session()->get('permissions') ?? [];
            $this->settings    = session()->get('settings') ?? [];
        }
    }

    protected function can(string $permission): bool
    {
        return in_array($permission, $this->permissions, true);
    }

    protected function requirePermission(string $permission): mixed
    {
        if (!$this->can($permission)) {
            if ($this->request->isAJAX()) {
                die(json_encode(['success'=>false,'message'=>'Permission denied']));
            }
            return redirect()->to('/fieldly/public/index.php/dashboard')->with('error', 'You do not have permission to do that.');
        }
        return null;
    }

    protected function view(string $view, array $data = []): string
    {
        $perms = $this->permissions;

        $data['currentUser']  = $this->user;
        $data['permissions']  = $perms;
        $data['settings']     = $this->settings;
        $data['companyId']    = $this->companyId;
        $data['can']          = function(string $p) use ($perms): bool {
            return in_array($p, $perms, true);
        };

        return \Config\Services::renderer()->setData($data)->render($view);
    }

    protected function nextNumber(string $prefixKey, string $nextKey): string
    {
        $m      = model('CompanySettingModel');
        $prefix = $m->getSetting($this->companyId, 'numbering', $prefixKey) ?? '';
        $next   = (int)($m->getSetting($this->companyId, 'numbering', $nextKey) ?? 1);
        $m->saveSetting($this->companyId, 'numbering', $nextKey, $next + 1);
        return $prefix . str_pad($next, config('Fieldly')->numberPadding, '0', STR_PAD_LEFT);
    }

    protected function log(string $type, string $entityType, int $entityId, string $desc, array $meta = []): void
    {
        model('ActivityLogModel')->insert([
            'company_id'  => $this->companyId,
            'type'        => $type,
            'entity_type' => $entityType,
            'entity_id'   => $entityId,
            'user_id'     => $this->userId,
            'user_name'   => ($this->user['first_name']??'').' '.($this->user['last_name']??''),
            'description' => $desc,
            'meta'        => $meta ? json_encode($meta) : null,
            'ip_address'  => $this->request->getIPAddress(),
        ]);
    }

    protected function softDelete(string $modelName, int $id, string $entityType, string $summary): bool
    {
        $model  = model($modelName);
        $record = $model->find($id);
        if (!$record || (int)($record['company_id']??0) !== $this->companyId) return false;

        model('DeletedItemModel')->insert([
            'company_id'     => $this->companyId,
            'entity_type'    => $entityType,
            'entity_id'      => $id,
            'entity_ref'     => $record['number'] ?? null,
            'entity_summary' => $summary,
            'snapshot_json'  => json_encode($record),
            'deleted_by'     => $this->userId,
        ]);
        db_connect()->table($model->table)->where('id', $id)->update(['deleted_at' => date('Y-m-d H:i:s')]);
        return true;
    }

    protected function jsonResponse(mixed $data = null, string $message = 'OK', int $status = 200): ResponseInterface
    {
        return $this->response->setStatusCode($status)->setJSON(['success' => $status < 400, 'message' => $message, 'data' => $data]);
    }

    protected function saveCustomFields(string $entityType, int $entityId, array $fields): void
    {
        if (!$fields) return;
        $m = model('CustomFieldValueModel');
        foreach ($fields as $fieldDefId => $value) {
            $m->upsert($this->companyId, $entityType, $entityId, (int)$fieldDefId, $value);
        }
    }
}