<?php
namespace App\Controllers;

use App\Services\DidarApiService;
use App\Repositories\PersonRepository;
use App\Utils\Sanitizer;
use App\Utils\PhoneNormalizer;
use App\Utils\Logger;

/**
 * Controller for Didar-specific helper endpoints
 * (search, external lead data, etc.)
 */
class DidarController extends ApiController
{
    private $didarApi;
    private $personRepo;

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

    /**
     * Get Didar deals and activities for a given lead/contact.
     * Mirrors legacy get_lead_didar_data exactly.
     */
    public function getLeadData()
    {
        global $app;
        // Capability gate: roles configured with lead-profile access only
        // (admin/agent/crm_specialist/system have it; accountant does not).
        if (!isset($app->services->rbac) || !$app->services->rbac || !$app->services->rbac->can('leads.profile.view')) {
            $this->errorResponse('دسترسی محدود - شما مجاز به مشاهده اطلاعات لید نیستید', 403);
        }
        try {
            $contactId = Sanitizer::sanitize($_POST['contact_id'] ?? '');

            if (empty($contactId)) {
                $this->errorResponse('شناسه شخص الزامی است');
            }

            Logger::logInfo("getLeadData called", [
                'input_contact_id' => $contactId,
                'contact_id_type' => gettype($contactId),
                'is_numeric' => is_numeric($contactId),
                'is_guid' => preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $contactId)
            ]);

            // Find person by numeric id only (not didar_contact_id to avoid confusion)
            $person = $this->personRepo->findById($contactId);
            if (!$person) {
                // Fallback: try to find by didar_contact_id if it's a valid GUID
                if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $contactId)) {
                    $person = $this->personRepo->findByDidarId($contactId);
                }

                if (!$person) {
                    Logger::logWarning("Person not found", [
                        'searched_contact_id' => $contactId,
                        'is_guid' => preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $contactId)
                    ]);
                    $this->errorResponse('شخص یافت نشد');
                }
            }

            // RBAC ownership scope. 'all'-scope roles (admin/crm_specialist/accountant/
            // system and any custom role granted 'all') are never restricted here, so no
            // built-in role's behavior changes. Non-'all' roles (e.g. agent='self', custom
            // selected_users) are scoped to their owned leads — closing the prior bypass.
            $leadScope = (array)$app->services->rbac->getDataScope('leads');
            if (($leadScope['scope_type'] ?? 'none') !== 'all'
                && !$app->services->rbac->isOwnerInScope('leads', (string)($person->owner_didar_id ?? ''))) {
                $this->errorResponse('دسترسی به این رکورد در محدوده مجاز شما نیست', 403);
            }

            Logger::logDebug("Person found for Didar lookup", [
                'input_contact_id' => $contactId,
                'person_id' => $person->id,
                'person_name' => ($person->first_name ?? '') . ' ' . ($person->last_name ?? ''),
                'didar_contact_id' => $person->didar_contact_id ?? 'null',
                'mobile_phone' => $person->mobile_phone ?? 'null'
            ]);

            $didarContactId = $person->didar_contact_id ?? '';
            if ($this->isLocalContactId($didarContactId)) {
                Logger::logInfo("Local contact - returning empty data", [
                    'contact_id' => $contactId,
                    'didar_contact_id' => $didarContactId
                ]);
                $this->successResponse([
                    'deals' => [],
                    'activities' => [],
                    'local_only' => true
                ]);
                return;
            }

            $realContactId = null;

            // Check if didar_contact_id is a valid GUID format
            if (!empty($didarContactId) && preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $didarContactId)) {
                // It's a valid GUID, use it
                $realContactId = $didarContactId;
                Logger::logDebug("Using stored GUID from database", [
                    'contact_id' => $contactId,
                    'didar_contact_id' => $didarContactId
                ]);
            } else {
                // For numeric IDs or invalid formats, always search by phone number
                // This ensures we get the correct current GUID from Didar
                Logger::logInfo("Numeric or invalid didar_contact_id - searching by phone instead", [
                    'contact_id' => $contactId,
                    'didar_contact_id' => $didarContactId,
                    'is_numeric' => is_numeric($didarContactId),
                    'reason' => is_numeric($didarContactId) ? 'numeric_id' : 'invalid_format'
                ]);
                // Not a GUID or numeric ID, search by phone number to get the real contactId
                $mobilePhone = $person->mobile_phone ?: $person->secondary_mobile_phone ?: '';

                if (empty($mobilePhone)) {
                    Logger::logWarning("No phone number available for Didar search", [
                        'contact_id' => $contactId,
                        'didar_contact_id' => $didarContactId
                    ]);
                    $this->errorResponse('شماره تلفن برای این شخص یافت نشد. نمی‌توان از دیدار اطلاعات دریافت کرد.');
                }

                // Normalize phone number (convert 10-digit to 11-digit format)
                $phoneCleaned = PhoneNormalizer::normalize($mobilePhone);

                Logger::logDebug("Searching Didar by phone to get real contactId", [
                    'contact_id' => $contactId,
                    'person_name' => ($person->first_name ?? '') . ' ' . ($person->last_name ?? ''),
                    'phone' => $phoneCleaned,
                    'original_phone' => $mobilePhone,
                    'didar_contact_id_in_db' => $didarContactId
                ]);

                // Search in Didar by phone
                $searchCriteria = [
                    'ContactType' => 0,
                    'IsDeleted' => 0,
                    'IsPinned' => -1,
                    'IsVIP' => -1,
                    'LeadType' => -1,
                    'Pin' => -1,
                    'SortOrder' => 1,
                    'Keywords' => $phoneCleaned,
                    'SearchFromTime' => '1930-01-01T00:00:00.000Z',
                    'SearchToTime' => '9999-12-01T00:00:00.000Z',
                    'CustomFields' => [],
                    'FilterId' => null
                ];

                $searchRes = $this->didarApi->call('/contact/PersonSearch', 'POST', [
                    'Criteria' => $searchCriteria,
                    'From' => 0,
                    'Limit' => 50
                ]);

                if (isset($searchRes['error'])) {
                    Logger::logWarning("Failed to search person in Didar by phone", [
                        'contact_id' => $contactId,
                        'phone' => $phoneCleaned,
                        'error' => $searchRes['error']
                    ]);
                    $this->errorResponse("خطا در جستجوی شخص در دیدار: " . $searchRes['error']);
                }

                // Find the person in search results
                if (isset($searchRes['Response']['List']) && is_array($searchRes['Response']['List'])) {
                    Logger::logDebug("Didar search results", [
                        'contact_id' => $contactId,
                        'phone' => $phoneCleaned,
                        'results_count' => count($searchRes['Response']['List'])
                    ]);

                    foreach ($searchRes['Response']['List'] as $foundPerson) {
                        // Normalize found phone number for comparison
                        $foundPhone = PhoneNormalizer::normalize($foundPerson['MobilePhone'] ?? '');
                        Logger::logDebug("Checking search result", [
                            'contact_id' => $contactId,
                            'searched_phone' => $phoneCleaned,
                            'found_person_id' => $foundPerson['Id'] ?? 'null',
                            'found_person_name' => $foundPerson['DisplayName'] ?? '',
                            'found_person_phone' => $foundPerson['MobilePhone'] ?? '',
                            'found_phone_normalized' => $foundPhone,
                            'phone_match' => ($foundPhone === $phoneCleaned)
                        ]);

                        if ($foundPhone === $phoneCleaned) {
                            $realContactId = $foundPerson['Id'] ?? null;
                            Logger::logInfo("Found person in Didar by phone", [
                                'contact_id' => $contactId,
                                'person_name' => ($person->first_name ?? '') . ' ' . ($person->last_name ?? ''),
                                'phone' => $phoneCleaned,
                                'real_contact_id' => $realContactId,
                                'display_name' => $foundPerson['DisplayName'] ?? '',
                                'found_phone_original' => $foundPerson['MobilePhone'] ?? '',
                                'found_phone_normalized' => $foundPhone
                            ]);
                            break;
                        }
                    }
                } else {
                    Logger::logWarning("No search results from Didar", [
                        'contact_id' => $contactId,
                        'phone' => $phoneCleaned,
                        'response_has_list' => isset($searchRes['Response']['List'])
                    ]);
                }

                if (empty($realContactId)) {
                    Logger::logWarning("Person not found in Didar search results", [
                        'contact_id' => $contactId,
                        'person_name' => ($person->first_name ?? '') . ' ' . ($person->last_name ?? ''),
                        'phone' => $phoneCleaned,
                        'results_count' => isset($searchRes['Response']['List']) ? count($searchRes['Response']['List']) : 0
                    ]);
                    $this->errorResponse("شخص در دیدار یافت نشد. لطفاً مطمئن شوید که این لید از دیدار همگام‌سازی شده است.");
                }
            }

            $contactGuid = $realContactId; // Use the real GUID for API calls

            Logger::logDebug("Using contactId for Didar API", [
                'original_contact_id' => $_POST['contact_id'] ?? '',
                'person_id' => $person->id,
                'person_name' => ($person->first_name ?? '') . ' ' . ($person->last_name ?? ''),
                'final_contact_id' => $contactGuid,
                'is_guid' => preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $contactGuid),
                'contact_id_type' => gettype($contactGuid),
                'contact_id_length' => strlen($contactGuid)
            ]);
        
        // Get deals for this person
        Logger::logDebug("Fetching Didar deals for lead", [
            'contact_id' => $contactGuid
        ]);
        
        $dealsRequest = [
            'Criteria' => [
                'ContactIds' => [$contactGuid],
                'Status' => -1
            ],
            'From' => 0,
            'Limit' => 100
        ];
        
        Logger::logDebug("Sending deals request to Didar API", [
            'contact_id' => $contactGuid,
            'request' => $dealsRequest,
            'contact_id_type' => gettype($contactGuid),
            'contact_id_length' => strlen($contactGuid)
        ]);
        
        $dealsRes = $this->didarApi->call('/deal/search', 'POST', $dealsRequest);
        
        $deals = [];
        if (isset($dealsRes['error'])) {
            Logger::logWarning("Failed to fetch deals for lead", [
                'contact_id' => $contactGuid,
                'error' => $dealsRes['error'],
                'http_code' => $dealsRes['http_code'] ?? null,
                'response' => $dealsRes['response'] ?? null
            ]);
        } else if (isset($dealsRes['Response']['List']) && is_array($dealsRes['Response']['List'])) {
            $deals = $dealsRes['Response']['List'];
            Logger::logInfo("Fetched deals for lead", [
                'contact_id' => $contactGuid,
                'count' => count($deals)
            ]);
        } else {
            Logger::logWarning("No deals found or invalid response structure", [
                'contact_id' => $contactGuid,
                'response_keys' => array_keys($dealsRes ?? []),
                'has_response' => isset($dealsRes['Response']),
                'has_list' => isset($dealsRes['Response']['List'])
            ]);
        }
        
        // Get activities
        $activitiesRequest = [
            'ContactId' => $contactGuid,
            'FromDate' => '1901-01-01T00:00:00.000Z',
            'ToDate' => '9999-12-01T00:00:00.000Z',
            'IsDone' => -1,
            'From' => 0,
            'Limit' => 100
        ];
        
        Logger::logDebug("Sending activities request to Didar API", [
            'contact_id' => $contactGuid,
            'request' => $activitiesRequest,
            'contact_id_type' => gettype($contactGuid),
            'contact_id_length' => strlen($contactGuid)
        ]);
        
        $activitiesRes = $this->didarApi->call('/activity/search', 'POST', $activitiesRequest);
        
        $activities = [];
        if (isset($activitiesRes['error'])) {
            Logger::logWarning("Failed to fetch activities for lead", [
                'contact_id' => $contactGuid,
                'error' => $activitiesRes['error'],
                'http_code' => $activitiesRes['http_code'] ?? null,
                'response' => $activitiesRes['response'] ?? null
            ]);
        } else if (isset($activitiesRes['Response']['List']) && is_array($activitiesRes['Response']['List'])) {
            $activities = $activitiesRes['Response']['List'];
            Logger::logInfo("Fetched activities for lead", [
                'contact_id' => $contactGuid,
                'count' => count($activities)
            ]);
        } else {
            Logger::logWarning("No activities found or invalid response structure", [
                'contact_id' => $contactGuid,
                'response_keys' => array_keys($activitiesRes ?? []),
                'has_response' => isset($activitiesRes['Response']),
                'has_list' => isset($activitiesRes['Response']['List'])
            ]);
        }
        
            $this->successResponse([
                'deals' => $deals,
                'activities' => $activities,
            ]);
        } catch (\Exception $e) {
            Logger::logError("Error in getLeadData", $e, [
                'contact_id' => $_POST['contact_id'] ?? ''
            ]);
            $this->errorResponse('خطا در دریافت اطلاعات: ' . $e->getMessage(), 500);
        }
    }

    private function isLocalContactId(?string $contactId): bool
    {
        return !empty($contactId) && strpos($contactId, 'local_') === 0;
    }
}


