<?php
/**
 * Dashboard Controller
 *
 * @package Freelance_Studio
 */

class FS_Dashboard_Controller {

    /**
     * Display the dashboard
     */
    public function index() {
        // Get dashboard statistics
        $stats = $this->get_dashboard_stats();
        
        // Get recent projects (5 most recent by updated_at or created_at)
        $recent_projects = FS_Project::get_all(array(
            'limit' => 5,
            'orderby' => 'created_at',
            'order' => 'DESC'
        ));
        
        // Get invoices with status indicators (paid, sent, overdue)
        $dashboard_invoices = $this->get_dashboard_invoices();
        
        // Get task widget status preferences (default: pending, in_progress)
        $task_widget_statuses = get_option('fs_dashboard_task_statuses', array('pending', 'in_progress'));
        if (empty($task_widget_statuses)) {
            $task_widget_statuses = array('pending', 'in_progress');
        }
        
        // Get incomplete tasks based on user preferences
        // Use same persistent sort as task list page
        $task_sort_orderby = get_user_meta(get_current_user_id(), 'fs_task_sort_orderby', true) ?: 'due_date';
        $task_sort_order = get_user_meta(get_current_user_id(), 'fs_task_sort_order', true) ?: 'ASC';
        
        $incomplete_tasks = FS_Task::get_all(array(
            'status' => $task_widget_statuses,
            'limit' => 10,
            'orderby' => $task_sort_orderby,
            'order' => $task_sort_order,
            'exclude_orphaned' => true, // v3.8.1 - Don't show tasks from deleted projects
            'smart_recurring' => true,  // Only show active recurring instance per series; hide parent templates
        ));
        
        // Get internal tasks if internal tracking is enabled
        $internal_tasks = array();
        $internal_tracking_enabled = get_option('fs_internal_tracking_enabled', '0') === '1';
        if ($internal_tracking_enabled) {
            $internal_tasks = FS_Task::get_internal_tasks(array('limit' => 10));
        }
        
        // Get projects for quick add task dropdown
        $projects_dropdown = FS_Project::get_for_dropdown();
        
        // Get running timer
        $running_timer = FS_Time_Entry::get_running();
        
        // Get pending proposals (sent, viewed, revision_requested)
        $pending_proposals = FS_Proposal::get_all(array(
            'status' => array('sent', 'viewed', 'revision_requested', 'revised'),
            'limit' => 5,
        ));
        
        // Get unsigned contracts (sent, viewed)
        $unsigned_contracts = FS_Contract::get_all(array(
            'status' => array('sent', 'viewed'),
        ));
        
        // Get tax/financial summary for combined reporting card
        $financial_summary = $this->get_financial_summary();
        
        // Get time tracking goals data
        $time_goals = $this->get_time_goals();
        
        // Get recent timer sessions
        $recent_sessions = FS_Time_Entry::get_recent_sessions(8);
        
        // Get upcoming events for calendar widget (excluding tasks)
        $upcoming_events = FS_Calendar_Controller::get_upcoming_events_no_tasks(7);
        
        // Get calendar data for mini-calendar widget
        $calendar_data = $this->get_calendar_widget_data();
        
        // Get week data for week-view widget (includes all events including tasks)
        $week_data = $this->get_week_widget_data();
        
        // Get action items for "Action Needed" widget
        $action_items = $this->get_action_items();
        
        // Load the view
        include JEEB_FS_PLUGIN_DIR . 'includes/views/dashboard/index.php';
    }
    
    /**
     * Get time tracking goals and progress
     *
     * @return array
     */
    private function get_time_goals() {
        $weekly_goal = floatval(get_option('fs_weekly_goal', 40));
        $daily_goal = floatval(get_option('fs_daily_goal', 8));
        
        // Get current week's time (Monday to Sunday)
        $week_start = gmdate('Y-m-d', strtotime('monday this week'));
        $week_end = gmdate('Y-m-d', strtotime('sunday this week'));
        $today = gmdate('Y-m-d');
        
        // Get time entries for current week
        $week_entries = FS_Time_Entry::get_all(array(
            'user_id' => get_current_user_id(),
            'date_from' => $week_start,
            'date_to' => $week_end,
            'running' => false,
        ));
        
        // Get time entries for today
        $today_entries = FS_Time_Entry::get_all(array(
            'user_id' => get_current_user_id(),
            'date_from' => $today,
            'date_to' => $today,
            'running' => false,
        ));
        
        // Calculate totals
        $week_seconds = 0;
        $today_seconds = 0;
        
        foreach ($week_entries as $entry) {
            $week_seconds += intval($entry->duration);
        }
        
        foreach ($today_entries as $entry) {
            $today_seconds += intval($entry->duration);
        }
        
        // Add running timer if any
        $running_timer = FS_Time_Entry::get_running();
        if ($running_timer) {
            $week_seconds += $running_timer->current_duration;
            $today_seconds += $running_timer->current_duration;
        }
        
        // Calculate progress percentages
        $weekly_progress = $weekly_goal > 0 ? min(100, ($week_seconds / 3600) / $weekly_goal * 100) : 0;
        $daily_progress = $daily_goal > 0 ? min(100, ($today_seconds / 3600) / $daily_goal * 100) : 0;
        
        return array(
            'weekly_goal' => $weekly_goal,
            'weekly_hours' => round($week_seconds / 3600, 1),
            'weekly_progress' => round($weekly_progress, 1),
            'daily_goal' => $daily_goal,
            'daily_hours' => round($today_seconds / 3600, 1),
            'daily_progress' => round($daily_progress, 1),
            'week_start' => $week_start,
            'week_end' => $week_end,
        );
    }

    /**
     * Get action items that need the freelancer's attention
     *
     * @return array Array of action item objects with type, priority, title, subtitle, url, icon, badge_class
     */
    private function get_action_items() {
        $items = array();
        
        // 1. Requested tasks (client-submitted tasks awaiting action)
        $requested_tasks = FS_Task::get_all(array(
            'status' => 'requested',
            'limit' => 10,
            'exclude_orphaned' => true,
        ));
        foreach ($requested_tasks as $task) {
            $items[] = (object) array(
                'type' => 'task_requested',
                'priority' => 1,
                'icon' => 'dashicons-clipboard',
                'badge_class' => 'status-pending',
                'badge_text' => __('Task Requested', 'freelance-studio'),
                'title' => $task->name,
                'subtitle' => $task->project_name ?? '',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $task->project_id . '&tab=tasks'),
                'date' => $task->created_at ?? null,
            );
        }
        
        // 2. Proposals with revision requests
        $revision_proposals = FS_Proposal::get_all(array(
            'status' => 'revision_requested',
            'limit' => 10,
        ));
        foreach ($revision_proposals as $proposal) {
            $items[] = (object) array(
                'type' => 'proposal_revision',
                'priority' => 2,
                'icon' => 'dashicons-edit',
                'badge_class' => 'status-revision',
                'badge_text' => __('Changes Requested', 'freelance-studio'),
                'title' => $proposal->title,
                'subtitle' => $proposal->client_company ?: $proposal->client_name,
                'url' => admin_url('admin.php?page=fs-proposals&action=view&id=' . $proposal->id),
                'date' => $proposal->revision_requested_at ?? null,
            );
        }
        
        // 3. Overdue invoices
        $overdue_invoices = FS_Invoice::get_overdue();
        foreach ($overdue_invoices as $invoice) {
            $days_overdue = floor((time() - strtotime($invoice->due_date)) / 86400);
            $items[] = (object) array(
                'type' => 'invoice_overdue',
                'priority' => 3,
                'icon' => 'dashicons-warning',
                'badge_class' => 'status-overdue',
                /* translators: 1. count/number */
                'badge_text' => sprintf(__('%d days overdue', 'freelance-studio'), $days_overdue),
                /* translators: 1. number/ID */
                'title' => sprintf(__('Invoice #%s', 'freelance-studio'), $invoice->invoice_number),
                'subtitle' => FS_View_Context::format_currency($invoice->total) . ' — ' . ($invoice->client_company ?: $invoice->client_name ?: ''),
                'url' => admin_url('admin.php?page=fs-finances&tab=invoices&action=view&id=' . $invoice->id),
                'date' => $invoice->due_date,
            );
        }
        
        // 4. Contracts viewed but not signed (client saw it, needs a nudge)
        $viewed_contracts = FS_Contract::get_all(array(
            'status' => 'viewed',
            'limit' => 10,
        ));
        foreach ($viewed_contracts as $contract) {
            $items[] = (object) array(
                'type' => 'contract_viewed',
                'priority' => 5,
                'icon' => 'dashicons-media-text',
                'badge_class' => 'status-viewed',
                'badge_text' => __('Viewed, Not Signed', 'freelance-studio'),
                'title' => $contract->title,
                'subtitle' => $contract->client_name ?: ($contract->client_contact_name ?? ''),
                'url' => admin_url('admin.php?page=fs-contracts&action=view&id=' . $contract->id),
                'date' => $contract->viewed_at ?? null,
            );
        }
        
        // 5. Proposals expiring soon (within 7 days)
        $expiring_proposals = FS_Proposal::get_all(array(
            'status' => array('sent', 'viewed'),
            'limit' => 10,
        ));
        $seven_days = strtotime('+7 days');
        $now = time();
        foreach ($expiring_proposals as $proposal) {
            if (!empty($proposal->valid_until)) {
                $expires = strtotime($proposal->valid_until);
                if ($expires > $now && $expires <= $seven_days) {
                    $days_left = ceil(($expires - $now) / 86400);
                    $items[] = (object) array(
                        'type' => 'proposal_expiring',
                        'priority' => 4,
                        'icon' => 'dashicons-clock',
                        'badge_class' => 'status-pending',
                        /* translators: 1. count/number */
                        'badge_text' => sprintf(_n('%d day left', '%d days left', $days_left, 'freelance-studio'), $days_left),
                        'title' => $proposal->title,
                        'subtitle' => $proposal->client_company ?: $proposal->client_name,
                        'url' => admin_url('admin.php?page=fs-proposals&action=view&id=' . $proposal->id),
                        'date' => $proposal->valid_until,
                    );
                }
            }
        }
        
        // 6. Tasks that are "Needs Information" (waiting on something from you)
        $needs_info_tasks = FS_Task::get_all(array(
            'status' => 'needs_info',
            'limit' => 10,
            'exclude_orphaned' => true,
        ));
        foreach ($needs_info_tasks as $task) {
            $items[] = (object) array(
                'type' => 'task_needs_info',
                'priority' => 4,
                'icon' => 'dashicons-info',
                'badge_class' => 'status-pending',
                'badge_text' => __('Needs Info', 'freelance-studio'),
                'title' => $task->name,
                'subtitle' => $task->project_name ?? '',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $task->project_id . '&tab=tasks'),
                'date' => $task->created_at ?? null,
            );
        }
        
        // Sort by priority (lower = more urgent)
        usort($items, function($a, $b) {
            return $a->priority - $b->priority;
        });
        
        return $items;
    }

    /**
     * Get dashboard invoices with status categorization
     *
     * @return array
     */
    private function get_dashboard_invoices() {
        // Get recent invoices
        $invoices = FS_Invoice::get_all(array('limit' => 8));
        
        // Categorize by display status
        $categorized = array();
        foreach ($invoices as $invoice) {
            // Determine display status
            if ($invoice->status === 'paid') {
                $invoice->display_status = 'paid';
            } elseif (!empty($invoice->due_date) && strtotime($invoice->due_date) < time() && $invoice->status !== 'paid') {
                $invoice->display_status = 'overdue';
            } else {
                $invoice->display_status = 'sent';
            }
            $categorized[] = $invoice;
        }
        
        return array_slice($categorized, 0, 5);
    }

    /**
     * Get combined financial summary for dashboard
     *
     * @return array
     */
    private function get_financial_summary() {
        $current_year = gmdate('Y');
        
        // Revenue stats (invoices)
        $invoice_revenue = FS_Invoice::get_total_revenue(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        // Other income (manual income entries)
        $other_income = FS_Manual_Income::get_total(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        $ytd_revenue = ($invoice_revenue ?: 0) + ($other_income ?: 0);
        
        // Outstanding/Pending
        $outstanding = FS_Invoice::get_outstanding_total();
        
        // Expense stats
        $ytd_expenses = FS_Expense::get_total(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        // Calculate tax liability (using combined income)
        $income = $ytd_revenue;
        $expenses = FS_Tax_Calculator::get_ytd_expenses($current_year);
        $state = get_option('fs_tax_state', '');
        $federal_bracket = get_option('fs_federal_tax_bracket', 22);
        
        $tax_data = FS_Tax_Calculator::calculate_tax_liability(
            $income,
            $state,
            $federal_bracket,
            $expenses
        );
        
        return array(
            'gross_income' => $ytd_revenue,
            'pending_income' => $outstanding ?: 0,
            'expenses' => $ytd_expenses ?: 0,
            'estimated_tax' => $tax_data['tax_breakdown']['total_tax'] ?? 0,
            'net_income' => $ytd_revenue - ($ytd_expenses ?: 0),
        );
    }

    /**
     * Get dashboard statistics
     *
     * @return array
     */
    private function get_dashboard_stats() {
        $current_year = gmdate('Y');
        $current_month = gmdate('Y-m');
        
        // Revenue stats (invoices)
        $ytd_invoice_revenue = FS_Invoice::get_total_revenue(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        $month_invoice_revenue = FS_Invoice::get_total_revenue(
            $current_month . '-01',
            gmdate('Y-m-t')
        );
        
        // Other income (manual income entries)
        $ytd_other_income = FS_Manual_Income::get_total(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        $month_other_income = FS_Manual_Income::get_total(
            $current_month . '-01',
            gmdate('Y-m-t')
        );
        
        // Combined revenue
        $ytd_revenue = ($ytd_invoice_revenue ?: 0) + ($ytd_other_income ?: 0);
        $month_revenue = ($month_invoice_revenue ?: 0) + ($month_other_income ?: 0);
        
        // Outstanding
        $outstanding = FS_Invoice::get_outstanding_total();
        
        // Expense stats
        $ytd_expenses = FS_Expense::get_total(
            $current_year . '-01-01',
            $current_year . '-12-31'
        );
        
        // Project stats
        $active_projects = FS_Project::get_active_count();
        $total_clients = FS_Client::count('active');
        
        // Invoice counts by status
        $draft_invoices = FS_Invoice::count(array('status' => 'draft'));
        $pending_invoices = FS_Invoice::count(array('status' => array('sent', 'viewed', 'partial')));
        $overdue_invoices = count(FS_Invoice::get_overdue());
        
        return array(
            'ytd_revenue' => $ytd_revenue,
            'month_revenue' => $month_revenue,
            'outstanding' => $outstanding ?: 0,
            'ytd_expenses' => $ytd_expenses ?: 0,
            'net_income' => $ytd_revenue - ($ytd_expenses ?: 0),
            'active_projects' => $active_projects,
            'total_clients' => $total_clients,
            'draft_invoices' => $draft_invoices,
            'pending_invoices' => $pending_invoices,
            'overdue_invoices' => $overdue_invoices
        );
    }
    
    /**
     * Get calendar data for mini-calendar widget
     *
     * @return array
     */
    private function get_calendar_widget_data() {
        $year = gmdate('Y');
        $month = gmdate('n');
        
        // Get events for the current month using the calendar controller
        $calendar_controller = new FS_Calendar_Controller();
        
        // Use reflection to access private method or create a public static method
        // For now, we'll get events directly
        global $wpdb;
        
        $first_day = gmdate('Y-m-01');
        $last_day = gmdate('Y-m-t');
        
        $events = array();
        
        // Get Projects
        $projects_table = $wpdb->prefix . 'fs_projects';
        $projects = $wpdb->get_results($wpdb->prepare(
            "SELECT id, name, start_date, due_date FROM {$projects_table}
             WHERE (start_date BETWEEN %s AND %s) OR (due_date BETWEEN %s AND %s)",
            $first_day, $last_day, $first_day, $last_day
        ));
        
        foreach ($projects as $project) {
            if ($project->start_date && $project->start_date >= $first_day && $project->start_date <= $last_day) {
                $events[] = array(
                    'date' => $project->start_date,
                    'type' => 'project',
                    'title' => $project->name,
                    'color' => '#D2E768',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                    'icon' => '<span class="dashicons dashicons-portfolio"></span>',
                );
            }
            if ($project->due_date && $project->due_date >= $first_day && $project->due_date <= $last_day) {
                $events[] = array(
                    'date' => $project->due_date,
                    'type' => 'project',
                    'title' => $project->name,
                    'color' => '#D2E768',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                    'icon' => '<span class="dashicons dashicons-flag"></span>',
                );
            }
        }
        
        // Get Invoices
        $invoices_table = $wpdb->prefix . 'fs_invoices';
        $invoices = $wpdb->get_results($wpdb->prepare(
            "SELECT id, invoice_number, due_date FROM {$invoices_table}
             WHERE due_date BETWEEN %s AND %s AND status NOT IN ('paid', 'cancelled')",
            $first_day, $last_day
        ));
        
        foreach ($invoices as $invoice) {
            $events[] = array(
                'date' => $invoice->due_date,
                'type' => 'invoice',
                'title' => 'Invoice #' . $invoice->invoice_number,
                'color' => '#FFA26E',
                'url' => admin_url('admin.php?page=fs-finances&tab=invoices&action=view&id=' . $invoice->id),
                'icon' => '<span class="dashicons dashicons-money-alt"></span>',
            );
        }
        
        // Get Milestones
        $milestones_table = $wpdb->prefix . 'fs_milestones';
        $milestones = $wpdb->get_results($wpdb->prepare(
            "SELECT id, name, project_id, due_date FROM {$milestones_table}
             WHERE due_date BETWEEN %s AND %s AND status != 'completed'",
            $first_day, $last_day
        ));
        
        foreach ($milestones as $milestone) {
            $events[] = array(
                'date' => $milestone->due_date,
                'type' => 'milestone',
                'title' => $milestone->name,
                'color' => '#81A5DF',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $milestone->project_id),
                'icon' => '<span class="dashicons dashicons-marker"></span>',
            );
        }
        
        // Get Tasks
        $tasks_table = $wpdb->prefix . 'fs_tasks';
        $tasks = $wpdb->get_results($wpdb->prepare(
            "SELECT id, title, project_id, due_date, priority FROM {$tasks_table}
             WHERE due_date BETWEEN %s AND %s AND status != 'completed'",
            $first_day, $last_day
        ));
        
        foreach ($tasks as $task) {
            $priority_colors = array('urgent' => '#c53030', 'high' => '#EB8861', 'medium' => '#EDCE7A', 'low' => '#9CA3AF');
            $events[] = array(
                'date' => $task->due_date,
                'type' => 'task',
                'title' => $task->title,
                'color' => isset($priority_colors[$task->priority]) ? $priority_colors[$task->priority] : '#9CA3AF',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $task->project_id),
                'icon' => '<span class="dashicons dashicons-yes-alt"></span>',
            );
        }
        
        return array(
            'year' => $year,
            'month' => $month,
            'events' => $events,
        );
    }
    
    /**
     * Get week data for week-view widget
     *
     * @return array
     */
    private function get_week_widget_data() {
        $week_start = gmdate('Y-m-d', strtotime('monday this week'));
        $week_end = gmdate('Y-m-d', strtotime('sunday this week'));
        
        global $wpdb;
        
        $events = array();
        
        // Get Projects
        $projects_table = $wpdb->prefix . 'fs_projects';
        $projects = $wpdb->get_results($wpdb->prepare(
            "SELECT id, name, start_date, due_date FROM {$projects_table}
             WHERE (start_date BETWEEN %s AND %s) OR (due_date BETWEEN %s AND %s)",
            $week_start, $week_end, $week_start, $week_end
        ));
        
        foreach ($projects as $project) {
            if ($project->start_date && $project->start_date >= $week_start && $project->start_date <= $week_end) {
                $events[] = array(
                    'date' => $project->start_date,
                    'type' => 'project',
                    'title' => $project->name,
                    'color' => '#D2E768',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                    'icon' => '<span class="dashicons dashicons-portfolio"></span>',
                );
            }
            if ($project->due_date && $project->due_date >= $week_start && $project->due_date <= $week_end) {
                $events[] = array(
                    'date' => $project->due_date,
                    'type' => 'project',
                    'title' => $project->name,
                    'color' => '#D2E768',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                    'icon' => '<span class="dashicons dashicons-flag"></span>',
                );
            }
        }
        
        // Get Invoices
        $invoices_table = $wpdb->prefix . 'fs_invoices';
        $invoices = $wpdb->get_results($wpdb->prepare(
            "SELECT id, invoice_number, due_date FROM {$invoices_table}
             WHERE due_date BETWEEN %s AND %s AND status NOT IN ('paid', 'cancelled')",
            $week_start, $week_end
        ));
        
        foreach ($invoices as $invoice) {
            $is_overdue = $invoice->due_date < gmdate('Y-m-d');
            $events[] = array(
                'date' => $invoice->due_date,
                'type' => 'invoice',
                'title' => 'Invoice #' . $invoice->invoice_number,
                'color' => $is_overdue ? '#c53030' : '#FFA26E',
                'url' => admin_url('admin.php?page=fs-finances&tab=invoices&action=view&id=' . $invoice->id),
                'icon' => $is_overdue ? '<span class="dashicons dashicons-warning"></span>' : '<span class="dashicons dashicons-money-alt"></span>',
            );
        }
        
        // Get Milestones
        $milestones_table = $wpdb->prefix . 'fs_milestones';
        $milestones = $wpdb->get_results($wpdb->prepare(
            "SELECT id, name, project_id, due_date FROM {$milestones_table}
             WHERE due_date BETWEEN %s AND %s AND status != 'completed'",
            $week_start, $week_end
        ));
        
        foreach ($milestones as $milestone) {
            $events[] = array(
                'date' => $milestone->due_date,
                'type' => 'milestone',
                'title' => $milestone->name,
                'color' => '#81A5DF',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $milestone->project_id),
                'icon' => '<span class="dashicons dashicons-marker"></span>',
            );
        }
        
        // Get Tasks
        $tasks_table = $wpdb->prefix . 'fs_tasks';
        $tasks = $wpdb->get_results($wpdb->prepare(
            "SELECT id, title, project_id, due_date, priority FROM {$tasks_table}
             WHERE due_date BETWEEN %s AND %s AND status != 'completed'",
            $week_start, $week_end
        ));
        
        foreach ($tasks as $task) {
            $priority_colors = array('urgent' => '#c53030', 'high' => '#EB8861', 'medium' => '#EDCE7A', 'low' => '#9CA3AF');
            $task_url = !empty($task->project_id) 
                ? admin_url('admin.php?page=fs-projects&action=view&id=' . $task->project_id . '#tasks')
                : admin_url('admin.php?page=fs-tasks&view=kanban');
            $events[] = array(
                'date' => $task->due_date,
                'type' => 'task',
                'title' => $task->title,
                'color' => isset($priority_colors[$task->priority]) ? $priority_colors[$task->priority] : '#9CA3AF',
                'url' => $task_url,
                'icon' => '<span class="dashicons dashicons-yes-alt"></span>',
            );
        }
        
        // Get Bookings
        $bookings_table = $wpdb->prefix . 'fs_bookings';
        $meeting_types_table = $wpdb->prefix . 'fs_meeting_types';
        $bookings = $wpdb->get_results($wpdb->prepare( // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter
            "SELECT b.id, b.start_datetime, b.guest_name, mt.name as meeting_type_name, mt.color as meeting_color
             FROM {$bookings_table} b
             LEFT JOIN {$meeting_types_table} mt ON b.meeting_type_id = mt.id
             WHERE DATE(b.start_datetime) BETWEEN %s AND %s AND b.status = 'confirmed'",
            $week_start, $week_end
        ));
        
        foreach ($bookings as $booking) {
            $start_time = gmdate('g:i A', strtotime($booking->start_datetime));
            $events[] = array(
                'date' => gmdate('Y-m-d', strtotime($booking->start_datetime)),
                'type' => 'booking',
                'title' => $booking->meeting_type_name . ' - ' . $booking->guest_name,
                'color' => $booking->meeting_color ?: '#7B68A6',
                'url' => admin_url('admin.php?page=fs-bookings&action=view&id=' . $booking->id),
                'icon' => '<span class="dashicons dashicons-calendar-alt"></span>',
                'time' => $start_time,
            );
        }
        
        // Get External Calendar Events (Google Calendar)
        $external_events_table = $wpdb->prefix . 'fs_external_calendar_events';
        if ($wpdb->get_var("SHOW TABLES LIKE '{$external_events_table}'") === $external_events_table) {
            $external_events = $wpdb->get_results($wpdb->prepare(
                "SELECT id, title, start_datetime, end_datetime, color, source
                 FROM {$external_events_table}
                 WHERE DATE(start_datetime) BETWEEN %s AND %s",
                $week_start, $week_end
            ));
            
            foreach ($external_events as $ext_event) {
                $start_time = gmdate('g:i A', strtotime($ext_event->start_datetime));
                $events[] = array(
                    'date' => gmdate('Y-m-d', strtotime($ext_event->start_datetime)),
                    'type' => 'external',
                    'title' => $ext_event->title,
                    'color' => $ext_event->color ?: '#5D4E80',
                    'url' => admin_url('admin.php?page=fs-calendar'),
                    'icon' => '<span class="dashicons dashicons-calendar"></span>',
                    'time' => $start_time,
                );
            }
        }
        
        return array(
            'week_start' => $week_start,
            'events' => $events,
        );
    }
}
