<?php
namespace App\Services;

use App\Repositories\VirtualStageRepository;
use App\Repositories\ActivityRepository;
use App\Repositories\DealRepository;
use App\Repositories\PersonRepository;
use App\Models\VirtualStage;
use App\Utils\Logger;

/**
 * Virtual Stage Service
 * Handles virtual stage calculation and updates
 */
class VirtualStageService
{
    private $virtualStageRepo;
    private $activityRepo;
    private $dealRepo;
    private $personRepo;

    public function __construct(
        VirtualStageRepository $virtualStageRepo,
        ActivityRepository $activityRepo,
        DealRepository $dealRepo,
        PersonRepository $personRepo
    ) {
        $this->virtualStageRepo = $virtualStageRepo;
        $this->activityRepo = $activityRepo;
        $this->dealRepo = $dealRepo;
        $this->personRepo = $personRepo;
    }

    /**
     * Get the virtual stage repository (for accessing stage data directly)
     */
    public function getRepository()
    {
        return $this->virtualStageRepo;
    }

    /**
     * Calculate virtual stage for a contact
     */
    public function calculate($contactId)
    {
        // Get contact activities (lean projection — only the fields the stage logic reads).
        $activities = $this->activityRepo->findByContactIdForStage($contactId, 50);
        $activitiesArray = array_map(function($act) {
            return $act->toArray();
        }, $activities);
        
        // Get contact deals
        $deals = $this->dealRepo->findByContactId($contactId);
        $dealsArray = array_map(function($deal) {
            return $deal->toArray();
        }, $deals);
        
        // Get contact info for has_previous_purchase
        $person = $this->personRepo->findByDidarId($contactId);
        $hasPreviousPurchase = $person && isset($person->has_previous_purchase) && $person->has_previous_purchase == 1;
        
        // الگوریتم تعیین مرحله طبق کاریز جدید
        if (empty($activitiesArray)) {
            // If no activities, check if has previous purchase to determine initial stage
            if ($hasPreviousPurchase) {
                return 'with_purchase';
            }
            return 'new';
        }
        
        // NEW: Check stage field in the most recent activity first
        $lastActivity = $activitiesArray[0] ?? null;
        if ($lastActivity) {
            $lastActivityStage = $lastActivity['stage'] ?? null;
            // If stage is explicitly set in activity, use it (especially for with_purchase/without_purchase)
            if (!empty($lastActivityStage) && in_array($lastActivityStage, ['with_purchase', 'without_purchase', 'refer_crm'])) {
                return $lastActivityStage;
            }
            
            // Also check result_note for stage information
            $resultNote = $lastActivity['result_note'] ?? '';
            if (!empty($resultNote)) {
                if (stripos($resultNote, '📍 مرحله کاریز: لید با فروش قبلی') !== false) {
                    return 'with_purchase';
                }
                if (stripos($resultNote, '📍 مرحله کاریز: لید بدون فروش قبلی') !== false) {
                    return 'without_purchase';
                }
            }
        }
        
        // Check for call activities
        $hasCall = false;
        $hasNoAnswerCall = false;
        $hasFollowupCall = false;
        foreach ($activitiesArray as $act) {
            $activityTitle = $act['activity_type_title'] ?? '';
            $resultNote = $act['result_note'] ?? '';
            if (!empty($activityTitle) && stripos($activityTitle, 'تماس') !== false) {
                $hasCall = true;
                // Check if call had no answer
                if (stripos($resultNote, 'عدم پاسخ') !== false || stripos($resultNote, 'پاسخ نداد') !== false || stripos($resultNote, 'جواب نداد') !== false) {
                    $hasNoAnswerCall = true;
                } else {
                    $hasFollowupCall = true;
                }
            }
        }
        
        // Check if has deal
        if (!empty($dealsArray)) {
            $deal = $dealsArray[0];
            
            // Check if deal has payment link
            $hasPaymentLink = !empty($deal['payment_short_link']);
            
            // Check if deal is paid
            $isPaid = isset($deal['is_paid']) && $deal['is_paid'] == 1;
            
            // Successful deals should exit the active kariz and move to the purchased bucket.
            if (($deal['status'] ?? '') === 'Won') {
                return 'with_purchase';
            }
            if (($deal['status'] ?? '') === 'Lost') {
                return 'without_purchase';
            }
            
            // Deal exists but not Won
            if ($hasPaymentLink) {
                return 'deal_registered';
            }
            
            return 'deal_registered';
        }
        
        // No deal yet, check call status
        if ($hasCall) {
            if ($hasNoAnswerCall) {
                return 'contact_no_answer';
            }
            if ($hasFollowupCall) {
                return 'contact_followup';
            }
            return 'contact_followup';
        }
        
        // If no specific stage determined, check if has previous purchase
        if ($hasPreviousPurchase) {
            return 'with_purchase';
        }
        
        return 'new';
    }

    /**
     * Update virtual stage for a contact
     */
    public function update($contactId, $stageName = null, $force = false)
    {
        if ($stageName === null) {
            $stageName = $this->calculate($contactId);
        }
        
        Logger::logInfo("Updating virtual stage", [
            'contact_id' => $contactId,
            'stage_name' => $stageName,
            'force' => $force
        ]);
        
        // Check if the new stage is a special stage
        $specialStages = ['with_purchase', 'without_purchase', 'refer_crm'];
        $isSpecialStage = in_array($stageName, $specialStages);
        
        if ($isSpecialStage) {
            // For special stages, remove other active stages first
            $this->virtualStageRepo->deleteActiveStages($contactId);
            
            // Check if this special stage already exists
            if (!$this->virtualStageRepo->exists($contactId, $stageName)) {
                // Insert new special stage
                $stage = new VirtualStage([
                    'contact_didar_id' => $contactId,
                    'stage_name' => $stageName
                ]);
                $this->virtualStageRepo->save($stage);
            } else {
                // Update existing special stage timestamp
                $this->virtualStageRepo->updateTimestamp($contactId, $stageName);
            }
        } else {
            // For active stages
            if ($stageName === 'new' && !$force) {
                $specialStage = $this->virtualStageRepo->getSpecialStage($contactId);
                
                if ($specialStage) {
                    Logger::logWarning("Prevented overwriting special stage with 'new'", [
                        'contact_id' => $contactId,
                        'existing_special_stage' => $specialStage,
                        'requested_stage' => $stageName
                    ]);
                    return $specialStage;
                }
            }
            
            // If force is false, remove all active stages (except special ones)
            if (!$force) {
                $this->virtualStageRepo->deleteActiveStages($contactId);
            }
            
            // Insert or update the new active stage
            $stage = new VirtualStage([
                'contact_didar_id' => $contactId,
                'stage_name' => $stageName
            ]);
            $this->virtualStageRepo->save($stage);
        }
        
        // Verify the update
        $savedStage = $this->virtualStageRepo->getMostRecentStage($contactId);
        
        if ($savedStage !== $stageName) {
            Logger::logError("Virtual stage update failed", null, [
                'contact_id' => $contactId,
                'expected' => $stageName,
                'actual' => $savedStage
            ]);
            
            // If verification failed, try to get the active stage instead
            $activeStage = $this->virtualStageRepo->getActiveStage($contactId);
            
            if ($activeStage === $stageName) {
                Logger::logInfo("Virtual stage successfully saved (active stage is correct)", [
                    'contact_id' => $contactId,
                    'active_stage' => $activeStage,
                    'most_recent_stage' => $savedStage
                ]);
                return $activeStage;
            }
        } else {
            Logger::logInfo("Virtual stage successfully saved", [
                'contact_id' => $contactId,
                'stage_name' => $savedStage
            ]);
        }
        
        return $savedStage ?: $stageName;
    }
}

