<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Scheduled Task Model
 *
 * CRUD operations for scheduled automation tasks using CPT.
 *
 * @package    Kitsune_AI_Platform
 * @subpackage Kitsune_AI_Platform/includes/models
 */

class Kitsune_AI_Platform_Scheduled_Task_Model {

    /**
     * Frequency constants
     */
    const FREQUENCY_DAILY   = 'daily';
    const FREQUENCY_WEEKLY  = 'weekly';
    const FREQUENCY_MONTHLY = 'monthly';
    const FREQUENCY_YEARLY  = 'yearly';

    public function __construct() {
        // CPT is registered in Kitsune_AI_Platform_CPT
    }

    /**
     * Get all scheduled tasks
     * 
     * @return array
     */
    public function get_all() {
        $args = array(
            'post_type'      => 'kitsune_ai_sched_task',
            'posts_per_page' => -1,
            'post_status'    => array('publish', 'draft') // active, inactive
        );

        $query = new WP_Query($args);
        $tasks = array();

        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                $tasks[] = $this->format_task(get_post());
            }
            wp_reset_postdata();
        }

        return $tasks;
    }

    /**
     * Get scheduled task by ID
     * 
     * @param int $id Task ID
     * @return object|null
     */
    public function get_by_id($id) {
        $post = get_post($id);
        if (!$post || $post->post_type !== 'kitsune_ai_sched_task') return null;

        return $this->format_task($post);
    }

    /**
     * Create a scheduled task
     * 
     * @param array $data Task data
     * @return int|WP_Error Post ID or error
     */
    public function create($data) {
        $post_data = array(
            'post_title'   => sanitize_text_field($data['name']),
            'post_type'    => 'kitsune_ai_sched_task',
            'post_status'  => isset($data['active']) && $data['active'] ? 'publish' : 'draft',
            'post_content' => '', // Not used for this CPT
        );

        $post_id = wp_insert_post($post_data);

        if (!is_wp_error($post_id)) {
            // Save meta data
            update_post_meta($post_id, '_workflow_id', intval($data['workflow_id']));
            update_post_meta($post_id, '_frequency', sanitize_text_field($data['frequency']));
            update_post_meta($post_id, '_start_date', sanitize_text_field($data['start_date']));
            update_post_meta($post_id, '_end_date', sanitize_text_field($data['end_date'] ?? ''));
            update_post_meta($post_id, '_time_of_day', sanitize_text_field($data['time_of_day']));

            // Schedule the WP Cron event
            $this->schedule_cron_event($post_id);
        }

        return $post_id;
    }

    /**
     * Update a scheduled task
     * 
     * @param int   $id   Task ID
     * @param array $data Task data
     * @return int|WP_Error Post ID or error
     */
    public function update($id, $data) {
        $post_data = array(
            'ID' => $id,
        );

        if (isset($data['name'])) $post_data['post_title'] = sanitize_text_field($data['name']);
        if (isset($data['active'])) $post_data['post_status'] = $data['active'] ? 'publish' : 'draft';

        $result = wp_update_post($post_data);

        if (!is_wp_error($result)) {
            // Update meta data if provided
            if (isset($data['workflow_id'])) {
                update_post_meta($id, '_workflow_id', intval($data['workflow_id']));
            }
            if (isset($data['frequency'])) {
                update_post_meta($id, '_frequency', sanitize_text_field($data['frequency']));
            }
            if (isset($data['start_date'])) {
                update_post_meta($id, '_start_date', sanitize_text_field($data['start_date']));
            }
            if (isset($data['end_date'])) {
                update_post_meta($id, '_end_date', sanitize_text_field($data['end_date']));
            }
            if (isset($data['time_of_day'])) {
                update_post_meta($id, '_time_of_day', sanitize_text_field($data['time_of_day']));
            }

            // Reschedule the cron event
            $this->unschedule_cron_event($id);
            if (get_post_status($id) === 'publish') {
                $this->schedule_cron_event($id);
            }
        }

        return $result;
    }

    /**
     * Delete a scheduled task
     * 
     * @param int $id Task ID
     * @return WP_Post|false|null
     */
    public function delete($id) {
        $this->unschedule_cron_event($id);
        return wp_delete_post($id, true);
    }

    /**
     * Schedule WP Cron event for a task
     * 
     * @param int $task_id Task ID
     */
    public function schedule_cron_event($task_id) {
        $task = $this->get_by_id($task_id);
        if (!$task || $task->status !== 'active') return;

        // Clear any existing scheduled event
        $this->unschedule_cron_event($task_id);

        // Calculate the first run time
        $start_date = $task->start_date;
        $time_of_day = $task->time_of_day;
        
        // Parse start date and time
        $first_run = strtotime($start_date . ' ' . $time_of_day);
        
        // If first run is in the past, calculate next occurrence
        if ($first_run < time()) {
            $first_run = $this->calculate_next_occurrence($first_run, $task->frequency);
        }

        // Check if end date has passed
        if (!empty($task->end_date)) {
            $end_time = strtotime($task->end_date . ' 23:59:59');
            if ($first_run > $end_time) {
                return; // Don't schedule if already past end date
            }
        }

        // Map frequency to WP Cron schedule
        $recurrence = $this->get_wp_cron_recurrence($task->frequency);

        // Schedule the event
        wp_schedule_event($first_run, $recurrence, 'kitsune_ai_platform_run_scheduled_task', array($task_id));
    }

    /**
     * Unschedule WP Cron event for a task
     * 
     * @param int $task_id Task ID
     */
    public function unschedule_cron_event($task_id) {
        $timestamp = wp_next_scheduled('kitsune_ai_platform_run_scheduled_task', array($task_id));
        if ($timestamp) {
            wp_unschedule_event($timestamp, 'kitsune_ai_platform_run_scheduled_task', array($task_id));
        }
    }

    /**
     * Calculate next occurrence based on frequency
     * 
     * @param int    $timestamp Base timestamp
     * @param string $frequency Frequency constant
     * @return int Next occurrence timestamp
     */
    private function calculate_next_occurrence($timestamp, $frequency) {
        $datetime = new DateTime('@' . $timestamp);
        $now = new DateTime();

        while ($datetime < $now) {
            switch ($frequency) {
                case self::FREQUENCY_DAILY:
                    $datetime->modify('+1 day');
                    break;
                case self::FREQUENCY_WEEKLY:
                    $datetime->modify('+1 week');
                    break;
                case self::FREQUENCY_MONTHLY:
                    $datetime->modify('+1 month');
                    break;
                case self::FREQUENCY_YEARLY:
                    $datetime->modify('+1 year');
                    break;
                default:
                    $datetime->modify('+1 day');
            }
        }

        return $datetime->getTimestamp();
    }

    /**
     * Get WP Cron recurrence string from frequency
     * 
     * @param string $frequency Frequency constant
     * @return string WP Cron recurrence name
     */
    private function get_wp_cron_recurrence($frequency) {
        // Note: 'weekly', 'monthly', 'yearly' need to be registered via cron_schedules filter
        // For now, using custom logic in the cron handler to check frequency
        switch ($frequency) {
            case self::FREQUENCY_DAILY:
                return 'daily';
            case self::FREQUENCY_WEEKLY:
                return 'weekly';
            case self::FREQUENCY_MONTHLY:
                return 'monthly';
            case self::FREQUENCY_YEARLY:
                return 'yearly';
            default:
                return 'daily';
        }
    }

    /**
     * Format Post object to matched Scheduled Task structure
     * 
     * @param WP_Post $post Post object
     * @return object Formatted task
     */
    private function format_task($post) {
        $workflow_id = get_post_meta($post->ID, '_workflow_id', true);
        $workflow    = get_post($workflow_id);
        $last_run_ts = get_post_meta($post->ID, '_last_run', true);

        return (object) array(
            'id'           => $post->ID,
            'name'         => $post->post_title,
            'workflow_id'  => intval($workflow_id),
            /* translators: %s: Unknown workflow indicator */
            'workflow_name'=> $workflow ? $workflow->post_title : __('Unknown', 'kitsune-ai-platform'),
            'frequency'    => get_post_meta($post->ID, '_frequency', true),
            'start_date'   => get_post_meta($post->ID, '_start_date', true),
            'end_date'     => get_post_meta($post->ID, '_end_date', true),
            'time_of_day'  => get_post_meta($post->ID, '_time_of_day', true),
            'status'       => ($post->post_status === 'publish') ? 'active' : 'inactive',
            'next_run'     => $this->get_next_run_time($post->ID),
            'last_run'     => $last_run_ts
                ? sprintf(
                    /* translators: %s: Human-readable time difference. */
                    __('%s ago', 'kitsune-ai-platform'),
                    human_time_diff(strtotime($last_run_ts ?: 'now'), current_time('timestamp', true))
                )
                /* translators: %s: Never run indicator */
                : __('Never', 'kitsune-ai-platform'),
            'created_at'   => $post->post_date,
            'user_id'      => $post->post_author
        );
    }

    /**
     * Get next scheduled run time for a task
     * 
     * @param int $task_id Task ID
     * @return string|null Human-readable next run time
     */
    private function get_next_run_time($task_id) {
        $timestamp = wp_next_scheduled('kitsune_ai_platform_run_scheduled_task', array($task_id));
        if (!$timestamp) {
            return null;
        }

        return human_time_diff(current_time('timestamp', true), $timestamp) . ' ' . ($timestamp > current_time('timestamp', true) ? 'from now' : 'ago');
    }

    /**
     * Get frequency options for UI dropdown
     * 
     * @return array
     */
    public static function get_frequency_options() {
        return array(
            self::FREQUENCY_DAILY   => __('Daily', 'kitsune-ai-platform'),
            self::FREQUENCY_WEEKLY  => __('Weekly', 'kitsune-ai-platform'),
            self::FREQUENCY_MONTHLY => __('Monthly', 'kitsune-ai-platform'),
            self::FREQUENCY_YEARLY  => __('Yearly', 'kitsune-ai-platform'),
        );
    }

    /**
     * Update the last-run timestamp for a task (called by cron executor)
     *
     * @param int $task_id Task CPT ID
     */
    public function update_last_run($task_id) {
        update_post_meta($task_id, '_last_run', current_time('mysql', true));
    }

    /**
     * Reschedule all active tasks.
     * Useful after plugin activation / reactivation so cron events are restored.
     */
    public static function reschedule_all_active_tasks() {
        $model = new self();
        $args  = array(
            'post_type'      => 'kitsune_ai_sched_task',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'fields'         => 'ids',
        );

        $ids = get_posts($args);
        foreach ($ids as $task_id) {
            // Only schedule if not already scheduled
            if (!wp_next_scheduled('kitsune_ai_platform_run_scheduled_task', array($task_id))) {
                $model->schedule_cron_event($task_id);
            }
        }
    }
}
