/**
 * LiteMall 自动 SEO 文章生成器 · 每日调度器
 * 复用 app.js 的 setInterval 轻量模式：每 60 秒检查一次是否到达任务配置的生成时间。
 * 每个启用任务每天在其 generate_time 触发一次，按 daily_count 生成 N 篇（每篇选不同商品）。
 */

const { get, all, run } = require('../utils/db');
const generator = require('../lib/seo-article-generator');
const aiClient = require('../lib/ai-client');

const INTERVAL = 60 * 1000; // 每 60 秒检查
let timer = null;
let running = false;

// 进度回调（供 app.js 打日志，可留空）
const hooks = { onTick: null, onGenerate: null, onError: null };

function nowStr() { return new Date().toLocaleString('zh-CN', { hour12: false }); }
function today() { return new Date().toISOString().split('T')[0]; }

// 取可选商品列表（筛选未在本日生成过的）
function getEligibleProducts(task, excludeTodayIds) {
  let where = 'WHERE p.status=1';
  const params = [];
  if (task.category_id && task.category_id > 0) { where += ' AND p.category_id=?'; params.push(task.category_id); }
  if (task.max_price && task.max_price > 0) { where += ' AND p.price<=?'; params.push(task.max_price); }
  // 排除今天已生成过的商品
  if (excludeTodayIds.length) {
    where += ' AND p.id NOT IN (' + excludeTodayIds.map(() => '?').join(',') + ')';
    params.push(...excludeTodayIds);
  }
  return all(`SELECT p.*, c.name as category_name FROM products p LEFT JOIN categories c ON p.category_id=c.id ${where} ORDER BY p.sales DESC, p.id ASC`, params);
}

function insertArticle(article, task, productId) {
  const status = task.article_status === 1 ? 1 : 0; // 默认草稿
  const r = run(
    `INSERT INTO articles(title, category_id, author, cover, summary, content, sort, status, seo_keywords, source_product_id, is_ai_generated, ai_mode)
     VALUES(?,?,?,?,?,?,?,?,?,?,1,?)`,
    [article.title, task.category_id || null, 'SEO生成', '', article.summary, article.content, 0, status,
     (article.keywords || []).join(','), productId, article.mode]
  );
  return r.lastInsertRowid;
}

// 尝试为某个任务生成一批文章
async function runTask(task) {
  const todayIds = all('SELECT product_id FROM seo_generate_logs WHERE task_id=? AND gen_date=?', [task.id, today()]).map(r => r.product_id);
  const products = getEligibleProducts(task, todayIds);
  if (!products.length) {
    run("UPDATE seo_article_tasks SET last_run_date=? WHERE id=?", [today(), task.id]);
    run('INSERT INTO seo_generate_logs(task_id,product_id,mode,gen_date,status,message) VALUES(?,?,?,?,?,?)',
      [task.id, 0, task.mode, today(), 'skip', '无可生成商品或今日已全部生成']);
    return { gen: 0, skip: true };
  }
  const count = Math.min(task.daily_count || 1, products.length);
  let gen = 0;
  for (let i = 0; i < count; i++) {
    const p = products[i];
    try {
      const article = await generator.generateArticle(p, task);
      const articleId = insertArticle(article, task, p.id);
      run('INSERT INTO seo_generate_logs(task_id,product_id,article_id,mode,gen_date,title,status) VALUES(?,?,?,?,?,?,?)',
        [task.id, p.id, articleId, article.mode, today(), article.title, 'success']);
      gen++;
      if (hooks.onGenerate) hooks.onGenerate({ task, product: p, article, articleId });
    } catch (err) {
      const reason = String(err.message || err).slice(0, 300);
      run('INSERT INTO seo_generate_logs(task_id,product_id,mode,gen_date,status,message) VALUES(?,?,?,?,?,?)',
        [task.id, p.id, task.mode, today(), 'error', reason]);
      if (hooks.onError) hooks.onError({ task, product: p, error: err });
      // 单个失败不中断整批，但如果是 API Key 问题应停止
      if (/API Key|AI 服务调用失败|请先在后台配置/.test(reason)) break;
    }
  }
  run("UPDATE seo_article_tasks SET last_run_date=? WHERE id=?", [today(), task.id]);
  return { gen, total: count };
}

// 主调度：检查所有启用任务
async function tick() {
  if (running) return;
  running = true;
  try {
    const now = new Date();
    const hm = String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0');
    const tasks = all("SELECT * FROM seo_article_tasks WHERE enabled=1");
    for (const t of tasks) {
      const gtime = t.generate_time || '06:30';
      // 触达配置时间 且 今天尚未跑过
      if (hm === gtime && t.last_run_date !== today()) {
        const r = await runTask(t);
        if (hooks.onTick) hooks.onTick({ task: t, ...r, hm });
      }
    }
  } catch (e) {
    if (hooks.onError) hooks.onError({ error: e, msg: '调度器异常' });
  } finally {
    running = false;
  }
}

// 立即运行某个任务（供 admin 手动触发）
async function runTaskNow(taskId) {
  const task = get('SELECT * FROM seo_article_tasks WHERE id=?', [taskId]);
  if (!task) throw new Error('任务不存在');
  return await runTask(task);
}

function start() {
  if (timer) return;
  // 启动后先跑一次检查（若刚好到点）
  tick().catch(() => {});
  timer = setInterval(() => { tick().catch(() => {}); }, INTERVAL);
  timer.unref && timer.unref();
  console.log('[SEO调度器] 已启动，每60秒检查一次生成时间');
}

function stop() { if (timer) { clearInterval(timer); timer = null; } }

module.exports = { start, stop, tick, runTaskNow, hooks, INTERVAL };
