<?php
namespace App\Controllers;

use App\Repositories\FieldConfigRepository;
use App\Services\FieldPermissionService;
use App\Services\AuthService;
use App\Utils\Sanitizer;

/**
 * Field Configuration Controller
 * Manages field properties through Admin panel
 */
class FieldConfigController extends ApiController
{
    private FieldConfigRepository $fieldConfigRepo;
    private FieldPermissionService $fieldPermService;
    private AuthService $auth;

    public function __construct(
        FieldConfigRepository $fieldConfigRepo,
        FieldPermissionService $fieldPermService,
        AuthService $auth
    ) {
        $this->fieldConfigRepo = $fieldConfigRepo;
        $this->fieldPermService = $fieldPermService;
        $this->auth = $auth;
    }

    /**
     * Admin-only: Get all field configurations
     */
    public function getAll(): void
    {
        $this->requireCapability('field_config.view');

        $includeInactive = isset($_REQUEST['include_inactive']) && $_REQUEST['include_inactive'] === '1';
        $configurations = $this->fieldConfigRepo->getAll($includeInactive);

        $this->successResponse(['configurations' => $configurations]);
    }

    /**
     * Admin-only: Get specific field configuration
     * ✅ Uses field_name (not ID)
     */
    public function getByFieldName(): void
    {
        $this->requireCapability('field_config.view');

        $fieldName = Sanitizer::sanitize($_REQUEST['field_name'] ?? '');
        
        if (empty($fieldName)) {
            $this->errorResponse('Missing field_name parameter');
            return;
        }

        $config = $this->fieldConfigRepo->getByFieldName($fieldName);

        if (!$config) {
            $this->successResponse(['configuration' => null]);
            return;
        }

        $this->successResponse(['configuration' => $config]);
    }

    /**
     * Admin-only: Get configurations by entity type
     */
    public function getByEntity(): void
    {
        $this->requireCapability('field_config.view');

        $entityType = Sanitizer::sanitize($_REQUEST['entity_type'] ?? '');
        
        if (empty($entityType)) {
            $this->errorResponse('Missing entity_type parameter');
            return;
        }

        $includeInactive = isset($_REQUEST['include_inactive']) && $_REQUEST['include_inactive'] === '1';
        $configurations = $this->fieldConfigRepo->getByEntity($entityType, $includeInactive);

        $this->successResponse(['entity_type' => $entityType, 'configurations' => $configurations]);
    }

    /**
     * Auth-required: Get visible configurations for current user and entity type
     * Filters by view permissions and active state
     */
    public function getByEntityPublic(): void
    {
        if (!$this->auth->isAuthenticated()) {
            $this->errorResponse('Not authenticated', 401);
            return;
        }

        $entityType = Sanitizer::sanitize($_REQUEST['entity_type'] ?? '');
        if (empty($entityType)) {
            $this->errorResponse('Missing entity_type parameter');
            return;
        }

        $configs = $this->fieldConfigRepo->getByEntity($entityType, false);
        $active = [];
        foreach ($configs as $config) {
            if (!empty($config['is_active'])) {
                $active[] = $config;
            }
        }

        $this->successResponse(['entity_type' => $entityType, 'configurations' => $active]);
    }

    /**
     * Get editable fields for current user and entity type
     */
    public function getEditableFields(): void
    {
        if (!$this->auth->isAuthenticated()) {
            $this->errorResponse('Not authenticated', 401);
            return;
        }

        $entityType = Sanitizer::sanitize($_REQUEST['entity_type'] ?? 'deal');
        $userRole = $_SESSION['role'] ?? 'agent';

        $editableFields = $this->fieldPermService->getEditableFieldsForEntity($entityType, $userRole);

        $this->successResponse(['editable_fields' => $editableFields]);
    }

    /**
     * Admin-only: Save field configuration
     */
    public function save(): void
    {
        $this->requireCapability('field_config.edit');

        $fieldName = Sanitizer::sanitize($_POST['field_name'] ?? '');
        
        if (empty($fieldName)) {
            $this->errorResponse('Missing field_name');
            return;
        }

        $data = [
            'field_name' => $fieldName,
            'field_label' => Sanitizer::sanitize($_POST['field_label'] ?? ''),
            'field_type' => Sanitizer::sanitize($_POST['field_type'] ?? 'text'),
            'entity_type' => Sanitizer::sanitize($_POST['entity_type'] ?? 'deal'),
            'module_name' => Sanitizer::sanitize($_POST['module_name'] ?? null),
            'is_required' => isset($_POST['is_required']) ? (int)$_POST['is_required'] : 0,
            'is_editable' => isset($_POST['is_editable']) ? (int)$_POST['is_editable'] : 1,
            'is_editable_after_create' => isset($_POST['is_editable_after_create']) ? (int)$_POST['is_editable_after_create'] : 1,
            'is_active' => isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1,
            'edit_allow_roles' => json_decode($_POST['edit_allow_roles'] ?? '[]', true),
            'delete_allow_roles' => json_decode($_POST['delete_allow_roles'] ?? '[]', true),
            'view_allow_roles' => json_decode($_POST['view_allow_roles'] ?? '[]', true),
            'lookup_group_code' => Sanitizer::sanitize($_POST['lookup_group_code'] ?? null),
            'sort_order' => isset($_POST['sort_order']) ? (int)$_POST['sort_order'] : 0,
            'help_text' => Sanitizer::sanitize($_POST['help_text'] ?? null),
            'default_value' => Sanitizer::sanitize($_POST['default_value'] ?? null),
            'validation_pattern' => Sanitizer::sanitize($_POST['validation_pattern'] ?? null),
            'validation_message' => Sanitizer::sanitize($_POST['validation_message'] ?? null),
            'conditional_logic' => $_POST['conditional_logic'] ?? null,
            'group_name' => Sanitizer::sanitize($_POST['group_name'] ?? null),
        ];

        try {
            $this->fieldConfigRepo->save($data);
            $this->successResponse(['field_name' => $fieldName, 'message' => 'Field configuration saved']);
        } catch (\Exception $e) {
            $this->errorResponse('Error saving configuration: ' . $e->getMessage());
        }
    }

    /**
     * Admin-only: Delete field configuration
     */
    public function delete(): void
    {
        $this->requireCapability('field_config.delete');

        $fieldName = Sanitizer::sanitize($_POST['field_name'] ?? '');
        
        if (empty($fieldName)) {
            $this->errorResponse('Missing field_name');
            return;
        }

        try {
            $this->fieldConfigRepo->delete($fieldName);
            $this->successResponse(['message' => 'Field configuration deleted']);
        } catch (\Exception $e) {
            $this->errorResponse('Error deleting configuration: ' . $e->getMessage());
        }
    }

    /**
     * Admin-only: Update edit role permissions
     */
    public function updateEditRoles(): void
    {
        $this->requireCapability('field_config.edit');

        $fieldName = Sanitizer::sanitize($_POST['field_name'] ?? '');
        $roles = json_decode($_POST['edit_allow_roles'] ?? '[]', true);

        if (empty($fieldName)) {
            $this->errorResponse('Missing field_name');
            return;
        }

        try {
            $this->fieldConfigRepo->updateEditRoles($fieldName, $roles);
            $this->successResponse(['message' => 'Edit roles updated']);
        } catch (\Exception $e) {
            $this->errorResponse('Error updating roles: ' . $e->getMessage());
        }
    }

    /**
     * Require admin role
     */
    private function requireAdmin(): void
    {
        $this->requireCapability('field_config.manage');
    }

    private function requireCapability(string $capabilityKey): void
    {
        if (!$this->auth->isAuthenticated()) {
            $this->errorResponse('Access denied', 403);
            exit;
        }
        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);
        exit;
    }
}
