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

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

class FS_Calendar_Controller {

    /**
     * Handle the request
     */
    public function handle_request() {
        $this->index();
    }

    /**
     * Display calendar page
     */
    public function index() {
        // Get current month/year from URL or default to current
        $year = isset($_GET['year']) ? intval($_GET['year']) : gmdate('Y');
        $month = isset($_GET['month']) ? intval($_GET['month']) : gmdate('n');
        
        // Validate month bounds
        if ($month < 1) {
            $month = 12;
            $year--;
        } elseif ($month > 12) {
            $month = 1;
            $year++;
        }
        
        // Get view type (month or week)
        $view = isset($_GET['view']) ? sanitize_text_field($_GET['view']) : 'month';
        
        // For week view, get the week start date
        $week_start = isset($_GET['week']) ? sanitize_text_field($_GET['week']) : gmdate('Y-m-d', strtotime('monday this week'));
        
        // Get all events for the calendar
        $events = $this->get_calendar_events($year, $month, $view, $week_start);
        
        // Pass data to view
        $data = array(
            'year' => $year,
            'month' => $month,
            'view' => $view,
            'week_start' => $week_start,
            'events' => $events,
            'month_name' => gmdate('F', mktime(0, 0, 0, $month, 1, $year)),
        );
        
        include JEEB_FS_PLUGIN_DIR . 'includes/views/calendar/index.php';
    }

    /**
     * Get all calendar events for the given period
     */
    private function get_calendar_events($year, $month, $view = 'month', $week_start = null) {
        global $wpdb;
        
        // Determine date range based on view
        if ($view === 'week' && $week_start) {
            $start_date = $week_start;
            $end_date = gmdate('Y-m-d', strtotime($week_start . ' +6 days'));
        } else {
            // Month view - include days from adjacent months that appear in the calendar grid
            $first_day = gmdate('Y-m-01', mktime(0, 0, 0, $month, 1, $year));
            $last_day = gmdate('Y-m-t', mktime(0, 0, 0, $month, 1, $year));
            
            // Extend to full weeks
            $start_date = gmdate('Y-m-d', strtotime('monday this week', strtotime($first_day)));
            $end_date = gmdate('Y-m-d', strtotime('sunday this week', strtotime($last_day)));
        }
        
        $events = array();
        
        // Get Projects (start and end dates)
        $projects_table = $wpdb->prefix . 'fs_projects';
        $clients_table = $wpdb->prefix . 'fs_clients';
        
        $projects = $wpdb->get_results($wpdb->prepare(
            "SELECT p.*, c.company_name, c.name as client_name
             FROM {$projects_table} p
             LEFT JOIN {$clients_table} c ON p.client_id = c.id
             WHERE (p.start_date BETWEEN %s AND %s)
                OR (p.due_date BETWEEN %s AND %s)",
            $start_date, $end_date, $start_date, $end_date
        ));
        
        foreach ($projects as $project) {
            $client_display = $project->company_name ?: $project->client_name;
            
            if ($project->start_date && $project->start_date >= $start_date && $project->start_date <= $end_date) {
                $events[] = array(
                    'date' => $project->start_date,
                    'type' => 'project_start',
                    'title' => $project->name,
                    'subtitle' => $client_display,
                    'icon' => '🚀',
                    'color' => '#81A5DF',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                );
            }
            
            if ($project->due_date && $project->due_date >= $start_date && $project->due_date <= $end_date) {
                $events[] = array(
                    'date' => $project->due_date,
                    'type' => 'project_deadline',
                    'title' => $project->name,
                    'subtitle' => $client_display,
                    'icon' => '🏁',
                    'color' => '#81A5DF',
                    'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $project->id),
                );
            }
        }
        
        // Get Milestones
        $milestones_table = $wpdb->prefix . 'fs_milestones';
        
        $milestones = $wpdb->get_results($wpdb->prepare(
            "SELECT m.*, p.name as project_name
             FROM {$milestones_table} m
             LEFT JOIN {$projects_table} p ON m.project_id = p.id
             WHERE m.due_date BETWEEN %s AND %s
             AND m.status != 'completed'",
            $start_date, $end_date
        ));
        
        foreach ($milestones as $milestone) {
            $events[] = array(
                'date' => $milestone->due_date,
                'type' => 'milestone',
                'title' => $milestone->name,
                'subtitle' => $milestone->project_name,
                'icon' => '🎯',
                'color' => '#3ECFB2',
                'url' => admin_url('admin.php?page=fs-projects&action=view&id=' . $milestone->project_id),
            );
        }
        
        // Get Tasks
        $tasks_table = $wpdb->prefix . 'fs_tasks';
        
        $tasks = $wpdb->get_results($wpdb->prepare(
            "SELECT t.*, p.name as project_name
             FROM {$tasks_table} t
             LEFT JOIN {$projects_table} p ON t.project_id = p.id
             WHERE t.due_date BETWEEN %s AND %s
             AND t.status != 'completed'",
            $start_date, $end_date
        ));
        
        foreach ($tasks as $task) {
            $priority_colors = array(
                'urgent' => '#E85A5A',
                'high' => '#FFA26E',
                'medium' => '#FFE0CE',
                'low' => '#9CA3AF',
            );
            
            // Determine URL based on whether task has a project
            if (!empty($task->project_id)) {
                $task_url = admin_url('admin.php?page=fs-projects&action=view&id=' . $task->project_id . '#tasks');
            } else {
                $task_url = admin_url('admin.php?page=fs-tasks&view=kanban');
            }
            
            $events[] = array(
                'date' => $task->due_date,
                'type' => 'task',
                'title' => $task->title,
                'subtitle' => $task->project_name ? $task->project_name : __('No Project', 'freelance-studio'),
                'icon' => '✅',
                'color' => isset($priority_colors[$task->priority]) ? $priority_colors[$task->priority] : '#9CA3AF',
                'priority' => $task->priority,
                'url' => $task_url,
            );
        }
        
        // 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.*, mt.name as meeting_type_name, mt.color as meeting_color, mt.duration
             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'",
            $start_date, $end_date
        ));
        
        foreach ($bookings as $booking) {
            $attendee_name = $booking->guest_name;
            if ($booking->client_id) {
                $client = $wpdb->get_row($wpdb->prepare(
                    "SELECT name, company_name FROM {$clients_table} WHERE id = %d",
                    $booking->client_id
                ));
                if ($client) {
                    $attendee_name = $client->name;
                }
            }
            
            $start_time = gmdate('g:i A', strtotime($booking->start_datetime));
            $end_time = gmdate('g:i A', strtotime($booking->end_datetime));
            
            $events[] = array(
                'date' => gmdate('Y-m-d', strtotime($booking->start_datetime)),
                'type' => 'booking',
                'title' => $booking->meeting_type_name,
                'subtitle' => $attendee_name . ' • ' . $start_time . ' - ' . $end_time,
                'icon' => '📅',
                'color' => $booking->meeting_color ?: '#77D5C9',
                'url' => admin_url('admin.php?page=fs-bookings&action=view&id=' . $booking->id),
                'start_time' => $start_time,
                'end_time' => $end_time,
            );
        }
        
        // Get Invoice due dates
        $invoices_table = $wpdb->prefix . 'fs_invoices';
        
        $invoices = $wpdb->get_results($wpdb->prepare(
            "SELECT i.*, c.company_name, c.name as client_name
             FROM {$invoices_table} i
             LEFT JOIN {$clients_table} c ON i.client_id = c.id
             WHERE i.due_date BETWEEN %s AND %s
             AND i.status NOT IN ('paid', 'cancelled')",
            $start_date, $end_date
        ));
        
        foreach ($invoices as $invoice) {
            $client_display = $invoice->company_name ?: $invoice->client_name;
            $is_overdue = $invoice->due_date < gmdate('Y-m-d');
            
            $events[] = array(
                'date' => $invoice->due_date,
                'type' => 'invoice',
                'title' => 'Invoice #' . $invoice->invoice_number,
                'subtitle' => $client_display . ' - $' . number_format($invoice->total - $invoice->amount_paid, 2),
                'icon' => $is_overdue ? '⚠️' : '💰',
                'color' => $is_overdue ? '#E85A5A' : '#FFA26E',
                'url' => admin_url('admin.php?page=fs-finances&tab=invoices&action=view&id=' . $invoice->id),
            );
        }
        
        // Get Contract expirations
        $contracts_table = $wpdb->prefix . 'fs_contracts';
        
        $contracts = $wpdb->get_results($wpdb->prepare( // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter
            "SELECT ct.*, c.company_name, c.name as client_name
             FROM {$contracts_table} ct
             LEFT JOIN {$clients_table} c ON ct.client_id = c.id
             WHERE ct.valid_until BETWEEN %s AND %s
             AND ct.status NOT IN ('approved', 'cancelled')",
            $start_date, $end_date
        ));
        
        foreach ($contracts as $contract) {
            $client_display = $contract->company_name ?: $contract->client_name;
            
            $events[] = array(
                'date' => $contract->valid_until,
                'type' => 'contract',
                'title' => $contract->title,
                'subtitle' => $client_display . ' - Expires',
                'icon' => '📝',
                'color' => '#E85A5A',
                'url' => admin_url('admin.php?page=fs-contracts&action=view&id=' . $contract->id),
            );
        }
        
        // Get Proposal expirations
        $proposals_table = $wpdb->prefix . 'fs_proposals';
        
        $proposals = $wpdb->get_results($wpdb->prepare( // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter
            "SELECT pr.*, c.company_name, c.name as client_name
             FROM {$proposals_table} pr
             LEFT JOIN {$clients_table} c ON pr.client_id = c.id
             WHERE pr.valid_until BETWEEN %s AND %s
             AND pr.status NOT IN ('approved', 'cancelled', 'dismissed')",
            $start_date, $end_date
        ));
        
        foreach ($proposals as $proposal) {
            $client_display = $proposal->company_name ?: $proposal->client_name;
            
            $events[] = array(
                'date' => $proposal->valid_until,
                'type' => 'proposal',
                'title' => $proposal->title,
                'subtitle' => $client_display . ' - Expires',
                'icon' => '📋',
                'color' => '#E85A5A',
                'url' => admin_url('admin.php?page=fs-proposals&action=view&id=' . $proposal->id),
            );
        }
        
        // Get Quarterly Tax Deadlines
        $tax_deadlines = array(
            array('date' => $year . '-04-15', 'label' => 'Q1 Tax Payment Due'),
            array('date' => $year . '-06-15', 'label' => 'Q2 Tax Payment Due'),
            array('date' => $year . '-09-15', 'label' => 'Q3 Tax Payment Due'),
            array('date' => ($year + 1) . '-01-15', 'label' => 'Q4 Tax Payment Due'),
        );
        
        foreach ($tax_deadlines as $deadline) {
            if ($deadline['date'] >= $start_date && $deadline['date'] <= $end_date) {
                $events[] = array(
                    'date' => $deadline['date'],
                    'type' => 'tax',
                    'title' => $deadline['label'],
                    'subtitle' => 'Estimated Tax',
                    'icon' => '🏛️',
                    'color' => '#5D4E80',
                    'url' => admin_url('admin.php?page=fs-finances&tab=tax'),
                );
            }
        }
        
        // Get Google Calendar events (custom events created through the plugin UI)
        if (FS_Google_Calendar_Service::is_connected()) {
            $gcal_events = FS_Google_Calendar_Service::get_events_in_range($start_date, $end_date);
            
            foreach ($gcal_events as $gcal_event) {
                // Skip events that were synced from this plugin (they're already shown above)
                if ($gcal_event['is_fs_event'] && $gcal_event['fs_type'] !== 'custom') {
                    continue;
                }
                
                $events[] = array(
                    'date' => $gcal_event['date'],
                    'type' => 'google_calendar',
                    'title' => $gcal_event['title'],
                    'subtitle' => $gcal_event['all_day'] ? 'All day' : ($gcal_event['start_time'] . ' - ' . $gcal_event['end_time']),
                    'icon' => '📅',
                    'color' => $gcal_event['color'],
                    'url' => admin_url('admin.php?page=fs-calendar&year=' . gmdate('Y', strtotime($gcal_event['date'])) . '&month=' . gmdate('n', strtotime($gcal_event['date']))),
                    'gcal_id' => $gcal_event['id'],
                    'gcal_editable' => $gcal_event['editable'],
                    'gcal_data' => $gcal_event,
                );
            }
        }
        
        // Sort events by date
        usort($events, function($a, $b) {
            return strcmp($a['date'], $b['date']);
        });
        
        return $events;
    }

    /**
     * Get events for a specific date (used by AJAX)
     */
    public static function get_events_for_date($date) {
        $controller = new self();
        $year = gmdate('Y', strtotime($date));
        $month = gmdate('n', strtotime($date));
        
        $all_events = $controller->get_calendar_events($year, $month);
        
        return array_filter($all_events, function($event) use ($date) {
            return $event['date'] === $date;
        });
    }

    /**
     * Get upcoming events for dashboard widget
     */
    public static function get_upcoming_events($days = 7) {
        $controller = new self();
        
        $start_date = gmdate('Y-m-d');
        $end_date = gmdate('Y-m-d', strtotime("+{$days} days"));
        
        // We need to get events in a date range
        $year = gmdate('Y');
        $month = gmdate('n');
        
        // Get events for current and possibly next month
        $events = $controller->get_calendar_events($year, $month);
        
        // Filter to only upcoming events within the range
        $upcoming = array_filter($events, function($event) use ($start_date, $end_date) {
            return $event['date'] >= $start_date && $event['date'] <= $end_date;
        });
        
        // Re-sort by date
        usort($upcoming, function($a, $b) {
            return strcmp($a['date'], $b['date']);
        });
        
        return array_values($upcoming);
    }
    
    /**
     * Get upcoming events excluding tasks (for Upcoming Events widget)
     * Shows only deadlines, meetings, bookings, and external calendar events
     */
    public static function get_upcoming_events_no_tasks($days = 7) {
        $events = self::get_upcoming_events($days);
        
        // Filter out tasks - keep only project deadlines, milestones, invoices, bookings, and external events
        $filtered = array_filter($events, function($event) {
            return $event['type'] !== 'task';
        });
        
        return array_values($filtered);
    }
}
