<?php
namespace App\Controllers;

use App\Repositories\LookupRepository;
use App\Services\AuthService;
use App\Utils\Sanitizer;

class LookupController extends ApiController
{
    private LookupRepository $lookupRepo;
    private AuthService $auth;

    public function __construct(LookupRepository $lookupRepo, AuthService $auth)
    {
        $this->lookupRepo = $lookupRepo;
        $this->auth = $auth;
    }

    private function requireCapability(string $capabilityKey): void
    {
        if (!$this->auth->isAuthenticated()) {
            $this->errorResponse('Access denied', 403);
        }
        if (($_SESSION['role'] ?? '') === 'admin') {
            return;
        }
        global $app;
        if (isset($app->services->rbac) && $app->services->rbac && $app->services->rbac->can($capabilityKey)) {
            return;
        }
        $this->errorResponse('Access denied', 403);
    }

    public function getLookups(): void
    {
        $group = Sanitizer::sanitize($_REQUEST['group'] ?? '');
        $includeInactive = isset($_REQUEST['include_inactive']) && $_REQUEST['include_inactive'] === '1';
        $sessionDidarId = trim((string)($_SESSION['didar_id'] ?? ''));

        if ($group !== '') {
            $items = $this->lookupRepo->getItemsByGroupCode($group, $includeInactive);
            if (!$includeInactive && $group === 'pipeline_stages' && $sessionDidarId !== '') {
                $items = $this->lookupRepo->filterItemsForDidarUser($items, $sessionDidarId);
            }
            $this->successResponse(['group' => $group, 'items' => $items]);
            return;
        }

        $lookups = $this->lookupRepo->getAllLookups($includeInactive);
        if (!$includeInactive && $sessionDidarId !== '' && isset($lookups['pipeline_stages']['items'])) {
            $lookups['pipeline_stages']['items'] = $this->lookupRepo->filterItemsForDidarUser(
                (array)$lookups['pipeline_stages']['items'],
                $sessionDidarId
            );
        }
        $this->successResponse(['lookups' => $lookups]);
    }

    public function getGroups(): void
    {
        $this->requireCapability('lookups.view');
        $includeInactive = isset($_REQUEST['include_inactive']) && $_REQUEST['include_inactive'] === '1';
        $groups = $this->lookupRepo->getGroups($includeInactive);
        $this->successResponse(['groups' => $groups]);
    }

    public function getItems(): void
    {
        $this->requireCapability('lookups.view');
        $group = Sanitizer::sanitize($_REQUEST['group'] ?? '');
        if ($group === '') {
            $this->errorResponse('Missing group code');
        }
        $items = $this->lookupRepo->getItemsByGroupCode($group, true);
        $this->successResponse(['group' => $group, 'items' => $items]);
    }

    public function saveGroup(): void
    {
        $this->requireCapability((int)($_POST['id'] ?? 0) > 0 ? 'lookups.edit' : 'lookups.create');
        $data = [
            'id' => Sanitizer::sanitize($_POST['id'] ?? ''),
            'code' => Sanitizer::sanitize($_POST['code'] ?? ''),
            'title' => Sanitizer::sanitize($_POST['title'] ?? ''),
            'description' => Sanitizer::sanitize($_POST['description'] ?? ''),
            'sort_order' => Sanitizer::sanitize($_POST['sort_order'] ?? 0),
            'is_active' => isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1
        ];
        if (empty($data['code']) || empty($data['title'])) {
            $this->errorResponse('Missing code or title');
        }
        $id = $this->lookupRepo->saveGroup($data);
        $this->successResponse(['id' => $id]);
    }

    public function saveItem(): void
    {
        $this->requireCapability((int)($_POST['id'] ?? 0) > 0 ? 'lookups.edit' : 'lookups.create');
        $groupCode = Sanitizer::sanitize($_POST['group_code'] ?? '');
        $groupId = (int)($_POST['group_id'] ?? 0);
        if ($groupId <= 0 && $groupCode !== '') {
            $group = $this->lookupRepo->getGroupByCode($groupCode);
            $groupId = $group ? (int)$group['id'] : 0;
        }
        if ($groupId <= 0) {
            $this->errorResponse('Missing group');
        }

        $parentValue = Sanitizer::sanitize($_POST['parent_value'] ?? '');
        $parentId = isset($_POST['parent_id']) ? (int)$_POST['parent_id'] : null;
        if (!$parentId && $parentValue !== '') {
            $parent = $this->findItemByValue($groupId, $parentValue);
            $parentId = $parent ? (int)$parent['id'] : null;
        }

        $metaJson = $_POST['meta_json'] ?? null;
        $data = [
            'id' => Sanitizer::sanitize($_POST['id'] ?? ''),
            'group_id' => $groupId,
            'parent_id' => $parentId,
            'code' => Sanitizer::sanitize($_POST['code'] ?? ''),
            'title' => Sanitizer::sanitize($_POST['title'] ?? ''),
            'value' => Sanitizer::sanitize($_POST['value'] ?? ''),
            'meta_json' => $metaJson,
            'sort_order' => Sanitizer::sanitize($_POST['sort_order'] ?? 0),
            'is_active' => isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1,
            'is_visible' => isset($_POST['is_visible']) ? (int)$_POST['is_visible'] : 1
        ];
        if (empty($data['title'])) {
            $this->errorResponse('Missing title');
        }
        $id = $this->lookupRepo->saveItem($data);
        $this->successResponse(['id' => $id]);
    }

    public function deleteItem(): void
    {
        $this->requireCapability('lookups.delete');
        $id = (int)($_POST['id'] ?? 0);
        if ($id <= 0) {
            $this->errorResponse('Missing id');
        }
        $this->lookupRepo->deleteItem($id);
        $this->successResponse();
    }

    public function deleteGroup(): void
    {
        $this->requireCapability('lookups.delete');
        $id = (int)($_POST['id'] ?? 0);
        if ($id <= 0) {
            $this->errorResponse('Missing id');
        }
        $this->lookupRepo->deleteGroup($id);
        $this->successResponse();
    }

    private function findItemByValue(int $groupId, string $value): ?array
    {
        $items = $this->lookupRepo->getItemsByGroupId($groupId, true);
        foreach ($items as $item) {
            $val = $item['value'] !== null && $item['value'] !== '' ? $item['value'] : $item['title'];
            if ($val === $value) {
                return $item;
            }
        }
        return null;
    }
}
