<?php
/**
 * VMO Vision Roadmap Engine
 *
 * Generates AI-driven, milestone-based roadmaps from consultation day to vision
 * achievement. Breaks milestones into daily activities, tracks daily reports
 * against planned tasks, measures progress, adjusts estimated completion date,
 * and integrates background research scan results.
 *
 * Design principles (from product spec):
 * - Roadmap is MILESTONE-BASED, not time-based
 * - Daily activities are milestones broken into day-by-day tasks
 * - Daily reports record what ACTUALLY happened each day
 * - Progress = completed daily tasks; missed tasks = no progress + extra days
 * - Background scans can trigger roadmap adjustments
 * - Users can download activities/reports/milestones for date ranges
 *
 * @package VMO_AI_Website_Builder
 * @since 1.0.5.3
 */

if (!defined('ABSPATH')) {
    exit;
}

class VMO_Vision_Roadmap_Engine {

    /** @var VMO_Vision_Roadmap_Engine|null */
    private static $instance = null;

    /** @var string OpenAI API key */
    private $api_key;

    /** @var wpdb */
    private $wpdb;

    /**
     * Get singleton instance.
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->api_key = get_option('vmo_openai_api_key', '');
    }

    // =========================================================================
    // 1. AI-POWERED ROADMAP GENERATION
    // =========================================================================

    /**
     * Generate a complete AI-driven milestone roadmap from consultation data.
     *
     * The AI analyzes the business vision, research, recommendations, and all
     * consultation context to produce a milestone-based roadmap from Day 1 to
     * the day the business vision is achieved.
     *
     * @param string $session_id  Consultation session ID.
     * @param int    $user_id     WordPress user ID.
     * @param array  $consultation_data  Full consultation data array.
     * @return array|false The generated roadmap data, or false on failure.
     */
    public function generate_ai_roadmap($session_id, $user_id, array $consultation_data) {
        $bp = $consultation_data['business_profile'] ?? [];
        $ex = $consultation_data['extracted_information'] ?? [];
        $research = $consultation_data['research_profile'] ?? [];
        $recommendations = $consultation_data['recommendations_profile'] ?? [];
        $offers = $consultation_data['offers_profile'] ?? [];
        $payments = $consultation_data['payments_profile'] ?? [];
        $website_plan = $consultation_data['website_plan'] ?? [];
        $systems_plan = $consultation_data['systems_plan'] ?? [];

        // Extract vision context
        $identity = $bp['identity'] ?? [];
        $vision_data = $bp['vision'] ?? [];
        $targets = $bp['targets'] ?? [];
        $audience = $bp['audience'] ?? [];

        $business_name = $identity['name'] ?? $ex['businessName'] ?? 'The Business';
        $industry = $identity['industry'] ?? $ex['industry'] ?? '';
        $business_model = $identity['model'] ?? $ex['businessModel'] ?? '';
        $vision = $vision_data['vision'] ?? '';
        $mission = $vision_data['mission'] ?? '';
        $core_values = $vision_data['core_values'] ?? [];
        $north_star = $targets['north_star_metric'] ?? '';
        $short_term = $targets['short_term'] ?? '';
        $mid_term = $targets['mid_term'] ?? '';
        $long_term = $targets['long_term'] ?? '';
        $usp = $ex['uniqueSellingPoint'] ?? '';
        $has_ecommerce = !empty($ex['ecommerce_needed']);
        $has_booking = !empty($ex['needsBooking']);
        $location = $ex['location'] ?? '';

        // Build the AI prompt
        $context = "BUSINESS CONTEXT:
- Name: {$business_name}
- Industry: {$industry}
- Business Model: {$business_model}
- Location: {$location}
- USP: {$usp}
- E-commerce: " . ($has_ecommerce ? 'Yes' : 'No') . "
- Booking System: " . ($has_booking ? 'Yes' : 'No') . "

VISION & MISSION:
- Vision: {$vision}
- Mission: {$mission}
- Core Values: " . implode(', ', (array) $core_values) . "

TARGETS:
- North Star Metric: {$north_star}
- Short-term: {$short_term}
- Mid-term: {$mid_term}
- Long-term: {$long_term}

TARGET AUDIENCE: " . wp_json_encode($audience, JSON_UNESCAPED_SLASHES) . "
";

        // Add research context if available
        if (!empty($research)) {
            $context .= "\nMARKET RESEARCH FINDINGS:\n" . wp_json_encode($research, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n";
        }

        // Add recommendations context if available
        if (!empty($recommendations)) {
            $context .= "\nAPPROVED RECOMMENDATIONS:\n" . wp_json_encode($recommendations, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n";
        }

        // Summarize offers
        if (!empty($offers)) {
            $context .= "\nBUSINESS OFFERS:\n" . wp_json_encode($offers, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n";
        }

        $system_prompt = "You are VMO, the AI CEO and business strategist. You must generate a comprehensive, MILESTONE-BASED business execution roadmap.

CRITICAL RULES:
1. The roadmap is MILESTONE-BASED, not time-based. Each milestone is a concrete achievement.
2. Milestones span from Day 1 (today, the consultation completion date) to the day the business vision is FULLY achieved.
3. The timeline is CALCULATED from what needs to be done — the user does NOT set it.
4. Every milestone must have clear success criteria and measurable outcomes.
5. Milestones must be ordered by dependencies (what must come first).
6. The total_days is determined by the sum of all work needed, NOT arbitrary dates.
7. Be realistic about timelines based on the business complexity, industry, and resources.

MILESTONE PHASES (customize these to the specific business):
- Foundation Phase: Business setup, website, legal, payment processing
- Operations Phase: CRM, email systems, phone systems, automations
- Launch Phase: Go live, initial marketing, first customers
- Growth Phase: Scale marketing, optimize conversions, expand offerings
- Maturity Phase: Sustainable revenue, market position, ongoing optimization
- Vision Achievement: Full business vision realized

For EACH milestone, provide:
- milestone_id: Unique identifier (m_1, m_2, etc.)
- name: Clear milestone name
- description: What this milestone achieves
- phase: Which phase (foundation/operations/launch/growth/maturity/vision)
- target_day: Day number from start (Day 1 = today)
- prerequisite_milestones: Array of milestone_ids that must be completed first
- success_criteria: Array of specific, measurable criteria
- kpi_targets: Array of KPI targets for this milestone
- activities: Array of specific tasks/activities within this milestone, each with:
  - id: Unique ID (a_1, a_2, etc.)
  - title: Task title
  - description: What needs to be done
  - type: task|ai_executed|user_approval|user_action|milestone_check
  - day: Which day (number from start)
  - estimated_duration_minutes: How long
  - priority: 1(critical) to 5(low)
- vision_alignment: How this milestone moves toward the business vision

OUTPUT FORMAT (strict JSON):
{
  \"business_name\": \"...\",
  \"vision_statement\": \"...\",
  \"north_star_metric\": \"...\",
  \"total_days\": <calculated total>,
  \"estimated_vision_date\": \"YYYY-MM-DD\",
  \"milestones\": [...],
  \"summary\": \"Executive summary of the roadmap\",
  \"key_risks\": [\"risk1\", \"risk2\"],
  \"success_factors\": [\"factor1\", \"factor2\"]
}

Generate a thorough, personalized roadmap. Every single day should have at least one activity. No day should be empty.";

        $messages = [
            ['role' => 'system', 'content' => $system_prompt],
            ['role' => 'user', 'content' => $context]
        ];

        // Call OpenAI for the roadmap generation
        $roadmap_json = $this->call_openai_json($messages, 4000, 0.3);

        if (empty($roadmap_json) || empty($roadmap_json['milestones'])) {
            error_log('VMO Vision Roadmap Engine: AI roadmap generation returned empty result');
            // Fall back to structured generation
            return $this->generate_structured_roadmap($session_id, $user_id, $consultation_data);
        }

        // Validate and enrich the AI output
        $roadmap = $this->validate_and_enrich_roadmap($roadmap_json, $consultation_data);

        // Persist to database
        $roadmap_id = $this->persist_roadmap($session_id, $user_id, $roadmap);

        if ($roadmap_id) {
            // Save milestones to dedicated table
            $this->save_milestones_to_db($roadmap_id, $user_id, $session_id, $roadmap);

            // Generate daily activities from milestones and save to DB
            $this->generate_and_save_daily_activities($roadmap_id, $user_id, $roadmap);

            // Schedule background research
            $this->schedule_deep_research($roadmap_id, $user_id);

            $roadmap['roadmap_id'] = $roadmap_id;
        }

        return $roadmap;
    }

    /**
     * Structured (non-AI) roadmap generation as fallback when API fails.
     * Still vision-connected but uses template milestones enhanced with business data.
     */
    private function generate_structured_roadmap($session_id, $user_id, array $cd) {
        $bp = $cd['business_profile'] ?? [];
        $ex = $cd['extracted_information'] ?? [];
        $identity = $bp['identity'] ?? [];
        $targets = $bp['targets'] ?? [];
        $vision_data = $bp['vision'] ?? [];

        $business_name = $identity['name'] ?? $ex['businessName'] ?? 'Your Business';
        $industry = $identity['industry'] ?? $ex['industry'] ?? 'General';
        $vision = $vision_data['vision'] ?? '';
        $north_star = $targets['north_star_metric'] ?? '';
        $short_term = $targets['short_term'] ?? '';
        $mid_term = $targets['mid_term'] ?? '';
        $long_term = $targets['long_term'] ?? '';
        $has_ecommerce = !empty($ex['ecommerce_needed']);
        $has_booking = !empty($ex['needsBooking']);

        // Estimate total days based on complexity
        $total_days = 180; // Base: 6 months
        if ($has_ecommerce) $total_days += 60;
        if (!empty($cd['research_profile'])) $total_days += 30;
        if ($long_term && (strpos(strtolower($long_term), 'year') !== false || strpos(strtolower($long_term), 'million') !== false)) {
            $total_days = max($total_days, 365); // At least 1 year for ambitious visions
        }
        $total_days = min(730, $total_days); // Cap at 2 years

        $milestone_id = 1;
        $activity_id = 1;
        $milestones = [];

        // Phase 1: Foundation (Days 1-14)
        $foundation_activities = [];
        for ($day = 1; $day <= 14; $day++) {
            $titles = [
                1 => 'Finalize brand identity and visual assets',
                2 => 'Purchase domain and configure hosting',
                3 => 'Design website layout and structure',
                4 => 'Build core website pages (Home, About, Contact)',
                5 => 'Set up SSL certificate and security',
                6 => 'Configure SEO foundations (meta tags, sitemap)',
                7 => 'Website content review and refinement',
                8 => 'Set up analytics and tracking codes',
                9 => 'Register business legally (if needed)',
                10 => 'Create privacy policy and terms of service',
                11 => 'Set up payment processing (Stripe/PayPal)',
                12 => 'Test all website functionality',
                13 => 'Mobile responsiveness review',
                14 => 'Final pre-launch website review and approval',
            ];
            $foundation_activities[] = [
                'id' => 'a_' . $activity_id++,
                'title' => $titles[$day] ?? "Foundation task for {$business_name}",
                'description' => '',
                'type' => ($day === 14 || $day === 7) ? 'user_approval' : 'ai_executed',
                'day' => $day,
                'estimated_duration_minutes' => 120,
                'priority' => $day <= 7 ? 1 : 2,
            ];
        }

        $milestones[] = [
            'milestone_id' => 'm_' . $milestone_id++,
            'name' => "{$business_name} Foundation Complete",
            'description' => "Website live, legal docs ready, payment processing configured for {$business_name}",
            'phase' => 'foundation',
            'target_day' => 14,
            'prerequisite_milestones' => [],
            'success_criteria' => ['Website accessible and functional', 'Payment processing active', 'Legal documents published', 'Analytics tracking live'],
            'kpi_targets' => ['Website uptime > 99%', 'All pages load < 3s'],
            'activities' => $foundation_activities,
            'vision_alignment' => $short_term ?: "Establish {$business_name}'s digital foundation",
        ];

        // Phase 2: Operations (Days 15-30)
        $ops_activities = [];
        $ops_tasks = [
            'Configure CRM and lead capture system',
            'Set up email marketing platform',
            'Create welcome email sequence',
            'Configure automated follow-up workflows',
            $has_booking ? 'Set up online booking system' : 'Create lead qualification forms',
            $has_ecommerce ? 'Configure product catalog and inventory' : 'Set up service descriptions and pricing',
            'Set up customer support channels',
            'Configure phone system and voicemail',
            'Create operational SOPs document',
            'Test all operational systems end-to-end',
            'Set up automated reporting dashboards',
            'Configure backup and disaster recovery',
            'Staff training on systems (if applicable)',
            'Launch readiness checklist review',
            'Operations sign-off and approval',
            'Go-live preparation',
        ];
        for ($i = 0; $i < count($ops_tasks); $i++) {
            $ops_activities[] = [
                'id' => 'a_' . $activity_id++,
                'title' => $ops_tasks[$i],
                'description' => '',
                'type' => ($i === count($ops_tasks) - 1 || $i === count($ops_tasks) - 2) ? 'user_approval' : 'ai_executed',
                'day' => 15 + $i,
                'estimated_duration_minutes' => 90,
                'priority' => $i < 5 ? 1 : 2,
            ];
        }

        $milestones[] = [
            'milestone_id' => 'm_' . $milestone_id++,
            'name' => 'Operations Fully Configured',
            'description' => 'All business systems operational — CRM, email, phone, automations',
            'phase' => 'operations',
            'target_day' => 30,
            'prerequisite_milestones' => ['m_1'],
            'success_criteria' => ['CRM capturing leads', 'Email sequences active', 'All automations tested', 'Phone system operational'],
            'kpi_targets' => ['Lead capture form conversion > 5%', 'Email deliverability > 95%'],
            'activities' => $ops_activities,
            'vision_alignment' => "Operational infrastructure to support {$business_name}'s growth",
        ];

        // Phase 3: Launch & Initial Marketing (Days 31-60)
        $launch_activities = [];
        $launch_start = 31;
        $launch_tasks = [
            'Official launch announcement',
            'Social media profiles creation and optimization',
            'First blog post / content piece published',
            'Google Business Profile setup',
            'Launch email campaign to initial contacts',
            'First paid advertising campaign',
            'SEO keyword targeting activated',
            'Content calendar created for next 90 days',
            'Social media posting schedule activated',
            'First week performance review',
            'Lead magnet created and deployed',
            'Email nurture sequence launched',
            'Local SEO optimization (if applicable)',
            'First customer/client acquisition efforts',
            'Referral program setup',
            'Second week performance review',
            'Content marketing — week 3 content published',
            'Paid ads optimization based on data',
            'Community building efforts',
            'Social proof collection (testimonials, reviews)',
            'Third week performance review',
            'Content marketing — week 4 content published',
            'Conversion rate optimization round 1',
            'Email list growth campaign',
            'Partnership outreach begins',
            'Fourth week performance review',
            'Month 1 comprehensive performance review',
            'Strategy adjustment based on data',
            'Month 2 planning and goal setting',
            'Launch phase completion review and approval',
        ];
        for ($i = 0; $i < count($launch_tasks); $i++) {
            $launch_activities[] = [
                'id' => 'a_' . $activity_id++,
                'title' => $launch_tasks[$i],
                'description' => '',
                'type' => (strpos($launch_tasks[$i], 'review') !== false || strpos($launch_tasks[$i], 'approval') !== false) ? 'user_approval' : 'task',
                'day' => $launch_start + $i,
                'estimated_duration_minutes' => 60,
                'priority' => $i < 10 ? 1 : 2,
            ];
        }

        $milestones[] = [
            'milestone_id' => 'm_' . $milestone_id++,
            'name' => 'Market Entry Complete',
            'description' => "First customers acquired, marketing engine running for {$business_name}",
            'phase' => 'launch',
            'target_day' => 60,
            'prerequisite_milestones' => ['m_2'],
            'success_criteria' => ['First 10+ leads generated', 'Social media presence established', 'SEO ranking for target keywords', 'Email list growing'],
            'kpi_targets' => [$north_star ?: 'First measurable revenue/leads'],
            'activities' => $launch_activities,
            'vision_alignment' => $short_term ?: "Establish {$business_name}'s market presence",
        ];

        // Phase 4: Growth (Days 61-120)
        $growth_activities = [];
        $growth_start = 61;
        // Generate weekly cycles of growth activities
        for ($week = 1; $week <= 8; $week++) {
            $week_start = $growth_start + (($week - 1) * 7);
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: SEO scan and content optimization", 'description' => '', 'type' => 'ai_executed', 'day' => $week_start, 'estimated_duration_minutes' => 60, 'priority' => 2];
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: New content creation and publishing", 'description' => '', 'type' => 'task', 'day' => $week_start + 1, 'estimated_duration_minutes' => 90, 'priority' => 2];
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: Lead nurturing and follow-ups", 'description' => '', 'type' => 'task', 'day' => $week_start + 2, 'estimated_duration_minutes' => 60, 'priority' => 1];
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: Paid advertising review and optimization", 'description' => '', 'type' => 'task', 'day' => $week_start + 3, 'estimated_duration_minutes' => 45, 'priority' => 2];
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: Customer engagement and retention activities", 'description' => '', 'type' => 'task', 'day' => $week_start + 4, 'estimated_duration_minutes' => 45, 'priority' => 3];
            $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Week {$week}: Analytics deep dive and KPI tracking", 'description' => '', 'type' => 'ai_executed', 'day' => $week_start + 5, 'estimated_duration_minutes' => 30, 'priority' => 2];
            if ($week % 4 === 0) {
                $growth_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Month " . ($week / 4 + 2) . " performance review", 'description' => '', 'type' => 'user_approval', 'day' => $week_start + 6, 'estimated_duration_minutes' => 60, 'priority' => 1];
            }
        }

        $milestones[] = [
            'milestone_id' => 'm_' . $milestone_id++,
            'name' => 'Sustainable Growth Achieved',
            'description' => "Consistent revenue generation, optimized marketing, growing customer base for {$business_name}",
            'phase' => 'growth',
            'target_day' => 120,
            'prerequisite_milestones' => ['m_3'],
            'success_criteria' => ['Consistent monthly revenue growth', 'Customer acquisition cost optimized', 'Organic traffic growing month-over-month', 'Repeat customer rate > 20%'],
            'kpi_targets' => [$mid_term ?: 'Sustainable growth trajectory'],
            'activities' => $growth_activities,
            'vision_alignment' => $mid_term ?: "Scale {$business_name}'s operations and revenue",
        ];

        // Phase 5: Maturity & Vision Achievement (Day 121 to total_days)
        $maturity_activities = [];
        $maturity_start = 121;
        $remaining_days = $total_days - $maturity_start;
        $remaining_weeks = max(1, floor($remaining_days / 7));

        for ($week = 1; $week <= min($remaining_weeks, 52); $week++) {
            $week_start = $maturity_start + (($week - 1) * 7);
            if ($week_start > $total_days) break;

            $maturity_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Market scan and competitive analysis (Week {$week})", 'description' => '', 'type' => 'ai_executed', 'day' => min($week_start, $total_days), 'estimated_duration_minutes' => 30, 'priority' => 2];
            $maturity_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Growth optimization and new opportunity pursuit (Week {$week})", 'description' => '', 'type' => 'task', 'day' => min($week_start + 2, $total_days), 'estimated_duration_minutes' => 60, 'priority' => 2];

            if ($week % 4 === 0) {
                $maturity_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Monthly strategy review and vision progress check", 'description' => '', 'type' => 'user_approval', 'day' => min($week_start + 6, $total_days), 'estimated_duration_minutes' => 60, 'priority' => 1];
            }
            if ($week % 13 === 0) {
                $maturity_activities[] = ['id' => 'a_' . $activity_id++, 'title' => "Quarterly vision alignment review and roadmap adjustment", 'description' => '', 'type' => 'user_approval', 'day' => min($week_start + 6, $total_days), 'estimated_duration_minutes' => 90, 'priority' => 1];
            }
        }

        // Final vision achievement activity
        $maturity_activities[] = [
            'id' => 'a_' . $activity_id++,
            'title' => 'Business Vision Achievement Assessment',
            'description' => "Comprehensive assessment: Has {$business_name} achieved the stated business vision?",
            'type' => 'user_approval',
            'day' => $total_days,
            'estimated_duration_minutes' => 120,
            'priority' => 1,
        ];

        $milestones[] = [
            'milestone_id' => 'm_' . $milestone_id++,
            'name' => 'Business Vision Achieved',
            'description' => $vision ?: "Full business objectives met for {$business_name}",
            'phase' => 'vision',
            'target_day' => $total_days,
            'prerequisite_milestones' => ['m_4'],
            'success_criteria' => [$long_term ?: 'Business vision fully realized', $north_star ?: 'North star metric achieved'],
            'kpi_targets' => [$long_term ?: 'Vision target'],
            'activities' => $maturity_activities,
            'vision_alignment' => $vision ?: $long_term ?: "Achieve {$business_name}'s full potential",
        ];

        // Build the complete roadmap
        $total_activities = 0;
        foreach ($milestones as $m) {
            $total_activities += count($m['activities'] ?? []);
        }

        $roadmap = [
            'business_name' => $business_name,
            'vision_statement' => $vision,
            'north_star_metric' => $north_star,
            'total_days' => $total_days,
            'estimated_vision_date' => date('Y-m-d', strtotime('+' . $total_days . ' days')),
            'milestones' => $milestones,
            'total_milestones' => count($milestones),
            'total_activities' => $total_activities,
            'summary' => "Structured roadmap for {$business_name}: {$total_days} days from consultation to vision achievement across " . count($milestones) . " milestone phases.",
            'key_risks' => ['Market competition', 'Resource constraints', 'Execution speed'],
            'success_factors' => ['Consistent daily execution', 'Data-driven optimization', 'Customer focus'],
            'generation_method' => 'structured_fallback',
            'generated_at' => current_time('mysql'),
            'vision_anchor' => [
                'business_name' => $business_name,
                'industry' => $industry,
                'vision' => $vision,
                'mission' => $mission,
                'north_star_metric' => $north_star,
                'short_term_target' => $short_term,
                'mid_term_target' => $mid_term,
                'long_term_target' => $long_term,
            ],
            'timeline_calculation' => [
                'method' => 'calculated_from_activities',
                'start_date' => date('Y-m-d'),
                'vision_date' => date('Y-m-d', strtotime('+' . $total_days . ' days')),
                'formatted_duration' => $this->format_days_as_ymd($total_days),
            ],
        ];

        // Persist
        $roadmap_id = $this->persist_roadmap($session_id, $user_id, $roadmap);
        if ($roadmap_id) {
            $this->save_milestones_to_db($roadmap_id, $user_id, $session_id, $roadmap);
            $this->generate_and_save_daily_activities($roadmap_id, $user_id, $roadmap);
            $this->schedule_deep_research($roadmap_id, $user_id);
            $roadmap['roadmap_id'] = $roadmap_id;
        }

        return $roadmap;
    }

    /**
     * Validate AI-generated roadmap and fill any gaps.
     */
    private function validate_and_enrich_roadmap(array $roadmap_json, array $cd) {
        $bp = $cd['business_profile'] ?? [];
        $targets = $bp['targets'] ?? [];
        $identity = $bp['identity'] ?? [];
        $vision_data = $bp['vision'] ?? [];

        // Ensure required fields exist
        if (empty($roadmap_json['business_name'])) {
            $roadmap_json['business_name'] = $identity['name'] ?? $cd['extracted_information']['businessName'] ?? 'Your Business';
        }
        if (empty($roadmap_json['vision_statement'])) {
            $roadmap_json['vision_statement'] = $vision_data['vision'] ?? '';
        }
        if (empty($roadmap_json['north_star_metric'])) {
            $roadmap_json['north_star_metric'] = $targets['north_star_metric'] ?? '';
        }

        // Calculate total_days from activities if not set or seems wrong
        $max_day = 0;
        foreach ($roadmap_json['milestones'] as &$milestone) {
            if (isset($milestone['target_day']) && $milestone['target_day'] > $max_day) {
                $max_day = $milestone['target_day'];
            }
            foreach (($milestone['activities'] ?? []) as $activity) {
                if (isset($activity['day']) && $activity['day'] > $max_day) {
                    $max_day = $activity['day'];
                }
            }
            // Ensure milestone has an ID
            if (empty($milestone['milestone_id'])) {
                $milestone['milestone_id'] = 'm_' . uniqid();
            }
        }
        unset($milestone);

        if ($max_day > 0) {
            $roadmap_json['total_days'] = max($roadmap_json['total_days'] ?? 0, $max_day);
        }
        $roadmap_json['total_days'] = max(90, $roadmap_json['total_days'] ?? 180);

        // Set vision date
        $roadmap_json['estimated_vision_date'] = date('Y-m-d', strtotime('+' . $roadmap_json['total_days'] . ' days'));

        // Calculate totals
        $total_activities = 0;
        foreach ($roadmap_json['milestones'] as $m) {
            $total_activities += count($m['activities'] ?? []);
        }
        $roadmap_json['total_milestones'] = count($roadmap_json['milestones']);
        $roadmap_json['total_activities'] = $total_activities;

        // Add metadata
        $roadmap_json['generation_method'] = 'ai_generated';
        $roadmap_json['generated_at'] = current_time('mysql');
        $roadmap_json['vision_anchor'] = [
            'business_name' => $roadmap_json['business_name'],
            'industry' => $identity['industry'] ?? '',
            'vision' => $roadmap_json['vision_statement'],
            'mission' => $vision_data['mission'] ?? '',
            'north_star_metric' => $roadmap_json['north_star_metric'],
            'short_term_target' => $targets['short_term'] ?? '',
            'mid_term_target' => $targets['mid_term'] ?? '',
            'long_term_target' => $targets['long_term'] ?? '',
        ];
        $roadmap_json['timeline_calculation'] = [
            'method' => 'calculated_from_activities',
            'start_date' => date('Y-m-d'),
            'vision_date' => $roadmap_json['estimated_vision_date'],
            'formatted_duration' => $this->format_days_as_ymd($roadmap_json['total_days']),
        ];

        return $roadmap_json;
    }

    // =========================================================================
    // 2. DAILY ACTIVITIES FROM MILESTONES
    // =========================================================================

    /**
     * Generate daily activities by distributing milestone activities across days.
     * Every day from Day 1 to the vision achievement day has at least one task.
     */
    private function generate_and_save_daily_activities($roadmap_id, $user_id, array $roadmap) {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';
        $start_date = date('Y-m-d');
        $total_days = $roadmap['total_days'] ?? 180;

        // First, insert all milestone-derived activities
        foreach ($roadmap['milestones'] as $milestone) {
            foreach (($milestone['activities'] ?? []) as $activity) {
                $day = $activity['day'] ?? 1;
                $activity_date = date('Y-m-d', strtotime($start_date . ' + ' . ($day - 1) . ' days'));

                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $this->wpdb->insert($table, [
                    'activity_id' => ($activity['id'] ?? ('a_' . uniqid())) . '_' . uniqid(),
                    'roadmap_id' => $roadmap_id,
                    'milestone_id' => $milestone['milestone_id'] ?? null,
                    'user_id' => $user_id,
                    'day_number' => $day,
                    'activity_date' => $activity_date,
                    'activity_title' => $activity['title'] ?? 'Planned activity',
                    'activity_description' => $activity['description'] ?? '',
                    'activity_type' => $activity['type'] ?? 'task',
                    'estimated_duration_minutes' => $activity['estimated_duration_minutes'] ?? 60,
                    'priority' => $activity['priority'] ?? 3,
                    'status' => 'pending',
                    'expected_complete_by' => $activity_date . ' 17:00:00',
                    'ai_generated' => 1,
                    'recurring' => $activity['recurring'] ?? 0,
                    'recurrence_pattern' => $activity['recurrence_pattern'] ?? null,
                    'created_at' => current_time('mysql'),
                    'updated_at' => current_time('mysql'),
                ]);
            }
        }

        // Fill any empty days with daily operational tasks
        $this->fill_empty_days($roadmap_id, $user_id, $start_date, $total_days, $roadmap);
    }

    /**
     * Ensure no day is empty — fill gaps with daily operational activities.
     */
    private function fill_empty_days($roadmap_id, $user_id, $start_date, $total_days, array $roadmap) {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';
        $business_name = $roadmap['business_name'] ?? 'Your Business';
        $north_star = $roadmap['north_star_metric'] ?? '';

        // Get all days that already have activities
        $existing_days = $this->wpdb->get_col($this->wpdb->prepare(
            "SELECT DISTINCT day_number FROM {$table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $existing_days = array_map('intval', $existing_days);

        // Daily operational tasks to rotate through for empty days
        $daily_ops = [
            ["Check {$business_name} dashboard and KPIs", 'analytics', 30],
            ['Review and respond to customer inquiries', 'customer_service', 30],
            ['Social media engagement and posting', 'marketing', 30],
            [$north_star ? "Track progress toward: {$north_star}" : 'Review daily metrics and progress', 'analytics', 20],
            ['Content creation or curation', 'content', 45],
            ['Lead follow-up and nurturing', 'sales', 30],
            ['Plan and prioritize next day tasks', 'planning', 15],
        ];

        for ($day = 1; $day <= $total_days; $day++) {
            if (!in_array($day, $existing_days, true)) {
                $activity_date = date('Y-m-d', strtotime($start_date . ' + ' . ($day - 1) . ' days'));
                // Pick 2-3 operational tasks for this day
                $tasks_for_day = array_slice($daily_ops, ($day - 1) % count($daily_ops), 2);
                if (empty($tasks_for_day)) {
                    $tasks_for_day = [$daily_ops[0]];
                }

                foreach ($tasks_for_day as $task) {
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                    $this->wpdb->insert($table, [
                        'activity_id' => 'daily_' . $day . '_' . uniqid(),
                        'roadmap_id' => $roadmap_id,
                        'milestone_id' => null,
                        'user_id' => $user_id,
                        'day_number' => $day,
                        'activity_date' => $activity_date,
                        'activity_title' => $task[0],
                        'activity_description' => 'Daily operational activity',
                        'activity_type' => 'task',
                        'estimated_duration_minutes' => $task[2],
                        'priority' => 3,
                        'status' => 'pending',
                        'expected_complete_by' => $activity_date . ' 17:00:00',
                        'ai_generated' => 1,
                        'recurring' => 1,
                        'recurrence_pattern' => 'daily',
                        'created_at' => current_time('mysql'),
                        'updated_at' => current_time('mysql'),
                    ]);
                }
            }
        }
    }

    // =========================================================================
    // 3. DAILY REPORTS & PROGRESS TRACKING
    // =========================================================================

    /**
     * Submit a daily report — records what actually happened on a given day.
     * Compares against planned activities and calculates progress impact.
     *
     * @param string $roadmap_id
     * @param int    $user_id
     * @param int    $day_number
     * @param array  $completed_activity_ids  Activity IDs that were completed
     * @param string $user_notes  Optional notes about the day
     * @param string $blockers    Optional blockers encountered
     * @param string $wins        Optional wins of the day
     * @return array Report result with progress data
     */
    public function submit_daily_report($roadmap_id, $user_id, $day_number, array $completed_activity_ids = [], $user_notes = '', $blockers = '', $wins = '') {
        $activities_table = $this->wpdb->prefix . 'vmo_daily_activities';
        $reports_table = $this->wpdb->prefix . 'vmo_daily_reports';
        $roadmaps_table = $this->wpdb->prefix . 'vmo_business_roadmaps';

        // Get the roadmap
        $roadmap = $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT * FROM {$roadmaps_table} WHERE roadmap_id = %s AND user_id = %d",
            $roadmap_id, $user_id
        ));
        if (!$roadmap) {
            return ['success' => false, 'error' => 'Roadmap not found'];
        }

        // Get planned activities for this day
        $planned = $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$activities_table} WHERE roadmap_id = %s AND day_number = %d ORDER BY priority ASC",
            $roadmap_id, $day_number
        ));

        $planned_count = count($planned);
        $planned_ids = wp_list_pluck($planned, 'activity_id');

        // Mark completed activities
        $completed_count = 0;
        $actually_completed = [];
        $uncompleted = [];

        foreach ($planned as $activity) {
            if (in_array($activity->activity_id, $completed_activity_ids, true)) {
                // Mark as completed
                $this->wpdb->update(
                    $activities_table,
                    ['status' => 'completed', 'actual_completed_at' => current_time('mysql'), 'updated_at' => current_time('mysql')],
                    ['activity_id' => $activity->activity_id]
                );
                $completed_count++;
                $actually_completed[] = $activity->activity_id;
            } else {
                $uncompleted[] = $activity->activity_id;
            }
        }

        // Calculate progress delta
        $total_activities_in_roadmap = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $progress_delta = $total_activities_in_roadmap > 0
            ? round(($completed_count / $total_activities_in_roadmap) * 100, 2)
            : 0.00;

        // Calculate completion adjustment
        // If all tasks completed: no adjustment
        // If some tasks missed: add days proportional to missed tasks
        $missed_count = $planned_count - $completed_count;
        $estimated_adjustment = 0;
        if ($missed_count > 0 && $planned_count > 0) {
            // Each missed task adds approximately 1 day to the estimate
            $estimated_adjustment = $missed_count;
        }

        // Get previous cumulative adjustment
        $prev_cumulative = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT cumulative_adjustment FROM {$reports_table} WHERE roadmap_id = %s AND day_number < %d ORDER BY day_number DESC LIMIT 1",
            $roadmap_id, $day_number
        ));
        $cumulative_adjustment = $prev_cumulative + $estimated_adjustment;

        // Calculate streak
        $prev_streak = 0;
        if ($missed_count === 0 && $planned_count > 0) {
            $prev_streak = (int) $this->wpdb->get_var($this->wpdb->prepare(
                "SELECT streak_count FROM {$reports_table} WHERE roadmap_id = %s AND day_number < %d ORDER BY day_number DESC LIMIT 1",
                $roadmap_id, $day_number
            ));
            $prev_streak++;
        }

        // Day score: 0-100 based on completion percentage
        $day_score = $planned_count > 0 ? round(($completed_count / $planned_count) * 100) : 100;

        // Carry forward uncompleted tasks to next day
        $carried_forward = [];
        if (!empty($uncompleted)) {
            $report_date = date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . ($day_number - 1) . ' days'));
            $next_date = date('Y-m-d', strtotime($report_date . ' + 1 day'));
            $next_day = $day_number + 1;

            foreach ($uncompleted as $activity_id) {
                $original = $this->wpdb->get_row($this->wpdb->prepare(
                    "SELECT * FROM {$activities_table} WHERE activity_id = %s",
                    $activity_id
                ));
                if ($original) {
                    $new_id = 'carried_' . $day_number . '_' . uniqid();
                    $this->wpdb->insert($activities_table, [
                        'activity_id' => $new_id,
                        'roadmap_id' => $roadmap_id,
                        'milestone_id' => $original->milestone_id,
                        'user_id' => $user_id,
                        'day_number' => $next_day,
                        'activity_date' => $next_date,
                        'activity_title' => '[Carried Forward] ' . $original->activity_title,
                        'activity_description' => 'Carried forward from Day ' . $day_number . '. ' . ($original->activity_description ?? ''),
                        'activity_type' => $original->activity_type,
                        'estimated_duration_minutes' => $original->estimated_duration_minutes,
                        'priority' => max(1, $original->priority - 1), // Increase priority
                        'status' => 'pending',
                        'expected_complete_by' => $next_date . ' 17:00:00',
                        'ai_generated' => 1,
                        'created_at' => current_time('mysql'),
                        'updated_at' => current_time('mysql'),
                    ]);
                    $carried_forward[] = $new_id;

                    // Mark original as delayed
                    $this->wpdb->update(
                        $activities_table,
                        ['status' => 'delayed', 'updated_at' => current_time('mysql')],
                        ['activity_id' => $activity_id]
                    );
                }
            }
        }

        // Save the daily report
        $report_id = 'report_' . $day_number . '_' . uniqid();
        $report_date = date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . ($day_number - 1) . ' days'));

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $this->wpdb->replace($reports_table, [
            'report_id' => $report_id,
            'roadmap_id' => $roadmap_id,
            'user_id' => $user_id,
            'session_id' => $roadmap->session_id,
            'day_number' => $day_number,
            'report_date' => $report_date,
            'planned_activities_count' => $planned_count,
            'completed_activities_count' => $completed_count,
            'completed_activity_ids' => wp_json_encode($actually_completed),
            'uncompleted_activity_ids' => wp_json_encode($uncompleted),
            'carried_forward_ids' => wp_json_encode($carried_forward),
            'user_notes' => $user_notes,
            'blockers' => $blockers,
            'wins' => $wins,
            'progress_delta' => $progress_delta,
            'estimated_completion_adjustment' => $estimated_adjustment,
            'cumulative_adjustment' => $cumulative_adjustment,
            'day_score' => $day_score,
            'streak_count' => $prev_streak,
            'submitted_at' => current_time('mysql'),
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ]);

        // Update the roadmap's estimated completion date based on cumulative adjustment
        $original_total_days = (int) $roadmap->total_duration_days;
        $adjusted_total_days = $original_total_days + $cumulative_adjustment;
        $new_vision_date = date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . $adjusted_total_days . ' days'));

        $this->wpdb->update(
            $roadmaps_table,
            [
                'current_day_number' => $day_number,
                'vision_target_date' => $new_vision_date,
                'updated_at' => current_time('mysql'),
            ],
            ['roadmap_id' => $roadmap_id]
        );

        // Also update progress tracking
        $this->update_progress_tracking($roadmap_id, $user_id, $day_number);

        return [
            'success' => true,
            'report_id' => $report_id,
            'day_number' => $day_number,
            'report_date' => $report_date,
            'planned_count' => $planned_count,
            'completed_count' => $completed_count,
            'missed_count' => $missed_count,
            'day_score' => $day_score,
            'progress_delta' => $progress_delta,
            'estimated_adjustment_days' => $estimated_adjustment,
            'cumulative_adjustment_days' => $cumulative_adjustment,
            'original_vision_date' => date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . $original_total_days . ' days')),
            'adjusted_vision_date' => $new_vision_date,
            'streak' => $prev_streak,
            'carried_forward_count' => count($carried_forward),
        ];
    }

    /**
     * Update progress tracking record for a specific day.
     */
    private function update_progress_tracking($roadmap_id, $user_id, $day_number) {
        $activities_table = $this->wpdb->prefix . 'vmo_daily_activities';
        $tracking_table = $this->wpdb->prefix . 'vmo_progress_tracking';

        // Expected activities by this day
        $expected = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND day_number <= %d",
            $roadmap_id, $day_number
        ));

        // Actually completed
        $completed = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND status = 'completed'",
            $roadmap_id
        ));

        // Total
        $total = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));

        $progress_pct = $total > 0 ? round(($completed / $total) * 100, 2) : 0;
        $expected_pct = $total > 0 ? round(($expected / $total) * 100, 2) : 0;

        // Schedule health
        $diff = $completed - $expected;
        if ($diff >= 2) {
            $health = 'ahead';
        } elseif ($diff >= -1) {
            $health = 'on_track';
        } elseif ($diff >= -5) {
            $health = 'behind';
        } else {
            $health = 'critical';
        }

        // Weekly velocity
        $velocity = (float) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND status = 'completed' AND actual_completed_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)",
            $roadmap_id
        ));

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $this->wpdb->replace($tracking_table, [
            'user_id' => $user_id,
            'roadmap_id' => $roadmap_id,
            'tracking_date' => date('Y-m-d'),
            'day_number' => $day_number,
            'expected_activities' => $expected,
            'actual_completed' => $completed,
            'expected_milestones' => 0,
            'actual_milestones' => 0,
            'progress_percentage' => $progress_pct,
            'expected_percentage' => $expected_pct,
            'schedule_health' => $health,
            'days_ahead_behind' => $diff,
            'weekly_velocity' => $velocity,
            'created_at' => current_time('mysql'),
        ]);
    }

    /**
     * Get comprehensive progress data for a roadmap.
     */
    public function get_progress_summary($roadmap_id, $user_id) {
        $roadmaps_table = $this->wpdb->prefix . 'vmo_business_roadmaps';
        $activities_table = $this->wpdb->prefix . 'vmo_daily_activities';
        $reports_table = $this->wpdb->prefix . 'vmo_daily_reports';
        $milestones_table = $this->wpdb->prefix . 'vmo_roadmap_milestones';

        $roadmap = $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT * FROM {$roadmaps_table} WHERE roadmap_id = %s AND user_id = %d",
            $roadmap_id, $user_id
        ));
        if (!$roadmap) {
            return null;
        }

        // Current day
        $start = new \DateTime($roadmap->roadmap_start_date);
        $today = new \DateTime(date('Y-m-d'));
        $current_day = max(1, $today->diff($start)->days + 1);

        // Activities stats
        $total_activities = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $completed_activities = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND status = 'completed'",
            $roadmap_id
        ));
        $pending_today = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND day_number = %d AND status = 'pending'",
            $roadmap_id, $current_day
        ));

        // Milestone stats
        $total_milestones = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$milestones_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $completed_milestones = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$milestones_table} WHERE roadmap_id = %s AND (status = 'done' OR status = 'completed')",
            $roadmap_id
        ));

        // Report stats
        $total_reports = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$reports_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $latest_report = $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT * FROM {$reports_table} WHERE roadmap_id = %s ORDER BY day_number DESC LIMIT 1",
            $roadmap_id
        ));

        // Overall progress
        $progress_pct = $total_activities > 0 ? round(($completed_activities / $total_activities) * 100, 2) : 0;

        // Estimated dates
        $original_total = (int) $roadmap->total_duration_days;
        $cumulative_adj = $latest_report ? (int) $latest_report->cumulative_adjustment : 0;
        $adjusted_total = $original_total + $cumulative_adj;
        $original_vision_date = date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . $original_total . ' days'));
        $adjusted_vision_date = date('Y-m-d', strtotime($roadmap->roadmap_start_date . ' + ' . $adjusted_total . ' days'));
        $days_remaining = max(0, $adjusted_total - $current_day);

        return [
            'roadmap_id' => $roadmap_id,
            'business_name' => $roadmap->business_vision,
            'current_day' => $current_day,
            'total_days_original' => $original_total,
            'total_days_adjusted' => $adjusted_total,
            'cumulative_adjustment' => $cumulative_adj,
            'original_vision_date' => $original_vision_date,
            'adjusted_vision_date' => $adjusted_vision_date,
            'days_remaining' => $days_remaining,
            'progress_percentage' => $progress_pct,
            'total_activities' => $total_activities,
            'completed_activities' => $completed_activities,
            'pending_today' => $pending_today,
            'total_milestones' => $total_milestones,
            'completed_milestones' => $completed_milestones,
            'total_reports_submitted' => $total_reports,
            'current_streak' => $latest_report ? (int) $latest_report->streak_count : 0,
            'latest_day_score' => $latest_report ? (int) $latest_report->day_score : null,
            'schedule_health' => $this->calculate_schedule_health($completed_activities, $current_day, $total_activities, $original_total),
            'formatted_remaining' => $this->format_days_as_ymd($days_remaining),
            'formatted_total' => $this->format_days_as_ymd($adjusted_total),
        ];
    }

    /**
     * Calculate schedule health status.
     */
    private function calculate_schedule_health($completed, $current_day, $total_activities, $total_days) {
        if ($total_days <= 0 || $total_activities <= 0) return 'on_track';
        $expected_pct = ($current_day / $total_days) * 100;
        $actual_pct = ($completed / $total_activities) * 100;
        $diff = $actual_pct - $expected_pct;

        if ($diff >= 5) return 'ahead';
        if ($diff >= -3) return 'on_track';
        if ($diff >= -10) return 'behind';
        return 'critical';
    }

    // =========================================================================
    // 4. DYNAMIC ADJUSTMENT
    // =========================================================================

    /**
     * Apply roadmap adjustments from background research findings.
     * Called when user approves adjustments suggested by deep research scans.
     *
     * @param string $roadmap_id
     * @param int    $user_id
     * @param array  $adjustments Array of adjustment objects
     * @return array Results of applied adjustments
     */
    public function apply_adjustments($roadmap_id, $user_id, array $adjustments) {
        $results = [];

        foreach ($adjustments as $adj) {
            $type = $adj['type'] ?? $adj['adjustment_type'] ?? '';

            switch ($type) {
                case 'add_milestone':
                    $result = $this->add_milestone($roadmap_id, $user_id, $adj);
                    $results[] = ['type' => 'add_milestone', 'success' => (bool) $result];
                    break;

                case 'add_activity':
                    $result = $this->add_activity($roadmap_id, $user_id, $adj);
                    $results[] = ['type' => 'add_activity', 'success' => (bool) $result];
                    break;

                case 'modify_timeline':
                case 'modify_date':
                    $result = $this->modify_milestone_timeline($roadmap_id, $adj);
                    $results[] = ['type' => 'modify_timeline', 'success' => (bool) $result];
                    break;

                case 'remove_activity':
                    $result = $this->remove_activity($adj['activity_id'] ?? '');
                    $results[] = ['type' => 'remove_activity', 'success' => (bool) $result];
                    break;

                case 'reprioritize':
                    $result = $this->reprioritize_activity($adj['activity_id'] ?? '', $adj['new_priority'] ?? 3);
                    $results[] = ['type' => 'reprioritize', 'success' => (bool) $result];
                    break;
            }
        }

        // Mark research as applied
        if (!empty($adj['research_id'])) {
            $this->wpdb->update(
                $this->wpdb->prefix . 'vmo_deep_research_results',
                ['applied_to_roadmap' => 1, 'applied_at' => current_time('mysql')],
                ['research_id' => $adj['research_id']]
            );
        }

        // Recalculate roadmap totals
        $this->recalculate_roadmap_totals($roadmap_id);

        return $results;
    }

    private function add_milestone($roadmap_id, $user_id, array $data) {
        $milestones_table = $this->wpdb->prefix . 'vmo_roadmap_milestones';
        $milestone_id = 'milestone_adj_' . uniqid();

        return $this->wpdb->insert($milestones_table, [
            'milestone_id' => $milestone_id,
            'roadmap_id' => $roadmap_id,
            'user_id' => $user_id,
            'phase_name' => $data['phase'] ?? 'Adjustment',
            'title' => $data['title'] ?? $data['name'] ?? 'New milestone',
            'milestone_title' => $data['title'] ?? $data['name'] ?? 'New milestone',
            'milestone_description' => $data['description'] ?? '',
            'target_date' => $data['target_date'] ?? null,
            'target_day' => $data['target_day'] ?? null,
            'status' => 'planned',
            'priority' => $data['priority'] ?? 2,
            'vision_alignment' => $data['vision_alignment'] ?? '',
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ]);
    }

    private function add_activity($roadmap_id, $user_id, array $data) {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';
        $day = $data['day'] ?? $data['day_number'] ?? 1;
        $roadmap = $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT roadmap_start_date FROM {$this->wpdb->prefix}vmo_business_roadmaps WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $start_date = $roadmap ? $roadmap->roadmap_start_date : date('Y-m-d');
        $activity_date = $data['date'] ?? $data['activity_date'] ?? date('Y-m-d', strtotime($start_date . ' + ' . ($day - 1) . ' days'));

        return $this->wpdb->insert($table, [
            'activity_id' => 'adj_' . uniqid(),
            'roadmap_id' => $roadmap_id,
            'milestone_id' => $data['milestone_id'] ?? null,
            'user_id' => $user_id,
            'day_number' => $day,
            'activity_date' => $activity_date,
            'activity_title' => $data['title'] ?? 'Adjusted activity',
            'activity_description' => $data['description'] ?? '',
            'activity_type' => $data['type'] ?? 'task',
            'estimated_duration_minutes' => $data['duration'] ?? 60,
            'priority' => $data['priority'] ?? 2,
            'status' => 'pending',
            'expected_complete_by' => $activity_date . ' 17:00:00',
            'ai_generated' => 1,
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ]);
    }

    private function modify_milestone_timeline($roadmap_id, array $data) {
        $table = $this->wpdb->prefix . 'vmo_roadmap_milestones';
        $update = [];
        if (!empty($data['new_target_date'])) $update['target_date'] = $data['new_target_date'];
        if (!empty($data['new_target_day'])) $update['target_day'] = $data['new_target_day'];
        $update['updated_at'] = current_time('mysql');

        $where = ['roadmap_id' => $roadmap_id];
        if (!empty($data['milestone_id'])) {
            $where['milestone_id'] = $data['milestone_id'];
        } elseif (!empty($data['milestone_title'])) {
            // Use title-based matching
            return $this->wpdb->query($this->wpdb->prepare(
                "UPDATE {$table} SET target_date = %s, updated_at = %s WHERE roadmap_id = %s AND (title LIKE %s OR milestone_title LIKE %s)",
                $data['new_target_date'] ?? $data['new_date'] ?? date('Y-m-d', strtotime('+60 days')),
                current_time('mysql'),
                $roadmap_id,
                '%' . $data['milestone_title'] . '%',
                '%' . $data['milestone_title'] . '%'
            ));
        }

        return $this->wpdb->update($table, $update, $where);
    }

    private function remove_activity($activity_id) {
        if (empty($activity_id)) return false;
        return $this->wpdb->update(
            $this->wpdb->prefix . 'vmo_daily_activities',
            ['status' => 'skipped', 'updated_at' => current_time('mysql')],
            ['activity_id' => $activity_id]
        );
    }

    private function reprioritize_activity($activity_id, $new_priority) {
        if (empty($activity_id)) return false;
        return $this->wpdb->update(
            $this->wpdb->prefix . 'vmo_daily_activities',
            ['priority' => (int) $new_priority, 'updated_at' => current_time('mysql')],
            ['activity_id' => $activity_id]
        );
    }

    /**
     * Recalculate roadmap totals after adjustments.
     */
    private function recalculate_roadmap_totals($roadmap_id) {
        $activities_table = $this->wpdb->prefix . 'vmo_daily_activities';
        $roadmaps_table = $this->wpdb->prefix . 'vmo_business_roadmaps';
        $milestones_table = $this->wpdb->prefix . 'vmo_roadmap_milestones';

        $total_activities = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$activities_table} WHERE roadmap_id = %s AND status != 'skipped'",
            $roadmap_id
        ));
        $total_milestones = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$milestones_table} WHERE roadmap_id = %s",
            $roadmap_id
        ));
        $max_day = (int) $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT MAX(day_number) FROM {$activities_table} WHERE roadmap_id = %s AND status != 'skipped'",
            $roadmap_id
        ));

        $this->wpdb->update($roadmaps_table, [
            'total_activities' => $total_activities,
            'total_milestones' => $total_milestones,
            'total_duration_days' => max($max_day, 90),
            'updated_at' => current_time('mysql'),
        ], ['roadmap_id' => $roadmap_id]);
    }

    // =========================================================================
    // 5. DOWNLOAD / EXPORT
    // =========================================================================

    /**
     * Export daily activities for a date range.
     *
     * @param string $roadmap_id
     * @param int    $user_id
     * @param string $start_date YYYY-MM-DD
     * @param string $end_date   YYYY-MM-DD
     * @param string $format     json|csv
     * @return array Data array for export
     */
    public function export_daily_activities($roadmap_id, $user_id, $start_date = null, $end_date = null, $format = 'json') {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';

        $where = "roadmap_id = %s AND user_id = %d";
        $params = [$roadmap_id, $user_id];

        if ($start_date) {
            $where .= " AND activity_date >= %s";
            $params[] = $start_date;
        }
        if ($end_date) {
            $where .= " AND activity_date <= %s";
            $params[] = $end_date;
        }

        $rows = $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE {$where} ORDER BY day_number ASC, priority ASC",
            ...$params
        ), ARRAY_A);

        return $rows ?: [];
    }

    /**
     * Export daily reports for a date range.
     */
    public function export_daily_reports($roadmap_id, $user_id, $start_date = null, $end_date = null) {
        $table = $this->wpdb->prefix . 'vmo_daily_reports';

        $where = "roadmap_id = %s AND user_id = %d";
        $params = [$roadmap_id, $user_id];

        if ($start_date) {
            $where .= " AND report_date >= %s";
            $params[] = $start_date;
        }
        if ($end_date) {
            $where .= " AND report_date <= %s";
            $params[] = $end_date;
        }

        $rows = $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE {$where} ORDER BY day_number ASC",
            ...$params
        ), ARRAY_A);

        return $rows ?: [];
    }

    /**
     * Export milestones.
     */
    public function export_milestones($roadmap_id, $user_id) {
        $table = $this->wpdb->prefix . 'vmo_roadmap_milestones';

        return $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE roadmap_id = %s AND user_id = %d ORDER BY target_day ASC, priority ASC",
            $roadmap_id, $user_id
        ), ARRAY_A) ?: [];
    }

    // =========================================================================
    // 6. PERSISTENCE HELPERS
    // =========================================================================

    /**
     * Persist roadmap to the business_roadmaps tracking table.
     */
    private function persist_roadmap($session_id, $user_id, array $roadmap) {
        $table = $this->wpdb->prefix . 'vmo_business_roadmaps';
        $roadmap_id = 'roadmap_' . uniqid();

        // Deactivate any existing roadmaps for this session
        $this->wpdb->update(
            $table,
            ['is_active' => 0, 'status' => 'archived', 'updated_at' => current_time('mysql')],
            ['session_id' => $session_id, 'user_id' => $user_id, 'is_active' => 1]
        );

        $result = $this->wpdb->insert($table, [
            'roadmap_id' => $roadmap_id,
            'user_id' => $user_id,
            'session_id' => $session_id,
            'business_vision' => $roadmap['vision_statement'] ?? '',
            'roadmap_version' => 1,
            'roadmap_data' => wp_json_encode($roadmap),
            'total_milestones' => $roadmap['total_milestones'] ?? count($roadmap['milestones'] ?? []),
            'total_activities' => $roadmap['total_activities'] ?? 0,
            'total_duration_days' => $roadmap['total_days'] ?? 180,
            'roadmap_start_date' => date('Y-m-d'),
            'vision_target_date' => $roadmap['estimated_vision_date'] ?? date('Y-m-d', strtotime('+180 days')),
            'current_day_number' => 1,
            'status' => 'active',
            'is_active' => 1,
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql'),
        ]);

        return $result ? $roadmap_id : false;
    }

    /**
     * Save milestones to the dedicated milestones table.
     */
    private function save_milestones_to_db($roadmap_id, $user_id, $session_id, array $roadmap) {
        $table = $this->wpdb->prefix . 'vmo_roadmap_milestones';

        // Clear old milestones for this roadmap
        $this->wpdb->delete($table, ['roadmap_id' => $roadmap_id, 'user_id' => $user_id]);

        foreach ($roadmap['milestones'] as $index => $milestone) {
            $this->wpdb->insert($table, [
                'milestone_id' => $milestone['milestone_id'] ?? ('m_' . ($index + 1)),
                'roadmap_id' => $roadmap_id,
                'user_id' => $user_id,
                'session_id' => $session_id,
                'phase_number' => $index + 1,
                'phase_name' => $milestone['phase'] ?? ('Phase ' . ($index + 1)),
                'title' => $milestone['name'] ?? $milestone['title'] ?? 'Milestone ' . ($index + 1),
                'milestone_title' => $milestone['name'] ?? $milestone['title'] ?? 'Milestone ' . ($index + 1),
                'milestone_description' => $milestone['description'] ?? '',
                'target_date' => isset($milestone['target_day']) ? date('Y-m-d', strtotime('+' . $milestone['target_day'] . ' days')) : null,
                'target_day' => $milestone['target_day'] ?? null,
                'owner' => 'jarvis',
                'status' => 'planned',
                'progress' => 0,
                'progress_percentage' => 0.00,
                'success_criteria' => wp_json_encode($milestone['success_criteria'] ?? []),
                'kpi_targets' => wp_json_encode($milestone['kpi_targets'] ?? []),
                'dependent_on_milestone_id' => is_array($milestone['prerequisite_milestones'] ?? null) ? ($milestone['prerequisite_milestones'][0] ?? null) : ($milestone['prerequisite_milestones'] ?? null),
                'priority' => $milestone['priority'] ?? ($index + 1),
                'vision_alignment' => $milestone['vision_alignment'] ?? '',
                'notes' => $milestone['notes'] ?? '',
                'created_at' => current_time('mysql'),
                'updated_at' => current_time('mysql'),
            ]);
        }
    }

    /**
     * Schedule background deep research for this roadmap.
     */
    private function schedule_deep_research($roadmap_id, $user_id) {
        if (!function_exists('wp_schedule_event')) {
            return;
        }

        wp_clear_scheduled_hook('vmo_weekly_deep_research', [$roadmap_id, $user_id]);

        // Default to weekly; plan-gated check happens in the cron callback
        $next_run = strtotime('+1 day 9:00 AM');
        wp_schedule_event($next_run, 'weekly', 'vmo_weekly_deep_research', [$roadmap_id, $user_id]);

        error_log("VMO Vision Roadmap Engine: Deep research scheduled for user {$user_id}, roadmap {$roadmap_id}");
    }

    // =========================================================================
    // 7. QUERY HELPERS
    // =========================================================================

    /**
     * Get the user's active roadmap.
     */
    public function get_active_roadmap($user_id, $session_id = null) {
        $table = $this->wpdb->prefix . 'vmo_business_roadmaps';

        if ($session_id) {
            return $this->wpdb->get_row($this->wpdb->prepare(
                "SELECT * FROM {$table} WHERE session_id = %s AND user_id = %d AND is_active = 1 ORDER BY created_at DESC LIMIT 1",
                $session_id, $user_id
            ));
        }

        return $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE user_id = %d AND is_active = 1 ORDER BY created_at DESC LIMIT 1",
            $user_id
        ));
    }

    /**
     * Get today's activities for a roadmap.
     */
    public function get_todays_activities($roadmap_id, $user_id) {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';

        return $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE roadmap_id = %s AND user_id = %d AND activity_date = %s ORDER BY priority ASC",
            $roadmap_id, $user_id, date('Y-m-d')
        ));
    }

    /**
     * Get activities for a specific day number.
     */
    public function get_day_activities($roadmap_id, $day_number) {
        $table = $this->wpdb->prefix . 'vmo_daily_activities';

        return $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE roadmap_id = %s AND day_number = %d ORDER BY priority ASC",
            $roadmap_id, $day_number
        ));
    }

    /**
     * Get daily report for a specific day.
     */
    public function get_daily_report($roadmap_id, $day_number) {
        $table = $this->wpdb->prefix . 'vmo_daily_reports';

        return $this->wpdb->get_row($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE roadmap_id = %s AND day_number = %d",
            $roadmap_id, $day_number
        ));
    }

    /**
     * Get pending research adjustments (not yet applied).
     */
    public function get_pending_adjustments($roadmap_id) {
        $table = $this->wpdb->prefix . 'vmo_deep_research_results';

        return $this->wpdb->get_results($this->wpdb->prepare(
            "SELECT * FROM {$table} WHERE roadmap_id = %s AND applied_to_roadmap = 0 ORDER BY research_date DESC",
            $roadmap_id
        ));
    }

    // =========================================================================
    // 8. OPENAI HELPER
    // =========================================================================

    /**
     * Call OpenAI and return parsed JSON.
     */
    private function call_openai_json(array $messages, $max_tokens = 4000, $temperature = 0.3) {
        if (empty($this->api_key)) {
            error_log('VMO Vision Roadmap Engine: No API key available');
            return [];
        }

        $model = defined('VMO_OPENAI_MODEL') ? VMO_OPENAI_MODEL : 'gpt-5.2-2025-12-11';
        $payload = [
            'model' => $model,
            'messages' => $messages,
            'temperature' => $temperature,
        ];

        // Handle token parameter based on model
        if (function_exists('vmo_get_token_param')) {
            $payload = array_merge($payload, vmo_get_token_param($model, $max_tokens));
        } else {
            $payload['max_tokens'] = $max_tokens;
        }

        $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [
            'headers' => [
                'Authorization' => 'Bearer ' . $this->api_key,
                'Content-Type' => 'application/json',
            ],
            'body' => wp_json_encode($payload),
            'timeout' => 90, // Longer timeout for roadmap generation
            'method' => 'POST',
        ]);

        // Fallback to gpt-4o if primary model fails
        if (is_wp_error($response) || wp_remote_retrieve_response_code($response) >= 400) {
            error_log('VMO Vision Roadmap Engine: Primary model failed, falling back to gpt-4o');
            $payload['model'] = 'gpt-4o';
            if (isset($payload['max_completion_tokens'])) {
                $payload['max_tokens'] = $payload['max_completion_tokens'];
                unset($payload['max_completion_tokens']);
            }
            $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->api_key,
                    'Content-Type' => 'application/json',
                ],
                'body' => wp_json_encode($payload),
                'timeout' => 90,
                'method' => 'POST',
            ]);
        }

        if (is_wp_error($response)) {
            error_log('VMO Vision Roadmap Engine: API call failed - ' . $response->get_error_message());
            return [];
        }

        $body = wp_remote_retrieve_body($response);
        $decoded = json_decode($body, true);

        $content = '';
        if (is_array($decoded) && isset($decoded['choices'][0]['message']['content'])) {
            $content = $decoded['choices'][0]['message']['content'];
        }
        if (!is_string($content) || trim($content) === '') {
            return [];
        }

        $content = trim($content);
        // Strip code fences
        if (preg_match('/^```(?:json)?\s*(.*)```$/is', $content, $fenced)) {
            $content = trim($fenced[1]);
        }

        $parsed = json_decode($content, true);
        return is_array($parsed) ? $parsed : [];
    }

    /**
     * Format days as Y:M:D string.
     */
    private function format_days_as_ymd($total_days) {
        $total_days = max(0, (int) $total_days);
        $years = floor($total_days / 365);
        $remaining = $total_days % 365;
        $months = floor($remaining / 30);
        $days = $remaining % 30;

        if ($years > 0) {
            return "{$years}Y : {$months}M : {$days}D";
        } elseif ($months > 0) {
            return "{$months}M : {$days}D";
        }
        return "{$days} Days";
    }
}
