<?php
require_once __DIR__ . '/../base_api.php';

class CronAPI extends BaseAPI {

    /**
     * 解析 cron 表达式为宝塔参数
     */
    private function parseCronExpression($expr) {
        $expr = trim($expr);
        $parts = preg_split('/\s+/', $expr, 5);
        if (count($parts) < 5) {
            return array('type' => 'day', 'minute' => '0', 'hour' => '1', 'where1' => '1', 'week' => '');
        }
        $minute = $parts[0];
        $hour = $parts[1];
        $dayOfMonth = $parts[2];
        $month = $parts[3];
        $dayOfWeek = isset($parts[4]) ? $parts[4] : '*';
        
        // 每N分钟
        if (strpos($minute, '*/') === 0) {
            return array('type' => 'minute-n', 'minute' => str_replace('*/', '', $minute), 'hour' => '0', 'where1' => '1', 'week' => '');
        }
        // 每N小时
        if (strpos($hour, '*/') === 0) {
            return array('type' => 'hour-n', 'minute' => $minute, 'hour' => str_replace('*/', '', $hour), 'where1' => '1', 'week' => '');
        }
        // 每小时
        if ($hour === '*' && $dayOfMonth === '*' && $dayOfWeek === '*') {
            return array('type' => 'hour', 'minute' => $minute, 'hour' => '0', 'where1' => '1', 'week' => '');
        }
        // 每周
        if ($dayOfWeek !== '*' && $dayOfWeek !== '') {
            return array('type' => 'week', 'minute' => $minute, 'hour' => $hour, 'where1' => '1', 'week' => $dayOfWeek);
        }
        // 每N天
        if (strpos($dayOfMonth, '*/') === 0) {
            return array('type' => 'day-n', 'minute' => $minute, 'hour' => $hour, 'where1' => str_replace('*/', '', $dayOfMonth), 'week' => '');
        }
        // 每天
        return array('type' => 'day', 'minute' => $minute, 'hour' => $hour, 'where1' => '1', 'week' => '');
    }

    /**
     * 从宝塔任务项构建 cron 表达式
     */
    private function buildCronExpression($task) {
        $minute = isset($task['minute']) ? $task['minute'] : '0';
        $hour = isset($task['hour']) ? $task['hour'] : '1';
        $where1 = isset($task['where1']) ? $task['where1'] : '1';
        $week = isset($task['week']) ? $task['week'] : '';
        $type = isset($task['type']) ? $task['type'] : 'day';
        
        if ($type === 'week' && $week !== '') {
            return $minute . ' ' . $hour . ' * * ' . $week;
        }
        if ($type === 'hour') {
            return $minute . ' * * * *';
        }
        if ($type === 'hour-n' || strpos($type, 'hour') !== false) {
            return $minute . ' */' . $hour . ' * * *';
        }
        if ($type === 'minute-n' || strpos($type, 'minute') !== false) {
            return '*/' . $minute . ' * * * *';
        }
        if ($type === 'day-n') {
            return $minute . ' ' . $hour . ' */' . $where1 . ' * *';
        }
        return $minute . ' ' . $hour . ' * * *';
    }

    /**
     * 解析任务类型和URL
     */
    private function parseTaskInfo($task) {
        $command = isset($task['sBody']) ? $task['sBody'] : (isset($task['echo']) ? $task['echo'] : '');
        $name = isset($task['name']) ? $task['name'] : '';
        
        $taskType = 'URL-GET';
        $url = '';
        
        // 从命令中解析
        if (strpos($command, '-X POST') !== false || strpos($command, 'POST') !== false) {
            $taskType = 'URL-POST';
        }
        
        // 提取URL
        if (preg_match("/curl.*?['\"]?(https?:\/\/[^'\"\\s]+)['\"]?/i", $command, $matches)) {
            $url = $matches[1];
        } elseif (preg_match("/(https?:\/\/[^\\s'\"]+)/i", $command, $matches)) {
            $url = $matches[1];
        }
        
        // 从任务名称中提取显示名称（去掉前缀）
        $displayName = $name;
        if (preg_match('/^(MNBT|ELEML TOD)_[^_]+_(.+)$/', $name, $matches)) {
            $displayName = $matches[2];
        }
        
        return array(
            'task_type' => $taskType,
            'url' => $url,
            'display_name' => $displayName
        );
    }

    /**
     * 生成周期描述文本
     */
    private function getCycleText($task) {
        $type = isset($task['type']) ? $task['type'] : 'day';
        $minute = isset($task['minute']) ? intval($task['minute']) : 0;
        $hour = isset($task['hour']) ? intval($task['hour']) : 1;
        $where1 = isset($task['where1']) ? intval($task['where1']) : 1;
        $week = isset($task['week']) ? $task['week'] : '';
        
        $weekNames = array('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
        $h = str_pad($hour, 2, '0', STR_PAD_LEFT);
        $m = str_pad($minute, 2, '0', STR_PAD_LEFT);
        
        switch ($type) {
            case 'day':
                return "每天 {$h}:{$m} 执行";
            case 'day-n':
                return "每隔 {$where1} 天 {$h}:{$m} 执行";
            case 'hour':
                return "每小时第 {$minute} 分钟执行";
            case 'hour-n':
                return "每隔 {$hour} 小时第 {$minute} 分钟执行";
            case 'minute-n':
                return "每隔 {$minute} 分钟执行";
            case 'week':
                $wn = isset($weekNames[intval($week)]) ? $weekNames[intval($week)] : $week;
                return "每{$wn} {$h}:{$m} 执行";
        }
        return '';
    }

    /**
     * 映射宝塔任务为前端格式
     */
    private function mapTask($item) {
        $status = isset($item['status']) ? (int)$item['status'] : 1;
        $command = isset($item['sBody']) ? $item['sBody'] : (isset($item['echo']) ? $item['echo'] : '');
        $taskInfo = $this->parseTaskInfo($item);
        
        return array(
            'id' => isset($item['id']) ? $item['id'] : (isset($item['_id']) ? $item['_id'] : ''),
            'name' => isset($item['name']) ? $item['name'] : '未命名',
            'display_name' => $taskInfo['display_name'],
            'command' => $command,
            'url' => $taskInfo['url'],
            'task_type' => $taskInfo['task_type'],
            'cron_expression' => $this->buildCronExpression($item),
            'cycle_text' => $this->getCycleText($item),
            'status' => $status === 1 ? 'enabled' : 'disabled',
            'run_count' => isset($item['count']) ? (int)$item['count'] : 0,
            'last_run_time' => isset($item['addtime']) ? $item['addtime'] : ''
        );
    }

    public function getCronTasks() {
        $prefix = isset($_POST['prefix']) ? $_POST['prefix'] : '';
        
        $result = $this->bt_api->shell_list('');
        if (!$result) {
            $this->success(array('tasks' => array()));
            return;
        }
        
        $list = array();
        $rawList = array();
        
        if (isset($result['data']) && is_array($result['data'])) {
            $rawList = $result['data'];
        } elseif (is_array($result) && isset($result[0]['id'])) {
            $rawList = $result;
        } elseif (is_array($result) && !isset($result['status'])) {
            $rawList = $result;
        }
        
        foreach ($rawList as $item) {
            if (!is_array($item)) continue;
            $name = isset($item['name']) ? $item['name'] : '';
            
            // 如果指定了前缀，只返回匹配的任务
            if ($prefix && strpos($name, $prefix) !== 0) {
                continue;
            }
            
            $list[] = $this->mapTask($item);
        }
        
        $this->success(array('tasks' => $list));
    }

    public function addCronTask() {
        $name = isset($_POST['name']) ? trim($_POST['name']) : '';
        $command = isset($_POST['command']) ? trim($_POST['command']) : '';
        $cron_expression = isset($_POST['cron_expression']) ? trim($_POST['cron_expression']) : '0 1 * * *';
        
        if (empty($name) || empty($command)) {
            $this->error('任务名称和执行命令不能为空');
        }
        
        $params = $this->parseCronExpression($cron_expression);
        
        $url = $this->bt_api->BT_PANEL . '/crontab?action=AddCrontab';
        $p_data = $this->bt_api->GetKeyData();
        $p_data['name'] = $name;
        $p_data['type'] = $params['type'];
        $p_data['where1'] = $params['where1'];
        $p_data['hour'] = $params['hour'];
        $p_data['minute'] = $params['minute'];
        $p_data['week'] = $params['week'];
        $p_data['sType'] = 'toShell';
        $p_data['sBody'] = $command;
        $p_data['save'] = '';
        $p_data['backupTo'] = 'localhost';
        $p_data['sName'] = '';
        $p_data['urladdress'] = '';
        
        $result = $this->bt_api->HttpPostCookie($url, $p_data);
        $data = json_decode($result, true);
        
        if (isset($data['status']) && $data['status'] === false) {
            $this->error(isset($data['msg']) ? $data['msg'] : '添加任务失败');
        }
        
        $this->success(array('msg' => '添加成功'));
    }

    public function toggleCronTask() {
        $id = isset($_POST['id']) ? $_POST['id'] : '';
        if (empty($id)) {
            $this->error('任务ID不能为空');
        }
        
        // 获取当前状态
        $listResult = $this->bt_api->shell_list('');
        $currentStatus = 1;
        $list = array();
        
        if (isset($listResult['data'])) {
            $list = $listResult['data'];
        } elseif (is_array($listResult) && !isset($listResult['status'])) {
            $list = $listResult;
        }
        
        foreach ($list as $item) {
            $tid = isset($item['id']) ? $item['id'] : (isset($item['_id']) ? $item['_id'] : null);
            if ((string)$tid === (string)$id) {
                $currentStatus = isset($item['status']) ? (int)$item['status'] : 1;
                break;
            }
        }
        
        $newStatus = $currentStatus === 1 ? 0 : 1;
        
        // 尝试使用 SetCrontabStatus
        if (method_exists($this->bt_api, 'SetCrontabStatus')) {
            $result = $this->bt_api->SetCrontabStatus($id, $newStatus);
        } else {
            // 回退：直接调用API
            $url = $this->bt_api->BT_PANEL . '/crontab?action=SetCrontabStatus';
            $p_data = $this->bt_api->GetKeyData();
            $p_data['id'] = $id;
            $p_data['status'] = $newStatus ? '1' : '0';
            $res = $this->bt_api->HttpPostCookie($url, $p_data);
            $result = json_decode($res, true);
        }
        
        if (isset($result['status']) && $result['status'] === false) {
            $this->error(isset($result['msg']) ? $result['msg'] : '操作失败');
        }
        
        $this->success(array('msg' => '状态已更新'));
    }

    public function deleteCronTask() {
        $id = isset($_POST['id']) ? $_POST['id'] : '';
        if (empty($id)) {
            $this->error('任务ID不能为空');
        }
        
        $result = $this->bt_api->shell_del($id);
        
        if (isset($result['status']) && $result['status'] === false) {
            $this->error(isset($result['msg']) ? $result['msg'] : '删除失败');
        }
        
        $this->success(array('msg' => '删除成功'));
    }
}
