<?php

namespace App\Http\Controllers\Inquiry;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Inquiry\CalculateOutboundPremiumRequest;
use App\Models\Company;
use App\Models\Deductible;
use App\Models\Language;
use App\Models\Plan;
use App\Models\Price;
use App\Services\InsuranceRateCalculator;
use App\Services\JfRateService;
use App\Services\ManulifeRateService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Throwable;

/**
 * @OA\Get(
 *   path="/api/inquiry/outbound/premium",
 *   tags={"Inquiry"},
 *   summary="Calculate Outbound Insurance Premium",
 *   operationId="calculate_outbound_premium",
 *   security={{"auth":{}}},
 *
 *   @OA\Parameter(name="Accept-Language", in="header", description="Accept-Language", required=true, example="en", @OA\Schema(type="string")),
 *   @OA\Parameter(name="API-Key", in="header", description="API-Key", required=true, example="", @OA\Schema(type="string")),
 *   
 *   @OA\Parameter(name="started_at", in="query", description="Trip Start Date (YYYY-MM-DD)", required=true, example="2025-04-01"),
 *   @OA\Parameter(name="ended_at", in="query", description="Trip End Date (YYYY-MM-DD)", required=true, example="2025-04-15"),
 *   @OA\Parameter(name="destination", in="query", description="Destination (canada, worldwide_excluding_usa, worldwide_including_usa)", required=true, example="worldwide_including_usa"),
 *   @OA\Parameter(name="insurance_cover", in="query", description="Insurance Coverage Amount", required=true, example="100000"),
 *   @OA\Parameter(name="birthdays", in="query", description="Birthdays CSV (YYYY-MM-DD,YYYY-MM-DD)", required=true, example="1980-05-15,1985-08-20"),
 *   @OA\Parameter(name="trip_purpose", in="query", description="Trip Purpose (tourism, business, education, medical, other)", required=false, example="tourism"),
 *   @OA\Parameter(name="destination_country", in="query", description="Specific Destination Country", required=false, example="United States"),
 *   @OA\Parameter(name="deductible_amount", in="query", description="Deductible Amount (0,500,1000,5000,10000)", required=false, example="0"),
 *   @OA\Parameter(name="rate_categories", in="query", description="Rate Categories CSV (A,B,C for each person)", required=false, example="A,B"),
 *   @OA\Parameter(name="has_pre_existing_conditions", in="query", description="Pre-existing Conditions CSV (true,false)", required=false, example="false,false"),
 *   @OA\Parameter(name="is_smokers", in="query", description="Smoker Status CSV (true,false)", required=false, example="false,true"),
 *   @OA\Parameter(name="company_ids", in="query", description="Company IDs CSV to filter", required=false, example="1,2,3"),
 *   @OA\Parameter(name="plan_ids", in="query", description="Plan IDs CSV to filter", required=false, example="10,20,30"),
 *   
 *   @OA\Response(
 *     response=200,
 *     description="Success",
 *     @OA\JsonContent(
 *       type="object",
 *       @OA\Property(property="result", type="object",
 *         @OA\Property(property="trip_details", type="object",
 *           @OA\Property(property="start_date", type="string", example="2025-04-01"),
 *           @OA\Property(property="end_date", type="string", example="2025-04-15"),
 *           @OA\Property(property="duration_days", type="integer", example=15),
 *           @OA\Property(property="destination", type="string", example="worldwide_including_usa"),
 *           @OA\Property(property="destination_label", type="string", example="Worldwide (Including USA)"),
 *           @OA\Property(property="trip_purpose", type="string", example="tourism"),
 *           @OA\Property(property="destination_country", type="string", example="United States")
 *         ),
 *         @OA\Property(property="people_details", type="array",
 *           @OA\Items(type="object",
 *             @OA\Property(property="age", type="integer", example=44),
 *             @OA\Property(property="requires_questionnaire", type="boolean", example=false),
 *             @OA\Property(property="rate_category", type="string", example="A"),
 *             @OA\Property(property="is_smoker", type="boolean", example=false),
 *             @OA\Property(property="has_pre_existing_conditions", type="boolean", example=false)
 *           )
 *         ),
 *         @OA\Property(property="insurance_details", type="object",
 *           @OA\Property(property="insurance_cover", type="integer", example=100000),
 *           @OA\Property(property="deductible_amount", type="integer", example=0),
 *           @OA\Property(property="questionnaire_required", type="boolean", example=false)
 *         ),
 *         @OA\Property(property="quotes", type="array",
 *           @OA\Items(type="object",
 *             @OA\Property(property="company_id", type="integer", example=1),
 *             @OA\Property(property="company_name", type="string", example="Manulife"),
 *             @OA\Property(property="company_logo", type="string", example="/uploads/companies/manulife.png"),
 *             @OA\Property(property="plans", type="array",
 *               @OA\Items(type="object",
 *                 @OA\Property(property="plan_id", type="integer", example=10),
 *                 @OA\Property(property="plan_name", type="string", example="Single-Trip Emergency Medical"),
 *                 @OA\Property(property="plan_description", type="string", example="Comprehensive medical coverage for single trips"),
 *                 @OA\Property(property="prices", type="array",
 *                   @OA\Items(type="object",
 *                     @OA\Property(property="price_id", type="integer", example=100),
 *                     @OA\Property(property="daily_rate", type="number", format="float", example=8.75),
 *                     @OA\Property(property="total_premium", type="number", format="float", example=131.25),
 *                     @OA\Property(property="base_premium", type="number", format="float", example=131.25),
 *                     @OA\Property(property="tax_amount", type="number", format="float", example=0.00),
 *                     @OA\Property(property="final_amount", type="number", format="float", example=131.25),
 *                     @OA\Property(property="rate_category", type="string", example="A"),
 *                     @OA\Property(property="canada_half_price_applied", type="boolean", example=false),
 *                     @OA\Property(property="has_smoking_surcharge", type="boolean", example=false),
 *                     @OA\Property(property="deductible_amount", type="integer", example=0),
 *                     @OA\Property(property="deductible_discount_percent", type="integer", example=0),
 *                     @OA\Property(property="deductible_discount_amount", type="number", format="float", example=0.00)
 *                   )
 *                 ),
 *                 @OA\Property(property="requires_questionnaire", type="boolean", example=false),
 *                 @OA\Property(property="questionnaire_type", type="string", example="manulife_60_plus"),
 *                 @OA\Property(property="message", type="string", example="Final rate will be confirmed after questionnaire completion")
 *               )
 *             )
 *           )
 *         ),
 *         @OA\Property(property="summary", type="object",
 *           @OA\Property(property="total_people", type="integer", example=2),
 *           @OA\Property(property="min_premium", type="number", format="float", example=131.25),
 *           @OA\Property(property="max_premium", type="number", format="float", example=245.80),
 *           @OA\Property(property="average_premium_per_person", type="number", format="float", example=65.63),
 *           @OA\Property(property="eligible_companies_count", type="integer", example=3),
 *           @OA\Property(property="eligible_plans_count", type="integer", example=5)
 *         )
 *       )
 *     )
 *   )
 * )
 */
class CalculateOutboundPremiumController extends ApiController
{
    /**
     * @var InsuranceRateCalculator
     */
    private $rateCalculator;

    /**
     * @var JfRateService
     */
    private $jfRateService;

    /**
     * @var ManulifeRateService
     */
    private $manulifeRateService;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->rateCalculator = app(InsuranceRateCalculator::class);
        $this->jfRateService = app(JfRateService::class);
        $this->manulifeRateService = app(ManulifeRateService::class);
    }

    /**
     * Handle the incoming request.
     */
    public function __invoke(CalculateOutboundPremiumRequest $request): JsonResponse
    {
        try {
            $data = $request->validatedData();
            
            // Generate cache key for this calculation
            $cacheKey = $this->generateCacheKey($data);
            
            // Check cache first
            if ($cachedResult = Cache::get($cacheKey)) {
                return $this->success($cachedResult);
            }
            
            // Get language ID for translations
            $languageId = Language::where('code', $request->validated('language', 'en'))->value('id');
            
            // Calculate quotes
            $result = $this->calculateQuotes($data, $languageId);
            
            // Cache the result for 5 minutes
            Cache::put($cacheKey, $result, 300);
            
            return $this->success($result);
            
        } catch (Throwable $e) {
            return $this->error($e->getMessage(), [], $e->getCode() ?: 500);
        }
    }

    /**
     * Calculate insurance quotes based on input data.
     */
    private function calculateQuotes(array $data, int $languageId): array
    {
        $tripDetails = $this->prepareTripDetails($data);
        $peopleDetails = $this->preparePeopleDetails($data);
        $insuranceDetails = $this->prepareInsuranceDetails($data);
        
        // Get eligible companies and plans
        $eligibleCompanies = $this->getEligibleCompanies($data);
        $eligiblePlans = $this->getEligiblePlans($data, $eligibleCompanies);
        
        // Calculate quotes for each plan
        $quotes = [];
        $allPremiums = [];
        
        foreach ($eligiblePlans as $plan) {
            $planQuotes = $this->calculatePlanQuotes($plan, $data, $peopleDetails, $languageId);
            
            if (!empty($planQuotes)) {
                $companyId = $plan->company_id;
                
                if (!isset($quotes[$companyId])) {
                    $company = $plan->company;
                    $companyTranslation = $company->translations->where('language_id', $languageId)->first();
                    
                    $quotes[$companyId] = [
                        'company_id' => $companyId,
                        'company_name' => $companyTranslation->name ?? $company->name,
                        'company_logo' => $company->logo,
                        'company_slug' => $company->slug,
                        'plans' => [],
                    ];
                }
                
                $planTranslation = $plan->translations->where('language_id', $languageId)->first();
                
                $planData = [
                    'plan_id' => $plan->id,
                    'plan_name' => $planTranslation->name ?? $plan->slug,
                    'plan_description' => $planTranslation->description ?? '',
                    'plan_slug' => $plan->slug,
                    'prices' => $planQuotes,
                    'requires_questionnaire' => $plan->requires_questionnaire,
                    'questionnaire_type' => $plan->questionnaire_type,
                    'message' => $this->getPlanMessage($plan, $peopleDetails),
                ];
                
                $quotes[$companyId]['plans'][] = $planData;
                
                // Collect premiums for summary
                foreach ($planQuotes as $quote) {
                    $allPremiums[] = $quote['final_amount'];
                }
            }
        }
        
        // Convert quotes to array
        $quotes = array_values($quotes);
        
        // Prepare summary
        $summary = $this->prepareSummary($data, $peopleDetails, $quotes, $allPremiums);
        
        return [
            'trip_details' => $tripDetails,
            'people_details' => $peopleDetails,
            'insurance_details' => $insuranceDetails,
            'quotes' => $quotes,
            'summary' => $summary,
        ];
    }

    /**
     * Prepare trip details for response.
     */
    private function prepareTripDetails(array $data): array
    {
        $startDate = Carbon::parse($data['started_at']);
        $endDate = Carbon::parse($data['ended_at']);
        
        return [
            'start_date' => $data['started_at'],
            'end_date' => $data['ended_at'],
            'duration_days' => $data['trip_duration'],
            'destination' => $data['destination'],
            'destination_label' => $this->getDestinationLabel($data['destination']),
            'trip_purpose' => $data['trip_purpose'],
            'trip_purpose_label' => $this->getTripPurposeLabel($data['trip_purpose']),
            'destination_country' => $data['destination_country'] ?? null,
            'includes_usa' => $data['destination'] === 'worldwide_including_usa',
            'is_canada_only' => $data['destination'] === 'canada',
        ];
    }

    /**
     * Prepare people details for response.
     */
    private function preparePeopleDetails(array $data): array
    {
        $peopleDetails = [];
        
        for ($i = 0; $i < count($data['birthdays']); $i++) {
            $age = $data['ages'][$i];
            $requiresQuestionnaire = $age >= 60;
            
            $peopleDetails[] = [
                'index' => $i + 1,
                'age' => $age,
                'birthday' => $data['birthdays'][$i],
                'requires_questionnaire' => $requiresQuestionnaire,
                'rate_category' => $data['rate_categories'][$i] ?? 'A',
                'is_smoker' => $data['is_smokers'][$i] ?? false,
                'has_pre_existing_conditions' => $data['has_pre_existing_conditions'][$i] ?? false,
                'is_eligible' => true, // Assuming eligible unless determined otherwise
                'age_group' => $this->getAgeGroup($age),
            ];
        }
        
        return $peopleDetails;
    }

    /**
     * Prepare insurance details for response.
     */
    private function prepareInsuranceDetails(array $data): array
    {
        $requiresQuestionnaire = false;
        foreach ($data['ages'] as $age) {
            if ($age >= 60) {
                $requiresQuestionnaire = true;
                break;
            }
        }
        
        return [
            'insurance_cover' => $data['insurance_cover'],
            'deductible_amount' => $data['deductible_amount'] ?? 0,
            'questionnaire_required' => $requiresQuestionnaire,
            'is_entry' => false,
            'insurance_type' => 'outbound',
        ];
    }

    /**
     * Get eligible companies based on criteria.
     */
    private function getEligibleCompanies(array $data): array
    {
        $query = Company::query()
            ->where('is_active', true)
            ->whereHas('plans', function ($q) use ($data) {
                $q->where('is_active', true)
                  ->where('supports_outbound', true);
            });
        
        // Filter by company IDs if provided
        if (!empty($data['company_ids'])) {
            $query->whereIn('id', $data['company_ids']);
        }
        
        // Filter by company slug based on destination
        $destination = $data['destination'];
        if ($destination === 'canada') {
            // Both Manulife and JF support Canada
            $query->whereIn('slug', ['manulife', 'jf']);
        } elseif ($destination === 'worldwide_including_usa') {
            // Both support worldwide including USA
            $query->whereIn('slug', ['manulife', 'jf']);
        } else {
            // Worldwide excluding USA
            $query->whereIn('slug', ['manulife', 'jf']);
        }
        
        return $query->get()->all();
    }

    /**
     * Get eligible plans based on companies and criteria.
     */
    private function getEligiblePlans(array $data, array $companies): array
    {
        if (empty($companies)) {
            return [];
        }
        
        $companyIds = array_map(function ($company) {
            return $company->id;
        }, $companies);
        
        $query = Plan::query()
            ->where('is_active', true)
            ->where('supports_outbound', true)
            ->whereIn('company_id', $companyIds);
        
        // Filter by plan IDs if provided
        if (!empty($data['plan_ids'])) {
            $query->whereIn('id', $data['plan_ids']);
        }
        
        // Filter by questionnaire requirement if applicable
        $requiresQuestionnaire = false;
        foreach ($data['ages'] as $age) {
            if ($age >= 60) {
                $requiresQuestionnaire = true;
                break;
            }
        }
        
        if ($requiresQuestionnaire) {
            $query->where('requires_questionnaire', true);
        }
        
        return $query->orderBy('company_id')
                    ->orderBy('sort')
                    ->get()
                    ->all();
    }

    /**
     * Calculate quotes for a specific plan.
     */
    private function calculatePlanQuotes(Plan $plan, array $data, array $peopleDetails, int $languageId): array
    {
        $quotes = [];
        
        // Get company to determine which rate service to use
        $company = $plan->company;
        
        // Check if plan covers all ages
        if (!$plan->coversAllAges($data['ages'])) {
            return [];
        }
        
        // Calculate based on company
        if ($company->slug === 'jf') {
            $quotes = $this->calculateJfQuotes($plan, $data, $peopleDetails);
        } elseif ($company->slug === 'manulife') {
            $quotes = $this->calculateManulifeQuotes($plan, $data, $peopleDetails);
        } else {
            // Use default calculation for other companies
            $quotes = $this->calculateDefaultQuotes($plan, $data, $peopleDetails);
        }
        
        return $quotes;
    }

    /**
     * Calculate JF insurance quotes.
     */
    private function calculateJfQuotes(Plan $plan, array $data, array $peopleDetails): array
    {
        $quotes = [];
        
        // JF calculation logic
        $destination = $data['destination'];
        $duration = $data['trip_duration'];
        $deductible = $data['deductible_amount'] ?? 0;
        
        // Check if destination is valid for JF
        if ($destination === 'canada') {
            // JF doesn't have separate Canada rates, use worldwide excluding USA
            $destination = 'worldwide_excluding_usa';
        }
        
        // Calculate for each person
        $totalPremium = 0;
        $dailyRate = 0;
        
        foreach ($peopleDetails as $person) {
            $age = $person['age'];
            
            try {
                // Use JF rate service
                $premiumData = $this->jfRateService->calculatePremium(
                    $age,
                    $duration,
                    $destination
                );
                
                $dailyRate = max($dailyRate, $premiumData['daily_rate']);
                $totalPremium += $premiumData['total_premium'];
                
            } catch (\Exception $e) {
                // Skip person if calculation fails
                continue;
            }
        }
        
        if ($totalPremium > 0) {
            // Apply deductible discount for JF
            $deductibleDiscountPercent = $this->getDeductibleDiscountPercent($deductible);
            $deductibleDiscount = $totalPremium * ($deductibleDiscountPercent / 100);
            
            $basePremium = $totalPremium;
            $finalPremium = $totalPremium - $deductibleDiscount;
            
            $quotes[] = [
                'price_id' => null, // No specific price ID for calculated rates
                'daily_rate' => round($dailyRate, 2),
                'total_premium' => round($totalPremium, 2),
                'base_premium' => round($basePremium, 2),
                'tax_amount' => 0.00,
                'final_amount' => round($finalPremium, 2),
                'rate_category' => 'A', // JF doesn't have rate categories
                'canada_half_price_applied' => false,
                'has_smoking_surcharge' => false, // JF doesn't have smoking surcharge
                'deductible_amount' => $deductible,
                'deductible_discount_percent' => $deductibleDiscountPercent,
                'deductible_discount_amount' => round($deductibleDiscount, 2),
                'plan_type' => 'jf_top',
                'includes_usa' => $destination === 'worldwide_including_usa',
                'message' => $destination === 'worldwide_including_usa' 
                    ? 'Worldwide coverage including USA'
                    : 'Worldwide coverage excluding USA',
            ];
        }
        
        return $quotes;
    }

    /**
     * Calculate Manulife insurance quotes.
     */
    private function calculateManulifeQuotes(Plan $plan, array $data, array $peopleDetails): array
    {
        $quotes = [];
        
        // Manulife calculation logic
        $destination = $data['destination'];
        $duration = $data['trip_duration'];
        $deductible = $data['deductible_amount'] ?? 0;
        
        // Calculate for each rate category (A, B, C) if questionnaire might be required
        $rateCategories = ['A', 'B', 'C'];
        $hasAge60Plus = false;
        
        foreach ($peopleDetails as $person) {
            if ($person['age'] >= 60) {
                $hasAge60Plus = true;
                break;
            }
        }
        
        // If no one is 60+, only show category A
        if (!$hasAge60Plus) {
            $rateCategories = ['A'];
        }
        
        foreach ($rateCategories as $rateCategory) {
            $totalPremium = 0;
            $dailyRate = 0;
            $hasSmokingSurcharge = false;
            $canadaHalfPriceApplied = false;
            
            foreach ($peopleDetails as $index => $person) {
                $age = $person['age'];
                $isSmoker = $person['is_smoker'];
                $hasPreExistingConditions = $person['has_pre_existing_conditions'];
                
                try {
                    // Use Manulife rate service
                    $premiumData = $this->manulifeRateService->calculatePremium(
                        $age,
                        $duration,
                        $destination,
                        $rateCategory,
                        $isSmoker,
                        $deductible,
                        $hasPreExistingConditions
                    );
                    
                    $dailyRate = max($dailyRate, $premiumData['daily_rate']);
                    $totalPremium += $premiumData['total_premium'];
                    
                    if ($premiumData['smoking_surcharge'] > 0) {
                        $hasSmokingSurcharge = true;
                    }
                    
                    if ($premiumData['canada_half_price_applied']) {
                        $canadaHalfPriceApplied = true;
                    }
                    
                } catch (\Exception $e) {
                    // Skip person if calculation fails
                    continue;
                }
            }
            
            if ($totalPremium > 0) {
                $deductibleDiscountPercent = $this->getDeductibleDiscountPercent($deductible);
                $deductibleDiscount = $totalPremium * ($deductibleDiscountPercent / 100);
                
                $basePremium = $totalPremium;
                $finalPremium = $totalPremium - $deductibleDiscount;
                
                $quotes[] = [
                    'price_id' => null,
                    'daily_rate' => round($dailyRate, 2),
                    'total_premium' => round($totalPremium, 2),
                    'base_premium' => round($basePremium, 2),
                    'tax_amount' => 0.00,
                    'final_amount' => round($finalPremium, 2),
                    'rate_category' => $rateCategory,
                    'canada_half_price_applied' => $canadaHalfPriceApplied,
                    'has_smoking_surcharge' => $hasSmokingSurcharge,
                    'deductible_amount' => $deductible,
                    'deductible_discount_percent' => $deductibleDiscountPercent,
                    'deductible_discount_amount' => round($deductibleDiscount, 2),
                    'plan_type' => 'manulife_single_trip',
                    'includes_usa' => $destination === 'worldwide_including_usa',
                    'message' => $this->getManulifeMessage($rateCategory, $hasAge60Plus, $hasSmokingSurcharge),
                ];
            }
        }
        
        return $quotes;
    }

    /**
     * Calculate default quotes for other companies.
     */
    private function calculateDefaultQuotes(Plan $plan, array $data, array $peopleDetails): array
    {
        // Default calculation using plan prices
        $quotes = [];
        $duration = $data['trip_duration'];
        
        // Find matching prices for each age
        $matchingPriceIds = [];
        
        foreach ($peopleDetails as $person) {
            $age = $person['age'];
            
            $price = $plan->prices->first(function ($price) use ($age, $data) {
                return $price->age_from <= $age && 
                       ($price->age_to === null || $price->age_to >= $age) &&
                       $price->insurance_cover == $data['insurance_cover'] &&
                       $price->is_entry == false &&
                       $price->is_active == true;
            });
            
            if ($price) {
                $matchingPriceIds[] = $price->id;
            }
        }
        
        // If we have matching prices for all people
        if (count($matchingPriceIds) === count($peopleDetails)) {
            $totalPremium = 0;
            $dailyRate = 0;
            
            foreach ($matchingPriceIds as $priceId) {
                $price = Price::find($priceId);
                if ($price) {
                    $personPremium = $price->daily_cost * $duration;
                    $totalPremium += $personPremium;
                    $dailyRate = max($dailyRate, $price->daily_cost);
                }
            }
            
            if ($totalPremium > 0) {
                $quotes[] = [
                    'price_id' => $matchingPriceIds[0], // Use first price ID
                    'daily_rate' => round($dailyRate, 2),
                    'total_premium' => round($totalPremium, 2),
                    'base_premium' => round($totalPremium, 2),
                    'tax_amount' => 0.00,
                    'final_amount' => round($totalPremium, 2),
                    'rate_category' => 'A',
                    'canada_half_price_applied' => false,
                    'has_smoking_surcharge' => false,
                    'deductible_amount' => 0,
                    'deductible_discount_percent' => 0,
                    'deductible_discount_amount' => 0.00,
                    'plan_type' => 'default',
                    'includes_usa' => false,
                    'message' => 'Standard outbound coverage',
                ];
            }
        }
        
        return $quotes;
    }

    /**
     * Get deductible discount percentage.
     */
    private function getDeductibleDiscountPercent(int $deductible): int
    {
        return match($deductible) {
            500 => 10,
            1000 => 15,
            5000 => 30,
            10000 => 35,
            default => 0,
        };
    }

    /**
     * Get destination label.
     */
    private function getDestinationLabel(string $destination): string
    {
        return match($destination) {
            'canada' => 'Canada (Out of Province)',
            'worldwide_excluding_usa' => 'Worldwide (Excluding USA)',
            'worldwide_including_usa' => 'Worldwide (Including USA)',
            default => ucfirst(str_replace('_', ' ', $destination)),
        };
    }

    /**
     * Get trip purpose label.
     */
    private function getTripPurposeLabel(string $purpose): string
    {
        return match($purpose) {
            'tourism' => 'Tourism',
            'business' => 'Business',
            'education' => 'Education',
            'medical' => 'Medical',
            'other' => 'Other',
            default => ucfirst($purpose),
        };
    }

    /**
     * Get age group.
     */
    private function getAgeGroup(int $age): string
    {
        if ($age < 18) return '0-17';
        if ($age <= 30) return '18-30';
        if ($age <= 60) return '31-60';
        if ($age <= 64) return '60-64';
        if ($age <= 69) return '65-69';
        if ($age <= 74) return '70-74';
        if ($age <= 79) return '75-79';
        if ($age <= 84) return '80-84';
        return '85+';
    }

    /**
     * Get plan message.
     */
    private function getPlanMessage(Plan $plan, array $peopleDetails): string
    {
        $hasAge60Plus = false;
        foreach ($peopleDetails as $person) {
            if ($person['requires_questionnaire']) {
                $hasAge60Plus = true;
                break;
            }
        }
        
        if ($plan->requires_questionnaire && $hasAge60Plus) {
            return 'Final rate will be confirmed after questionnaire completion';
        }
        
        if ($plan->company->slug === 'jf') {
            return 'JF TOP Travel Insurance - No medical questionnaire required';
        }
        
        if ($plan->company->slug === 'manulife') {
            return 'Manulife Travel Insurance - Comprehensive medical coverage';
        }
        
        return 'Travel insurance coverage';
    }

    /**
     * Get Manulife specific message.
     */
    private function getManulifeMessage(string $rateCategory, bool $hasAge60Plus, bool $hasSmokingSurcharge): string
    {
        $messages = [];
        
        if ($hasAge60Plus) {
            $messages[] = "Rate Category {$rateCategory} applied";
            
            if ($rateCategory === 'A') {
                $messages[] = 'All medical questions answered NO';
            } elseif ($rateCategory === 'B') {
                $messages[] = 'Medium risk medical conditions';
            } elseif ($rateCategory === 'C') {
                $messages[] = 'High risk medical conditions';
            }
        }
        
        if ($hasSmokingSurcharge) {
            $messages[] = '10% smoking surcharge applied';
        }
        
        return implode('. ', $messages);
    }

    /**
     * Prepare summary of quotes.
     */
    private function prepareSummary(array $data, array $peopleDetails, array $quotes, array $allPremiums): array
    {
        if (empty($allPremiums)) {
            $minPremium = $maxPremium = $averagePremium = 0;
        } else {
            $minPremium = min($allPremiums);
            $maxPremium = max($allPremiums);
            $averagePremium = array_sum($allPremiums) / count($allPremiums);
        }
        
        $totalPeople = count($peopleDetails);
        $peopleRequiringQuestionnaire = 0;
        
        foreach ($peopleDetails as $person) {
            if ($person['requires_questionnaire']) {
                $peopleRequiringQuestionnaire++;
            }
        }
        
        $eligibleCompaniesCount = count($quotes);
        $eligiblePlansCount = 0;
        
        foreach ($quotes as $companyQuote) {
            $eligiblePlansCount += count($companyQuote['plans']);
        }
        
        return [
            'total_people' => $totalPeople,
            'people_requiring_questionnaire' => $peopleRequiringQuestionnaire,
            'min_premium' => round($minPremium, 2),
            'max_premium' => round($maxPremium, 2),
            'average_premium' => round($averagePremium, 2),
            'average_premium_per_person' => $totalPeople > 0 ? round($averagePremium / $totalPeople, 2) : 0,
            'eligible_companies_count' => $eligibleCompaniesCount,
            'eligible_plans_count' => $eligiblePlansCount,
            'trip_duration_days' => $data['trip_duration'],
            'destination' => $data['destination'],
            'includes_usa' => $data['destination'] === 'worldwide_including_usa',
        ];
    }

    /**
     * Generate cache key for calculation.
     */
    private function generateCacheKey(array $data): string
    {
        $keyParts = [
            'outbound_premium',
            $data['started_at'],
            $data['ended_at'],
            $data['destination'],
            $data['insurance_cover'],
            implode(',', $data['birthdays']),
            $data['deductible_amount'] ?? 0,
            implode(',', $data['rate_categories'] ?? []),
            implode(',', $data['is_smokers'] ?? []),
        ];
        
        return 'calc_' . md5(implode('|', $keyParts));
    }
}