const express = require('express');

const bargainRouter = express.Router();
const adminBargain = express.Router();

const { get, run, all, transaction } = require('../utils/db');
const { success, fail, page } = require('../utils/response');
const { mul, add, sub, toNum } = require('../utils/money');
const { authUser, authAdmin } = require('../middleware/auth');
const { isPremium } = require('../lib/limits');
const paymentSdk = require('../lib/payment');

// NOTE: genOrderNo 前缀+日期+随机数，随机位10位，单日碰撞概率可忽略
function genOrderNo(prefix) {
  const now = new Date();
  const date = `${now.getFullYear()}${String(now.getMonth()+1).padStart(2,'0')}${String(now.getDate()).padStart(2,'0')}`;
  const rand = String(Math.floor(Math.random() * 10000000000)).padStart(10, '0');
  return `${prefix}${date}${rand}`;
}

// ===================== 砍价 用户端 API =====================

// 活动列表（前端公开）
bargainRouter.get('/list', (req, res) => {
  try {
    const { page: p = 1, pageSize = 20 } = req.query;
    const pageNum = Math.max(1, +p);
    const size = Math.min(50, Math.max(1, +pageSize));
    const total = get('SELECT COUNT(*) as c FROM bargain_activities WHERE status=1').c;
    const list = all(`SELECT ba.*, p.name as product_name, p.image as product_image, p.price as product_price
      FROM bargain_activities ba LEFT JOIN products p ON ba.product_id=p.id
      WHERE ba.status=1 ORDER BY ba.id DESC LIMIT ? OFFSET ?`, [size, (pageNum - 1) * size]);
    return res.json(page(list, total, pageNum, size));
  } catch (e) {
    return res.json(fail('获取失败'));
  }
});

// 我的砍价单（付费）
bargainRouter.get('/session', authUser, (req, res) => {
  try {
    if (!isPremium()) return res.json(fail('付费版专属功能'));
    const { page: p = 1, pageSize = 50 } = req.query;
    const pageNum = Math.max(1, +p);
    const size = Math.min(100, Math.max(1, +pageSize));
    const total = get('SELECT COUNT(*) as c FROM bargain_sessions WHERE user_id=?', [req.userId]).c;
    const list = all(`SELECT s.*, ba.name as activity_name, ba.product_id, p.name as product_name, p.image as product_image
      FROM bargain_sessions s
      LEFT JOIN bargain_activities ba ON s.activity_id=ba.id
      LEFT JOIN products p ON ba.product_id=p.id
      WHERE s.user_id=? ORDER BY s.id DESC LIMIT ? OFFSET ?`, [req.userId, size, (pageNum - 1) * size]);
    return res.json(page(list, total, pageNum, size));
  } catch (e) {
    return res.json(fail('获取失败'));
  }
});

// 活动详情（公开）
bargainRouter.get('/:id', (req, res) => {
  try {
    const ba = get(`SELECT ba.*, p.name as product_name, p.image as product_image, p.images, p.description, p.price as product_price
      FROM bargain_activities ba LEFT JOIN products p ON ba.product_id=p.id WHERE ba.id=? AND ba.status=1`, [req.params.id]);
    if (!ba) return res.json(fail('砍价活动不存在或已结束'));
    return res.json(success(ba));
  } catch (e) {
    return res.json(fail('获取失败'));
  }
});

// 发起砍价（付费）→ 生成砍价单
bargainRouter.post('/start', authUser, (req, res) => {
  try {
    if (!isPremium()) return res.json(fail('付费版专属功能'));
    const { activity_id, quantity } = req.body;
    const qty = Math.max(1, Math.min(999, Math.floor(Number(quantity)) || 1));
    const ba = get('SELECT * FROM bargain_activities WHERE id=? AND status=1', [activity_id]);
    if (!ba) return res.json(fail('砍价活动不存在或已结束'));
    const now = Date.now();
    if (now < new Date(ba.start_time.replace(' ', 'T')).getTime()) return res.json(fail('活动未开始'));
    if (now > new Date(ba.end_time.replace(' ', 'T')).getTime()) return res.json(fail('活动已结束'));
    // 限购：进行中/可下单的未完成单
    if (ba.limit_count > 0) {
      const c = get(`SELECT COUNT(*) as c FROM bargain_sessions WHERE activity_id=? AND user_id=? AND status IN ('bargaining','can_order')`, [activity_id, req.userId]).c;
      if (c + qty > ba.limit_count) return res.json(fail('超出限购数量'));
    }
    const sessionNo = genOrderNo('JK');
    const hours = ba.expire_hours > 0 ? ba.expire_hours : 24;
    let expireAt;
    try { expireAt = new Date(Date.now() + hours * 3600 * 1000).toISOString().replace('T', ' ').slice(0, 19); } catch (e) { expireAt = new Date(Date.now() + 86400000).toISOString().replace('T', ' ').slice(0, 19); }
    transaction(() => {
      run(`INSERT INTO bargain_sessions(session_no,activity_id,user_id,original_price,current_price,floor_price,quantity,helped_count,status,expire_at)
        VALUES(?,?,?,?,?,?,?,?,?,?)`,
        [sessionNo, activity_id, req.userId, ba.original_price, ba.original_price, ba.floor_price, qty, 0, 'bargaining', expireAt]);
    });
    const s = get('SELECT * FROM bargain_sessions WHERE session_no=?', [sessionNo]);
    return res.json(success({ session: s, share_url: `/api/bargain/session/${sessionNo}` }));
  } catch (e) {
    return res.json(fail('发起失败'));
  }
});

// 好友帮砍（付费）→ 随机减价，写帮砍记录
bargainRouter.post('/help', authUser, (req, res) => {
  try {
    if (!isPremium()) return res.json(fail('付费版专属功能'));
    const { session_no } = req.body;
    const s = get('SELECT * FROM bargain_sessions WHERE session_no=?', [session_no]);
    if (!s) return res.json(fail('砍价单不存在'));
    if (s.status !== 'bargaining') return res.json(fail('该砍价单当前不可再砍'));
    if (s.user_id === req.userId) return res.json(fail('不能帮自己砍价'));
    const now = Date.now();
    if (now > new Date(s.expire_at.replace(' ', 'T')).getTime()) { run(`UPDATE bargain_sessions SET status='expired' WHERE id=?`, [s.id]); return res.json(fail('砍价已到期')); }
    // 是否已帮该单砍过
    const existed = get('SELECT id FROM bargain_helps WHERE session_id=? AND user_id=?', [s.id, req.userId]);
    if (existed) return res.json(fail('您已帮该单砍过价'));
    // 活动级每人最多帮砍 N 个不同 session
    const ba = get('SELECT * FROM bargain_activities WHERE id=?', [s.activity_id]);
    if (ba && ba.help_limit > 0) {
      const hc = get(`SELECT COUNT(DISTINCT session_id) as c FROM bargain_helps WHERE user_id=? AND activity_id=?`, [req.userId, s.activity_id]).c;
      if (hc + 1 > ba.help_limit) return res.json(fail('帮砍次数已达上限'));
    }
    // 计算随机砍掉金额：剩余空间 8%~20%；剩余 ≤1元 时直接砍到底，保证能砍到可下单价
    const current = toNum(s.current_price);
    const floor = toNum(s.floor_price);
    const oldCents = toNum(mul(current, 100));
    const floorCents = toNum(mul(floor, 100));
    const remain = Math.max(0, oldCents - floorCents); // 剩余分值
    if (remain <= 0) { run(`UPDATE bargain_sessions SET status='can_order' WHERE id=?`, [s.id]); return res.json(fail('已砍到最低价，无需再砍')); }
    let cutCents;
    if (remain <= 100) {
      cutCents = remain; // 剩余 ≤1元，一次到底，触底可下单
    } else {
      const r = Math.random() * (0.20 - 0.08) + 0.08; // 8%~20%
      cutCents = Math.max(1, Math.floor(remain * r));
    }
    // 兜底：若取到0，至少砍1分
    if (cutCents < 1) cutCents = 1;
    // 是否砍到底（永不跌破底价）
    const newCents = Math.max(floorCents, oldCents - cutCents);
    const newPrice = toNum(newCents / 100);
    const reachedFloor = newCents <= floorCents;
    const amount = toNum(cutCents / 100);
    let updated;
    transaction(() => {
      // CAS 防并发覆盖：仅当 current_price 仍是读到的旧值才扣减，否则回滚让请求重试
      const upd = run(`UPDATE bargain_sessions
        SET current_price=?, helped_count=helped_count+1, status=CASE WHEN ?=1 THEN 'can_order' ELSE 'bargaining' END
        WHERE id=? AND status='bargaining' AND current_price=?`,
        [newPrice, reachedFloor ? 1 : 0, s.id, s.current_price]);
      if (upd.changes === 0) throw new Error('同时砍价，请重试');
      // UNIQUE(session_id,user_id) 防刷兜底：冲突则整单回滚
      run(`INSERT INTO bargain_helps(session_id,activity_id,user_id,amount,created_at) VALUES(?,?,?,?,datetime('now','localtime'))`,
        [s.id, ba ? ba.id : s.activity_id, req.userId, amount]);
      updated = { current_price: newPrice, floor_price: s.floor_price, status: reachedFloor ? 'can_order' : 'bargaining', helped_count: +s.helped_count + 1, amount };
    });
    return res.json(success(updated));
  } catch (e) {
    return res.json(fail('帮砍失败'));
  }
});

// 砍价单详情（公开，用于分享/展示）
bargainRouter.get('/session/:no', (req, res) => {
  try {
    const s = get(`SELECT s.*, ba.name as activity_name, ba.product_id, p.image as product_image, p.name as product_name,
      u.nickname as owner_nickname
      FROM bargain_sessions s
      LEFT JOIN bargain_activities ba ON s.activity_id=ba.id
      LEFT JOIN products p ON ba.product_id=p.id
      LEFT JOIN users u ON s.user_id=u.id
      WHERE s.session_no=?`, [req.params.no]);
    if (!s) return res.json(fail('砍价单不存在'));
    const helps = all('SELECT bh.amount, u.nickname FROM bargain_helps bh LEFT JOIN users u ON bh.user_id=u.id WHERE bh.session_id=? ORDER BY bh.id DESC', [s.id]);
    s.helps = helps;
    return res.json(success(s));
  } catch (e) {
    return res.json(fail('获取失败'));
  }
});

// 按当前价下单（付费）→ 真实支付链 + CAS 扣活动库存
bargainRouter.post('/order', authUser, (req, res) => {
  try {
    if (!isPremium()) return res.json(fail('付费版专属功能'));
    const { session_no, payment_method } = req.body;
    const method = payment_method === 'alipay' ? 'alipay' : 'wechat';
    const s = get('SELECT * FROM bargain_sessions WHERE session_no=?', [session_no]);
    if (!s) return res.json(fail('砍价单不存在'));
    if (s.user_id !== req.userId) return res.json(fail('无权操作该砍价单'));
    if (s.status !== 'can_order') return res.json(fail('尚未砍到可下单价格'));
    const now = Date.now();
    if (now > new Date(s.expire_at.replace(' ', 'T')).getTime()) { run(`UPDATE bargain_sessions SET status='expired' WHERE id=?`, [s.id]); return res.json(fail('砍价已到期')); }
    const ba = get('SELECT * FROM bargain_activities WHERE id=? AND status=1', [s.activity_id]);
    if (!ba) return res.json(fail('活动不存在或已结束'));
    // 金额用整数分计算，全程无浮点（商城铁律）
    const qty = Math.max(1, Math.floor(Number(s.quantity)) || 1);
    const priceCents = toNum(mul(s.current_price, 100));      // 已触底，价格固定
    const payAmountCents = mul(priceCents, qty);
    const payAmount = toNum(payAmountCents / 100);
    // 只读数据（商品名/图）移出事务，缩小写锁持有时间
    const product = get('SELECT name, image FROM products WHERE id=?', [ba.product_id]);
    if (!product) throw new Error('商品不存在');
    let result;
    transaction(() => {
      // CAS 扣活动库存（防超卖铁律）
      const r = run(`UPDATE bargain_activities SET stock=stock-? WHERE id=? AND stock>=?`, [qty, ba.id, qty]);
      if (r.changes === 0) throw new Error('活动库存不足');
      // 防重复下单：can_order -> ordered 切换
      const upd = run(`UPDATE bargain_sessions SET status='ordered' WHERE id=? AND status='can_order'`, [s.id]);
      if (upd.changes === 0) throw new Error('该砍价单已下单');
      const orderNo = genOrderNo('BK');
      // better-sqlite3 run() 返回 lastInsertRowid，避免两次 SELECT
      const oi = run(`INSERT INTO orders(order_no,user_id,total_amount,discount_amount,shipping_fee,pay_amount,paid_amount,payment_method,status,created_at,updated_at)
        VALUES(?,?,?,?,?,?,?,?,?,datetime('now','localtime'),datetime('now','localtime'))`,
        [orderNo, req.userId, payAmount, 0, 0, payAmount, 0, method, 'pending_pay']);
      const orderId = oi.lastInsertRowid;
      run(`INSERT INTO order_items(order_id,product_id,product_name,image,price,quantity,subtotal)
        VALUES(?,?,?,?,?,?,?)`,
        [orderId, ba.product_id, product.name, product.image || '', payAmount, qty, payAmount]);
      // 写 pending 支付流水
      const tradeNo = 'BWY' + Date.now() + Math.floor(Math.random() * 900 + 100);
      run(`INSERT INTO payment_records(trade_no,order_id,user_id,amount,method,status,created_at)
        VALUES(?,?,?,?,?,?,datetime('now','localtime'))`,
        [tradeNo, orderId, req.userId, payAmount, method, 'pending']);
      let payUrl = null;
      if (paymentSdk.isSimulateMode()) payUrl = `/api/bargain/order/${orderNo}/mock-pay?trade_no=${tradeNo}`;
      result = { order_no: orderNo, amount: payAmount, pay_url: payUrl, is_mock: paymentSdk.isSimulateMode() };
    });
    return res.json(success(result));
  } catch (e) {
    return res.json(fail(e.message || '下单失败'));
  }
});

// 模拟支付确认（仅 isSimulateMode，防伪）
// 遵循项目约定：GET + query 参数 + 返回成功页；并继承 group-bulk 的归属/核价/原子加固
bargainRouter.get('/order/:no/mock-pay', (req, res) => {
  try {
    if (!paymentSdk.isSimulateMode()) return res.status(403).send('模拟支付已禁用');
    const { trade_no: tradeNo } = req.query;
    if (!tradeNo) return res.send('缺少流水号');
    // 归属校验：流水必须挂到该订单，且订单存在
    const p = get(`SELECT r.*, o.user_id AS order_user, o.pay_amount AS order_pay, o.order_no AS order_no
      FROM payment_records r JOIN orders o ON r.order_id=o.id
      WHERE r.trade_no=?`, [tradeNo]);
    if (!p) return res.send('流水不存在');
    if (String(p.order_no) !== String(req.params.no)) return res.send('订单与流水不匹配');
    if (p.status === 'success') return res.send(`<html><meta charset="utf-8"><body style="font-family:sans-serif;text-align:center;padding:80px 20px"><div style="color:#10b981;font-size:48px">✅</div><h2>该订单已支付</h2><p style="color:#666">订单: ${req.params.no}</p></body></html>`);
    // 核价：流水金额必须与订单应付一致（整数分比较，防篡改）
    if (toNum(p.amount) !== toNum(p.order_pay)) return res.send('支付金额校验失败，已拒绝');
    transaction(() => {
      run(`UPDATE payment_records SET status='success', pay_time=datetime('now','localtime') WHERE trade_no=? AND status='pending'`, [tradeNo]);
      run(`UPDATE orders SET status='pending_ship', paid_amount=?, updated_at=datetime('now','localtime')
        WHERE order_no=? AND status='pending_pay'`, [toNum(p.order_pay), req.params.no]);
    });
    return res.send(`<html><meta charset="utf-8"><title>模拟支付成功</title><body style="font-family:sans-serif;text-align:center;padding:80px 20px"><div style="color:#10b981;font-size:48px">✅</div><h2>模拟支付成功</h2><p style="color:#666">订单: ${req.params.no}</p><p style="color:#666">请关闭此页面返回商城</p></body></html>`);
  } catch (e) {
    return res.send('支付确认失败');
  }
});

// ===================== 管理端 API =====================

// 活动列表（分页）
adminBargain.get('/list', authAdmin, (req, res) => {
  const { page: p = 1, pageSize = 15, keyword } = req.query;
  const pageNum = Math.max(1, +p);
  const size = Math.min(50, Math.max(1, +pageSize));
  let where = 'WHERE 1=1';
  const params = [];
  if (keyword) { where += ' AND (ba.name LIKE ? OR p.name LIKE ?)'; params.push(`%${keyword}%`, `%${keyword}%`); }
  const total = get(`SELECT COUNT(*) as c FROM bargain_activities ba ${where}`, params).c;
  const list = all(`SELECT ba.*, p.name as product_name, p.image as product_image
    FROM bargain_activities ba LEFT JOIN products p ON ba.product_id=p.id ${where} ORDER BY ba.id DESC LIMIT ? OFFSET ?`,
    [...params, size, (pageNum - 1) * size]);
  return res.json(page(list, total, pageNum, size));
});

// 创建/编辑活动
adminBargain.post('', authAdmin, (req, res) => {
  const { id, product_id, name, image, original_price, floor_price, stock, limit_count, help_limit, expire_hours, start_time, end_time } = req.body;
  if (!product_id || !name) return res.json(fail('商品和活动名必填'));
  const p = get('SELECT * FROM products WHERE id=?', [product_id]);
  if (!p) return res.json(fail('商品不存在'));
  const orig = toNum(original_price !== undefined ? original_price : p.price);
  const floor = toNum(floor_price);
  if (!(floor > 0) || floor >= orig) return res.json(fail('底价需大于0且低于原价'));
  const data = {
    product_id, name, image: image || p.image || '',
    original_price: orig, floor_price: floor,
    stock: Math.max(0, Math.floor(Number(stock)) || 0),
    limit_count: Math.max(0, Math.floor(Number(limit_count)) || 0),
    help_limit: Math.max(0, Math.floor(Number(help_limit)) || 0),
    expire_hours: Math.max(1, Math.floor(Number(expire_hours)) || 24),
    start_time: start_time || new Date().toISOString().replace('T', ' ').slice(0, 19),
    end_time: end_time || new Date(Date.now() + 30 * 86400000).toISOString().replace('T', ' ').slice(0, 19)
  };
  if (id) {
    run(`UPDATE bargain_activities SET product_id=?,name=?,image=?,original_price=?,floor_price=?,stock=?,limit_count=?,help_limit=?,expire_hours=?,start_time=?,end_time=?
      WHERE id=?`,
      [data.product_id, data.name, data.image, data.original_price, data.floor_price, data.stock, data.limit_count, data.help_limit, data.expire_hours, data.start_time, data.end_time, id]);
    return res.json(success({ id }, '已更新'));
  }
  run(`INSERT INTO bargain_activities(product_id,name,image,original_price,floor_price,stock,limit_count,help_limit,expire_hours,start_time,end_time,status)
    VALUES(?,?,?,?,?,?,?,?,?,?,?,1)`,
    [data.product_id, data.name, data.image, data.original_price, data.floor_price, data.stock, data.limit_count, data.help_limit, data.expire_hours, data.start_time, data.end_time]);
  return res.json(success({ id: get('SELECT id FROM bargain_activities ORDER BY id DESC LIMIT 1').id }, '已创建'));
});

// 启用/停用
adminBargain.post('/:id/toggle', authAdmin, (req, res) => {
  const ba = get('SELECT * FROM bargain_activities WHERE id=?', [req.params.id]);
  if (!ba) return res.json(fail('活动不存在'));
  const ns = ba.status === 1 ? 0 : 1;
  run('UPDATE bargain_activities SET status=? WHERE id=?', [ns, req.params.id]);
  return res.json(success({ status: ns }, ns ? '已启用' : '已停用'));
});

// 删除（软删）→ 联动失效进行中/可下单的砍价单，避免已删活动仍可下单
adminBargain.delete('/:id', authAdmin, (req, res) => {
  transaction(() => {
    run("UPDATE bargain_activities SET status=0 WHERE id=?", [req.params.id]);
    run(`UPDATE bargain_sessions SET status='expired' WHERE activity_id=? AND status IN ('bargaining','can_order')`, [req.params.id]);
  });
  return res.json(success(null, '已删除'));
});

// 砍价单列表（运营查看）
adminBargain.get('/sessions', authAdmin, (req, res) => {
  const { page: p = 1, pageSize = 15, status, activity_id } = req.query;
  const pageNum = Math.max(1, +p);
  const size = Math.min(50, Math.max(1, +pageSize));
  let where = 'WHERE 1=1';
  const params = [];
  if (status) { where += ' AND s.status=?'; params.push(status); }
  if (activity_id) { where += ' AND s.activity_id=?'; params.push(activity_id); }
  const total = get(`SELECT COUNT(*) as c FROM bargain_sessions s ${where}`, params).c;
  const list = all(`SELECT s.*, ba.name as activity_name, u.nickname FROM bargain_sessions s
    LEFT JOIN bargain_activities ba ON s.activity_id=ba.id
    LEFT JOIN users u ON s.user_id=u.id ${where} ORDER BY s.id DESC LIMIT ? OFFSET ?`,
    [...params, size, (pageNum - 1) * size]);
  return res.json(page(list, total, pageNum, size));
});

// 砍价订单（标准 orders 中 order_no 前缀 BK）
adminBargain.get('/orders', authAdmin, (req, res) => {
  const { page: p = 1, pageSize = 15, keyword, status } = req.query;
  const pageNum = Math.max(1, +p);
  const size = Math.min(50, Math.max(1, +pageSize));
  let where = "WHERE o.order_no LIKE 'BK%'";
  const params = [];
  if (keyword) { where += ' AND (o.order_no LIKE ? OR oi.product_name LIKE ?)'; params.push(`%${keyword}%`, `%${keyword}%`); }
  if (status) { where += ' AND o.status=?'; params.push(status); }
  const total = get(`SELECT COUNT(*) as c FROM orders o ${where}`, params).c;
  const list = all(`SELECT o.*, GROUP_CONCAT(oi.product_name) as product_names, u.nickname
    FROM orders o
    LEFT JOIN order_items oi ON oi.order_id=o.id
    LEFT JOIN users u ON o.user_id=u.id ${where} GROUP BY o.id ORDER BY o.id DESC LIMIT ? OFFSET ?`,
    [...params, size, (pageNum - 1) * size]);
  return res.json(page(list, total, pageNum, size));
});

module.exports = { bargainRouter, adminBargain };
