import { Router } from 'express'
import { query, withTransaction } from '../config/database.js'
import { sendSuccess, sendError } from '../middleware/error.js'
import type { AuthRequest } from '../middleware/auth.js'

const router = Router()

// ============================================================
// 年度战略目标 (T-101)
// ============================================================

router.get('/annual', async (req: AuthRequest, res) => {
  try {
    const year = parseInt((req.query.year as string) || new Date().getFullYear().toString())
    const result = await query(
      `SELECT * FROM analytics.v3_annual_target WHERE year = $1 ORDER BY metric`, [year]
    )
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

router.post('/annual', async (req: AuthRequest, res) => {
  try {
    const { year, metric, target_value, description } = req.body
    const result = await query(`
      INSERT INTO analytics.v3_annual_target (year, metric, target_value, description, created_by)
      VALUES ($1, $2, $3, $4, $5)
      ON CONFLICT (year, metric) DO UPDATE SET
        target_value = EXCLUDED.target_value,
        description = EXCLUDED.description,
        updated_at = NOW()
      RETURNING *
    `, [year, metric, target_value, description, req.user?.name || 'system'])
    sendSuccess(res, result.rows[0])
  } catch (err: any) {
    sendError(res, err.message)
  }
})

router.delete('/annual/:id', async (req: AuthRequest, res) => {
  try {
    await query(`DELETE FROM analytics.v3_annual_target WHERE id = $1`, [req.params.id])
    sendSuccess(res, { deleted: true })
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 区域年度目标 (T-102)
// ============================================================

router.get('/regional', async (req: AuthRequest, res) => {
  try {
    const year = parseInt((req.query.year as string) || new Date().getFullYear().toString())
    const result = await query(
      `SELECT * FROM analytics.v3_regional_target WHERE year = $1 ORDER BY region`, [year]
    )
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

router.post('/regional', async (req: AuthRequest, res) => {
  try {
    const { year, region, revenue_target, profit_target, store_count_target, member_count_target, weight_pct } = req.body
    const result = await query(`
      INSERT INTO analytics.v3_regional_target (year, region, revenue_target, profit_target, store_count_target, member_count_target, weight_pct)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (year, region) DO UPDATE SET
        revenue_target = EXCLUDED.revenue_target,
        profit_target = EXCLUDED.profit_target,
        store_count_target = EXCLUDED.store_count_target,
        member_count_target = EXCLUDED.member_count_target,
        weight_pct = EXCLUDED.weight_pct,
        updated_at = NOW()
      RETURNING *
    `, [year, region, revenue_target, profit_target, store_count_target, member_count_target, weight_pct || 100])
    sendSuccess(res, result.rows[0])
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 门店月度目标 (T-103)
// ============================================================

router.get('/store-monthly', async (req: AuthRequest, res) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7) + '-01'
    const storeCode = req.query.store_code as string
    const conditions = [`month = $1`]
    const params: any[] = [month]
    if (storeCode) {
      conditions.push(`store_code = $2`)
      params.push(storeCode)
    }
    const result = await query(
      `SELECT * FROM analytics.v3_store_monthly_target WHERE ${conditions.join(' AND ')} ORDER BY store_code`,
      params
    )
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

router.post('/store-monthly', async (req: AuthRequest, res) => {
  try {
    const { month, store_code, store_name, region, grade, revenue_target, bill_count_target, avg_bill_value_target, member_penetration_target, cost_rate_target, profit_target } = req.body
    const year = new Date(month).getFullYear()
    const result = await query(`
      INSERT INTO analytics.v3_store_monthly_target (year, month, store_code, store_name, region, grade, revenue_target, bill_count_target, avg_bill_value_target, member_penetration_target, cost_rate_target, profit_target)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
      ON CONFLICT (month, store_code) DO UPDATE SET
        revenue_target = EXCLUDED.revenue_target,
        bill_count_target = EXCLUDED.bill_count_target,
        avg_bill_value_target = EXCLUDED.avg_bill_value_target,
        member_penetration_target = EXCLUDED.member_penetration_target,
        cost_rate_target = EXCLUDED.cost_rate_target,
        profit_target = EXCLUDED.profit_target,
        grade = EXCLUDED.grade,
        updated_at = NOW()
      RETURNING *
    `, [year, month, store_code, store_name, region, grade || 'B', revenue_target, bill_count_target, avg_bill_value_target, member_penetration_target, cost_rate_target, profit_target])
    sendSuccess(res, result.rows[0])
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 日级目标 (T-104)
// ============================================================

router.get('/daily', async (req: AuthRequest, res) => {
  try {
    const targetDate = (req.query.date as string) || new Date().toISOString().slice(0, 10)
    const storeCode = req.query.store_code as string
    const conditions = [`target_date = $1`]
    const params: any[] = [targetDate]
    if (storeCode) {
      conditions.push(`store_code = $2`)
      params.push(storeCode)
    }
    const result = await query(
      `SELECT * FROM analytics.v3_daily_target WHERE ${conditions.join(' AND ')} ORDER BY store_code`,
      params
    )
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 个人任务 (T-105)
// ============================================================

router.get('/personal-tasks', async (req: AuthRequest, res) => {
  try {
    const targetDate = (req.query.date as string) || new Date().toISOString().slice(0, 10)
    const storeCode = req.query.store_code as string
    const conditions = [`target_date = $1`]
    const params: any[] = [targetDate]
    if (storeCode) {
      conditions.push(`store_code = $2`)
      params.push(storeCode)
    }
    const result = await query(
      `SELECT * FROM analytics.v3_personal_task WHERE ${conditions.join(' AND ')} ORDER BY employee_name`,
      params
    )
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 目标自动拆解算法 (T-106, T-107)
// ============================================================

// T-106: 年度→区域→门店 拆解
router.post('/decompose/annual-to-store', async (req: AuthRequest, res) => {
  try {
    const { year, month } = req.body
    const targetMonth = month || `${year}-${String(new Date().getMonth() + 1).padStart(2, '0')}-01`

    const annualResult = await query(
      `SELECT metric, target_value FROM analytics.v3_annual_target WHERE year = $1`, [year]
    )
    const revenueTarget = annualResult.rows.find((r: any) => r.metric === 'revenue')
    if (!revenueTarget) {
      return sendError(res, `未找到 ${year} 年营收目标，请先设定年度目标`)
    }

    const regionalResult = await query(
      `SELECT region, weight_pct FROM analytics.v3_regional_target WHERE year = $1 ORDER BY region`, [year]
    )

    await withTransaction(async (client) => {
      for (const region of regionalResult.rows) {
        const storesResult = await client.query(`
          SELECT store_code, store_name, region FROM analytics.dim_store
          WHERE region = $1 AND close_date IS NULL
          ORDER BY store_code
        `, [region.region])

        const storeCount = storesResult.rows.length
        if (storeCount === 0) continue

        const regionalRevenue = Number(revenueTarget.target_value) * Number(region.weight_pct) / 100

        const gradesResult = await client.query(`
          SELECT store_code, grade FROM analytics.v3_store_grade
          WHERE grade_month = DATE_TRUNC('month', $1::date)::date
        `, [targetMonth])
        const gradeMap = new Map(gradesResult.rows.map((r: any) => [r.store_code, r.grade]))

        const weights = storesResult.rows.map((s: any) => {
          const grade = gradeMap.get(s.store_code) || 'B'
          switch (grade) {
            case 'A': return 1.1
            case 'B': return 1.0
            case 'C': return 0.9
            case 'D': return 0.7
            default: return 1.0
          }
        })
        const totalWeight = weights.reduce((a: number, b: number) => a + b, 0)

        for (let i = 0; i < storesResult.rows.length; i++) {
          const store = storesResult.rows[i]
          const storeRevenue = (regionalRevenue / 12) * (weights[i] / totalWeight)

          await client.query(`
            INSERT INTO analytics.v3_store_monthly_target (year, month, store_code, store_name, region, grade, revenue_target)
            VALUES ($1, $2, $3, $4, $5, $6, $7)
            ON CONFLICT (month, store_code) DO UPDATE SET
              revenue_target = EXCLUDED.revenue_target,
              grade = EXCLUDED.grade,
              updated_at = NOW()
          `, [year, targetMonth, store.store_code, store.store_name, store.region, gradeMap.get(store.store_code) || 'B', storeRevenue.toFixed(2)])
        }
      }
    })

    const countResult = await query(
      `SELECT count(*) AS total FROM analytics.v3_store_monthly_target WHERE month = $1`, [targetMonth]
    )
    sendSuccess(res, { month: targetMonth, stores: parseInt(countResult.rows[0].total) })
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// T-107: 月度→日 拆解
router.post('/decompose/monthly-to-daily', async (req: AuthRequest, res) => {
  try {
    const { month } = req.body
    const targetMonth = month || new Date().toISOString().slice(0, 8) + '01'

    const monthlyResult = await query(
      `SELECT store_code, store_name, revenue_target, bill_count_target FROM analytics.v3_store_monthly_target WHERE month = $1`,
      [targetMonth]
    )

    const year = parseInt(targetMonth.slice(0, 4))
    const monthNum = parseInt(targetMonth.slice(5, 7))
    const daysInMonth = new Date(year, monthNum, 0).getDate()

    await withTransaction(async (client) => {
      for (const target of monthlyResult.rows) {
        const dailyRevenue = Number(target.revenue_target) / daysInMonth
        const dailyBills = Number(target.bill_count_target || 0) / daysInMonth

        for (let day = 1; day <= daysInMonth; day++) {
          const dateStr = `${targetMonth.slice(0, 8)}${String(day).padStart(2, '0')}`
          const weight = (100 / daysInMonth).toFixed(2)

          await client.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, $6)
            ON CONFLICT (target_date, store_code) DO UPDATE SET
              revenue_target = EXCLUDED.revenue_target,
              bill_count_target = EXCLUDED.bill_count_target,
              weight_pct = EXCLUDED.weight_pct
          `, [dateStr, target.store_code, target.store_name, dailyRevenue.toFixed(2), Math.round(dailyBills), weight])
        }
      }
    })

    sendSuccess(res, { month: targetMonth, days: daysInMonth, stores: monthlyResult.rows.length })
  } catch (err: any) {
    sendError(res, err.message)
  }
})

// ============================================================
// 达成率计算
// ============================================================

router.get('/achievement', async (req: AuthRequest, res) => {
  try {
    const month = (req.query.month as string) || new Date().toISOString().slice(0, 7) + '-01'
    const result = await query(`
      SELECT
        t.store_code, t.store_name, t.region, t.grade,
        t.revenue_target,
        COALESCE(s.received, 0) AS actual_revenue,
        CASE WHEN t.revenue_target > 0
          THEN ROUND(COALESCE(s.received, 0) / t.revenue_target * 100, 2)
          ELSE 0 END AS achievement_rate,
        t.bill_count_target,
        COALESCE(s.bill_count, 0) AS actual_bill_count,
        CASE WHEN t.bill_count_target > 0
          THEN ROUND(COALESCE(s.bill_count, 0) / t.bill_count_target * 100, 2)
          ELSE 0 END AS bill_achievement_rate
      FROM analytics.v3_store_monthly_target t
      LEFT JOIN analytics.mv_store_risk_rating_monthly s
        ON s.store_code = t.store_code AND s.month_start = t.month
      WHERE t.month = $1
      ORDER BY achievement_rate DESC
    `, [month])
    sendSuccess(res, result.rows)
  } catch (err: any) {
    sendError(res, err.message)
  }
})

export default router
