<?php
namespace App\Controllers;

use App\Repositories\ConfigRepository;
use App\Repositories\PersonRepository;
use App\Utils\Logger;
use App\Utils\PhoneNormalizer;
use App\Utils\Sanitizer;

class IntegrationController extends ApiController
{
    private $configRepo;
    private $personRepo;

    public function __construct(ConfigRepository $configRepo, PersonRepository $personRepo)
    {
        $this->configRepo = $configRepo;
        $this->personRepo = $personRepo;
    }

    public function getLeadAssignment()
    {
        try {
            $enabled = $this->normalizeFlag($this->configRepo->getValue('external_api_enabled', '0'));
            if (!$enabled) {
                $this->errorResponse('external API is disabled', 503);
            }

            $configuredToken = trim((string)($this->configRepo->getValue('external_api_token', getenv('EXTERNAL_API_TOKEN') ?: '')));
            if ($configuredToken === '') {
                $this->errorResponse('external API token is not configured', 503);
            }

            $providedToken = $this->extractToken();
            if ($providedToken === '' || !hash_equals($configuredToken, $providedToken)) {
                Logger::logWarning('External API token mismatch', [
                    'endpoint' => 'get_lead_assignment',
                    'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
                ]);
                $this->errorResponse('unauthorized', 401);
            }

            $phone = Sanitizer::sanitize($_REQUEST['phone'] ?? '');
            $didarContactId = Sanitizer::sanitize($_REQUEST['didar_contact_id'] ?? '');
            $customerCode = Sanitizer::sanitize($_REQUEST['customer_code'] ?? '');
            $nationalId = Sanitizer::sanitize($_REQUEST['national_id'] ?? '');

            $phoneCandidates = $phone !== '' ? PhoneNormalizer::normalizeCandidates($phone) : [];

            if ($phone === '' && $didarContactId === '' && $customerCode === '' && $nationalId === '') {
                $this->errorResponse('one of phone, didar_contact_id, customer_code, or national_id is required', 422);
            }

            $row = $this->personRepo->findLeadAssignmentForExternalLookup([
                'phone_candidates' => $phoneCandidates,
                'didar_contact_id' => $didarContactId,
                'customer_code' => $customerCode,
                'national_id' => $nationalId,
            ]);

            if (!$row) {
                $this->successResponse([
                    'lead_found' => false,
                    'assigned' => false,
                    'has_agent' => false,
                    'sales_agent_name' => null,
                    'match_type' => null,
                    'lead' => null,
                    'sales_agent' => null,
                ]);
            }

            $leadName = trim((string)($row['first_name'] ?? '') . ' ' . (string)($row['last_name'] ?? ''));
            $hasOwner = trim((string)($row['owner_didar_id'] ?? '')) !== '';
            $ownerName = trim((string)($row['owner_name'] ?? ''));

            $this->successResponse([
                'lead_found' => true,
                'assigned' => $hasOwner,
                'has_agent' => $hasOwner,
                'sales_agent_name' => $hasOwner && $ownerName !== '' ? $ownerName : null,
                'match_type' => $row['match_type'] ?: null,
                'lead' => [
                    'id' => isset($row['id']) ? (int)$row['id'] : null,
                    'didar_contact_id' => $row['didar_contact_id'] ?: null,
                    'customer_code' => $row['customer_code'] ?: null,
                    'name' => $leadName !== '' ? $leadName : null,
                    'mobile_phone' => $row['mobile_phone'] ?: null,
                    'owner_didar_id' => $row['owner_didar_id'] ?: null,
                ],
                'sales_agent' => $hasOwner ? [
                    'id' => isset($row['owner_user_id']) ? (int)$row['owner_user_id'] : null,
                    'didar_user_id' => $row['owner_user_didar_id'] ?: ($row['owner_didar_id'] ?: null),
                    'name' => $ownerName !== '' ? $ownerName : null,
                    'first_name' => $row['owner_first_name'] ?: null,
                    'last_name' => $row['owner_last_name'] ?: null,
                    'email' => $row['owner_email'] ?: null,
                    'role' => $row['owner_role'] ?: null,
                    'is_active' => isset($row['owner_is_active']) ? (bool)$row['owner_is_active'] : null,
                ] : null,
            ]);
        } catch (\Throwable $e) {
            Logger::logError('External lead assignment lookup failed', $e, [
                'query_keys' => array_keys($_REQUEST ?? []),
            ]);
            $this->errorResponse('failed to fetch lead assignment', 500);
        }
    }

    private function normalizeFlag($value): bool
    {
        $normalized = is_string($value) ? strtolower(trim($value)) : $value;
        return in_array($normalized, [1, '1', true, 'true', 'on', 'yes'], true);
    }

    private function extractToken(): string
    {
        $header = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? '';
        if (is_string($header) && preg_match('/Bearer\s+(.+)/i', $header, $matches)) {
            return trim((string)$matches[1]);
        }

        $headerToken = $_SERVER['HTTP_X_API_TOKEN'] ?? '';
        if (is_string($headerToken) && trim($headerToken) !== '') {
            return trim($headerToken);
        }

        $requestToken = $_REQUEST['token'] ?? '';
        return trim((string)$requestToken);
    }
}
