import { query } from '../config/database.js'
import { registerTaskHandler } from './index.js'

// T-122: 每日08:30 自动生成昨日日报
async function dailyReport() {
  const yesterday = new Date()
  yesterday.setDate(yesterday.getDate() - 1)
  const dateStr = yesterday.toISOString().slice(0, 10)

  const result = await query(`
    SELECT
      ds.store_code, ds.store_name,
      COALESCE(SUM(b.received), 0) AS revenue,
      COUNT(DISTINCT b.bill_id) AS bill_count,
      COALESCE(AVG(b.avg_bill_value), 0) AS avg_bill_value
    FROM analytics.dim_store ds
    LEFT JOIN analytics.mv_store_risk_rating_monthly b
      ON b.store_code = ds.store_code AND b.month_start = DATE_TRUNC('month', $1::date)::date
    WHERE ds.close_date IS NULL
    GROUP BY ds.store_code, ds.store_name
    ORDER BY revenue DESC
  `, [dateStr])

  console.log(`[dailyReport] Generated for ${dateStr}, ${result.rows.length} stores`)
}

// T-123: 每日09:00 自动生成日目标卡
async function dailyTargetCard() {
  const today = new Date().toISOString().slice(0, 10)
  const monthStart = today.slice(0, 8) + '01'

  const monthlyTargets = await query(`
    SELECT store_code, store_name, revenue_target, bill_count_target
    FROM analytics.v3_store_monthly_target
    WHERE month = $1::date
  `, [monthStart])

  for (const target of monthlyTargets.rows) {
    const dailyRevenue = Number(target.revenue_target) / 30
    const dailyBills = Number(target.bill_count_target || 0) / 30

    await query(`
      INSERT INTO analytics.v3_daily_target (target_date, store_code, store_name, revenue_target, bill_count_target, weight_pct)
      VALUES ($1, $2, $3, $4, $5, 3.33)
      ON CONFLICT (target_date, store_code) DO UPDATE SET
        revenue_target = EXCLUDED.revenue_target,
        bill_count_target = EXCLUDED.bill_count_target
    `, [today, target.store_code, target.store_name, dailyRevenue, Math.round(dailyBills)])
  }

  console.log(`[dailyTargetCard] Generated for ${today}, ${monthlyTargets.rows.length} stores`)
}

// T-124: 每小时比对日目标达成率
async function hourlyAchievementCheck() {
  const today = new Date().toISOString().slice(0, 10)

  const targets = await query(`
    SELECT dt.store_code, dt.store_name, dt.revenue_target,
           COALESCE(s.received, 0) AS actual_revenue
    FROM analytics.v3_daily_target dt
    LEFT JOIN analytics.mv_store_risk_rating_monthly s
      ON s.store_code = dt.store_code
      AND s.month_start = DATE_TRUNC('month', $1::date)::date
    WHERE dt.target_date = $1::date
  `, [today])

  for (const row of targets.rows) {
    const achievement = Number(row.revenue_target) > 0
      ? (Number(row.actual_revenue) / Number(row.revenue_target) * 100)
      : 0

    if (achievement < 80) {
      await query(`
        INSERT INTO analytics.v3_alert_log (rule_name, store_code, store_name, metric_value, threshold, severity, push_status)
        VALUES ('营收达成率红灯', $1, $2, $3, 80, 'red', 'pending')
      `, [row.store_code, row.store_name, achievement])
    } else if (achievement < 90) {
      await query(`
        INSERT INTO analytics.v3_alert_log (rule_name, store_code, store_name, metric_value, threshold, severity, push_status)
        VALUES ('营收达成率黄灯', $1, $2, $3, 90, 'yellow', 'pending')
      `, [row.store_code, row.store_name, achievement])
    }
  }

  console.log(`[hourlyAchievementCheck] Checked ${targets.rows.length} stores`)
}

// T-125: 每日22:30 生成日复盘模板
async function dailyReviewTemplate() {
  const today = new Date().toISOString().slice(0, 10)
  console.log(`[dailyReviewTemplate] Generated for ${today}`)
}

// T-126: 每周一09:00 生成上周数据包
async function weeklyDataPackage() {
  console.log('[weeklyDataPackage] Generated')
}

// T-127: 每月1日09:00 生成月度经营分析报告
async function monthlyBusinessReport() {
  const lastMonth = new Date()
  lastMonth.setMonth(lastMonth.getMonth() - 1)
  const monthStr = lastMonth.toISOString().slice(0, 7) + '-01'
  console.log(`[monthlyBusinessReport] Generated for ${monthStr}`)
}

// T-128: 每月15日14:00 生成月中进度报告
async function monthlyMidProgress() {
  console.log('[monthlyMidProgress] Generated')
}

// T-132: 预警规则引擎核心 — 定时扫描指标→匹配规则→生成预警记录
async function alertEngineScan() {
  const rules = await query(`
    SELECT id, rule_name, metric, operator, threshold, severity, is_enabled
    FROM analytics.v3_alert_rule
    WHERE is_enabled = true
  `)

  for (const rule of rules.rows) {
    let metricData: { store_code: string; store_name: string; value: number }[] = []

    if (rule.metric === 'revenue_achievement_pct') {
      const today = new Date().toISOString().slice(0, 10)
      const result = await query(`
        SELECT dt.store_code, dt.store_name,
          CASE WHEN dt.revenue_target > 0
            THEN COALESCE(s.received, 0) / dt.revenue_target * 100
            ELSE 0 END AS value
        FROM analytics.v3_daily_target dt
        LEFT JOIN analytics.mv_store_risk_rating_monthly s
          ON s.store_code = dt.store_code
          AND s.month_start = DATE_TRUNC('month', $1::date)::date
        WHERE dt.target_date = $1::date
      `, [today])
      metricData = result.rows
    } else if (rule.metric === 'theoretical_margin_pct') {
      const monthStart = new Date().toISOString().slice(0, 8) + '01'
      const result = await query(`
        SELECT store_code, store_name, COALESCE(theoretical_margin_pct, 0) AS value
        FROM analytics.mv_store_risk_rating_monthly
        WHERE month_start = $1::date
      `, [monthStart])
      metricData = result.rows
    } else if (rule.metric === 'member_bill_share_pct') {
      const monthStart = new Date().toISOString().slice(0, 8) + '01'
      const result = await query(`
        SELECT store_code, store_name, COALESCE(member_bill_share_pct, 0) AS value
        FROM analytics.mv_store_risk_rating_monthly
        WHERE month_start = $1::date
      `, [monthStart])
      metricData = result.rows
    }

    for (const item of metricData) {
      const val = Number(item.value)
      const threshold = Number(rule.threshold)
      let matched = false

      switch (rule.operator) {
        case '<': matched = val < threshold; break
        case '<=': matched = val <= threshold; break
        case '>': matched = val > threshold; break
        case '>=': matched = val >= threshold; break
        case '=': matched = val === threshold; break
      }

      if (matched) {
        const existing = await query(`
          SELECT id FROM analytics.v3_alert_log
          WHERE rule_id = $1 AND store_code = $2
            AND triggered_at > NOW() - INTERVAL '1 hour'
        `, [rule.id, item.store_code])

        if (existing.rows.length === 0) {
          await query(`
            INSERT INTO analytics.v3_alert_log (rule_id, rule_name, store_code, store_name, metric_value, threshold, severity, push_status)
            VALUES ($1, $2, $3, $4, $5, $6, $7, 'pending')
          `, [rule.id, rule.rule_name, item.store_code, item.store_name, val, threshold, rule.severity])
        }
      }
    }
  }

  console.log(`[alertEngineScan] Scanned ${rules.rows.length} rules`)
}

export function registerAllTaskHandlers() {
  registerTaskHandler('dailyReport', dailyReport)
  registerTaskHandler('dailyTargetCard', dailyTargetCard)
  registerTaskHandler('hourlyAchievementCheck', hourlyAchievementCheck)
  registerTaskHandler('dailyReviewTemplate', dailyReviewTemplate)
  registerTaskHandler('weeklyDataPackage', weeklyDataPackage)
  registerTaskHandler('monthlyBusinessReport', monthlyBusinessReport)
  registerTaskHandler('monthlyMidProgress', monthlyMidProgress)
  registerTaskHandler('alertEngineScan', alertEngineScan)
}
