const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const multer = require('multer');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const sepay = require('./sepay');

const app = express();
const PORT = 3001;
const JWT_SECRET = 'shop-game-secret-key-2026';
const ADMIN_MASTER_KEY = 'admin-secret-2026'; // Key này dùng để kích hoạt quyền admin từ file .bat
const DATA_DIR = path.join(__dirname, 'data');

app.use(cors());
app.use(express.json());
const cookieParser = require('cookie-parser');
app.use(cookieParser());

// Bảo vệ thư mục admin: Chỉ cho phép truy cập index.html nếu có cookie hoặc token hợp lệ
app.get('/admin', (req, res) => {
  const token = req.cookies?.adminToken;
  const masterKey = req.cookies?.adminMasterKey;

  // Nếu có masterKey hợp lệ hoặc token admin hợp lệ
  if (masterKey === ADMIN_MASTER_KEY) {
    return res.sendFile(path.join(__dirname, 'admin', 'index.html'));
  }

  if (token) {
    try {
      const decoded = jwt.verify(token, JWT_SECRET);
      if (decoded.role === 'admin') {
        return res.sendFile(path.join(__dirname, 'admin', 'index.html'));
      }
    } catch (e) {}
  }

  // Nếu không có quyền, chuyển hướng sang trang login admin
  res.redirect('/admin/login.html');
});

// Endpoint để file .bat gọi tới, giúp set key admin vào trình duyệt
app.get('/api/admin/setup', (req, res) => {
  const { key } = req.query;
  if (key === ADMIN_MASTER_KEY) {
    res.cookie('adminMasterKey', ADMIN_MASTER_KEY, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: false });
    return res.send('<h1>Đã xác thực Admin thành công!</h1><p>Bây giờ bạn có thể truy cập trang quản trị.</p><script>setTimeout(()=>window.location.href="/admin", 2000)</script>');
  }
  res.status(403).send('<h1>Key không hợp lệ!</h1>');
});

app.use('/admin', (req, res, next) => {
  if (req.path === '/login.html' || req.path.startsWith('/css/') || req.path.startsWith('/js/')) {
    return next();
  }
  const token = req.cookies?.adminToken || req.headers.authorization?.split(' ')[1];
  const masterKey = req.cookies?.adminMasterKey;

  if (masterKey === ADMIN_MASTER_KEY) return next();

  if (token) {
    try {
      const decoded = jwt.verify(token, JWT_SECRET);
      if (decoded.role === 'admin') return next();
    } catch (e) {}
  }
  
  if (req.path === '/' || req.path === '/index.html') {
    return res.redirect('/admin/login.html');
  }
  next();
}, express.static(path.join(__dirname, 'admin')));

app.use(express.static(path.join(__dirname, 'public')));
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

const storage = multer.diskStorage({
  destination: (req, file, cb) => cb(null, path.join(__dirname, 'uploads')),
  filename: (req, file, cb) => {
    const ext = path.extname(file.originalname);
    cb(null, Date.now() + ext);
  }
});
const upload = multer({ storage });

function readJSON(file) {
  try {
    return JSON.parse(fs.readFileSync(path.join(DATA_DIR, file), 'utf8'));
  } catch { return []; }
}

function writeJSON(file, data) {
  fs.writeFileSync(path.join(DATA_DIR, file), JSON.stringify(data, null, 2));
}

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'Chua dang nhap' });
  try {
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch { res.status(401).json({ error: 'Token khong hop le' }); }
}

function adminMiddleware(req, res, next) {
  const token = req.cookies?.adminToken || req.headers.authorization?.split(' ')[1];
  const masterKey = req.cookies?.adminMasterKey || req.headers['x-admin-key'];

  // Ưu tiên Master Key
  if (masterKey === ADMIN_MASTER_KEY) {
    return next();
  }

  // Nếu không có Master Key, kiểm tra Token JWT (nếu vẫn dùng song song)
  if (token) {
    try {
      const decoded = jwt.verify(token, JWT_SECRET);
      if (decoded.role === 'admin') return next();
    } catch (e) {}
  }

  res.status(403).json({ error: 'Khong co quyen admin' });
}

app.post('/api/auth/register', async (req, res) => {
  const { username, email, password } = req.body;
  if (!username || !email || !password) return res.status(400).json({ error: 'Thieu thong tin' });
  const users = readJSON('users.json');
  if (users.find(u => u.username === username)) return res.status(400).json({ error: 'Username da ton tai' });
  if (users.find(u => u.email === email)) return res.status(400).json({ error: 'Email da ton tai' });
  const hash = await bcrypt.hash(password, 10);
  const user = {
    id: 'user-' + Date.now(),
    username, email,
    password: hash,
    role: 'user',
    balance: 0,
    deposit_balance: 0,
    pending_balance: 0,
    withdrawing_balance: 0,
    withdrawn_balance: 0,
    active: true,
    createdAt: new Date().toISOString()
  };
  users.push(user);
  writeJSON('users.json', users);
  const token = jwt.sign({ id: user.id, username: user.username, role: user.role }, JWT_SECRET, { expiresIn: '7d' });
  res.json({ token, user: { id: user.id, username: user.username, email: user.email, role: user.role, balance: user.balance, deposit_balance: user.deposit_balance } });
});

app.post('/api/auth/login', async (req, res) => {
  const { username, password } = req.body;
  const users = readJSON('users.json');
  const user = users.find(u => u.username === username);
  if (!user) return res.status(400).json({ error: 'Sai username hoac password' });
  if (!user.active) return res.status(400).json({ error: 'Tai khoan da bi khoa' });
  const valid = await bcrypt.compare(password, user.password);
  if (!valid) return res.status(400).json({ error: 'Sai username hoac password' });

  // Đảm bảo chỉ có 1 admin duy nhất (nếu là login admin)
  if (user.role === 'admin') {
    const admins = users.filter(u => u.role === 'admin');
    if (admins.length > 1) {
      // Nếu lỡ có nhiều admin, chỉ cho phép thằng đầu tiên
      if (user.id !== admins[0].id) {
        return res.status(403).json({ error: 'Chỉ cho phép một tài khoản admin duy nhất.' });
      }
    }
  }

  const token = jwt.sign({ id: user.id, username: user.username, role: user.role }, JWT_SECRET, { expiresIn: '7d' });
  
  // Set cookie cho admin để bảo vệ route static
  if (user.role === 'admin') {
    res.cookie('adminToken', token, { maxAge: 7 * 24 * 60 * 60 * 1000, httpOnly: false });
  }

  res.json({ token, user: { id: user.id, username: user.username, email: user.email, role: user.role, balance: user.balance, deposit_balance: user.deposit_balance } });
});

app.get('/api/user/profile', authMiddleware, (req, res) => {
  const users = readJSON('users.json');
  const user = users.find(u => u.id === req.user.id);
  if (!user) return res.status(404).json({ error: 'Khong tim thay user' });
  res.json({ 
    id: user.id, 
    username: user.username, 
    email: user.email, 
    role: user.role, 
    balance: user.balance || 0,
    deposit_balance: user.deposit_balance || 0,
    pending_balance: user.pending_balance || 0,
    withdrawing_balance: user.withdrawing_balance || 0,
    withdrawn_balance: user.withdrawn_balance || 0,
    createdAt: user.createdAt 
  });
});

const CATEGORIES = {
  'tai-khoan': { id: 'tai-khoan', name: 'Tài khoản', type: 'product' },
  'email': { id: 'email', name: 'Email', type: 'product' },
  'clone': { id: 'clone', name: 'Clone', type: 'product' },
  'tools': { id: 'tools', name: 'Tools', type: 'product' },
  'proxy': { id: 'proxy', name: 'Proxy & VPN', type: 'product' },
  'software': { id: 'software', name: 'Phần mềm', type: 'product' },
  'upgrade': { id: 'upgrade', name: 'Nâng cấp tài khoản', type: 'service' },
  'dev': { id: 'dev', name: 'Dịch vụ phần mềm', type: 'service' },
  'auto': { id: 'auto', name: 'Tool/Script Auto', type: 'service' },
  'vps': { id: 'vps', name: 'VPS', type: 'service' },
  'social': { id: 'social', name: 'Tăng tương tác', type: 'service' },
  'seo': { id: 'seo', name: 'Seo', type: 'service' },
  'marketing': { id: 'marketing', name: 'Marketing', type: 'service' },
  'blockchain': { id: 'blockchain', name: 'Blockchain', type: 'service' },
  'khac': { id: 'khac', name: 'Khác', type: 'product' }
};

app.get('/api/games/categories', (req, res) => {
  res.json(Object.values(CATEGORIES));
});

app.get('/api/games', (req, res) => {
  const games = readJSON('games.json');
  const accounts = readJSON('accounts.json');
  const result = games.filter(g => g.active).map(g => {
    const gameAccs = accounts.filter(a => a.gameId === g.id && a.active);
    // Luôn tính toán stock dựa trên số lượng credentials thực tế
    const totalStock = gameAccs.reduce((s, a) => {
      const actualStock = Array.isArray(a.credentials) ? a.credentials.length : (a.stock || 0);
      return s + actualStock;
    }, 0);
    const totalSold = gameAccs.reduce((s, a) => s + (a.sold || 0), 0);
    return { ...g, totalStock, totalSold, accountCount: gameAccs.length };
  });
  res.json(result);
});

app.get('/api/games/:gameId/accounts', (req, res) => {
  const { gameId } = req.params;
  const accounts = readJSON('accounts.json');
  const result = accounts.filter(a => a.gameId === gameId && a.active);
  const safeResult = result.map(({ password, credentials, ...rest }) => {
    // Luôn cập nhật stock thực tế trước khi trả về cho client
    const actualStock = Array.isArray(credentials) ? credentials.length : (rest.stock || 0);
    return { ...rest, stock: actualStock };
  });
  res.json(safeResult);
});

app.get('/api/games/category/:catId', (req, res) => {
  const games = readJSON('games.json');
  const accounts = readJSON('accounts.json');
  const result = games.filter(g => g.active && g.category === req.params.catId).map(g => {
    const gameAccs = accounts.filter(a => a.gameId === g.id && a.active);
    const totalStock = gameAccs.reduce((s, a) => s + a.stock, 0);
    const totalSold = gameAccs.reduce((s, a) => s + a.sold, 0);
    return { ...g, totalStock, totalSold, accountCount: gameAccs.length };
  });
  res.json(result);
});

app.get('/api/accounts/:id', (req, res) => {
  const accounts = readJSON('accounts.json');
  const acc = accounts.find(a => a.id === req.params.id);
  if (!acc) return res.status(404).json({ error: 'Khong tim thay tai khoan' });
  const { password, ...safe } = acc;
  res.json(safe);
});

app.post('/api/order/create', authMiddleware, (req, res) => {
  const { accountId } = req.body;
  const users = readJSON('users.json');
  const accounts = readJSON('accounts.json');
  const orders = readJSON('orders.json');
  const user = users.find(u => u.id === req.user.id);
  
  if (!user) return res.status(404).json({ error: 'Khong tim thay user' });
  const acc = accounts.find(a => a.id === accountId);
  if (!acc) return res.status(404).json({ error: 'Khong tim thay tai khoan game' });
  if (acc.stock <= 0 || !acc.credentials || acc.credentials.length === 0) {
    return res.status(400).json({ error: 'Tai khoan da het hang' });
  }
  const currentBalance = (user.deposit_balance || 0) + (user.balance || 0);
  if (currentBalance < acc.price) return res.status(400).json({ error: 'So du khong du' });

  // Get the first account from the list
  const credential = acc.credentials.shift();
  
  // Trừ tiền từ deposit_balance trước, nếu không đủ thì trừ tiếp vào balance
  if ((user.deposit_balance || 0) >= acc.price) {
    user.deposit_balance -= acc.price;
  } else {
    const remaining = acc.price - (user.deposit_balance || 0);
    user.deposit_balance = 0;
    user.balance -= remaining;
  }

  acc.stock = acc.credentials.length;
  acc.sold += 1;

  const order = {
    id: 'order-' + Date.now(),
    userId: user.id,
    username: user.username,
    accountId: acc.id,
    accountTitle: acc.title,
    // Format credential (assume user pasted "user|pass" or just "pass")
    gameUsername: credential.split('|')[0] || 'N/A',
    gamePassword: credential.split('|')[1] || credential,
    price: acc.price,
    gameId: acc.gameId,
    status: 'completed',
    createdAt: new Date().toISOString()
  };

  orders.push(order);
  writeJSON('users.json', users);
  writeJSON('accounts.json', accounts);
  writeJSON('orders.json', orders);
  res.json({ success: true, order: { id: order.id, accountTitle: order.accountTitle, gameUsername: order.gameUsername, gamePassword: order.gamePassword, price: order.price } });
});

app.get('/api/user/orders', authMiddleware, (req, res) => {
  const orders = readJSON('orders.json');
  const userOrders = orders.filter(o => o.userId === req.user.id);
  res.json(userOrders);
});

app.get('/api/charge/qr', (req, res) => {
  const payments = readJSON('payments.json');
  const { amount, content } = req.query;
  
  // Nếu có amount và content, và đã cấu hình SePay, trả về QR động
  if (amount && content && payments.sepayApiToken && payments.accountNumber && payments.sepayBankName) {
    const qrUrl = sepay.generateQrUrl({
      accountNumber: payments.accountNumber,
      bankShortName: payments.sepayBankName,
      amount: parseFloat(amount),
      content: content
    });
    return res.json({ ...payments, dynamicQr: qrUrl });
  }
  
  res.json(payments);
});

app.post('/api/charge/sepay-check', authMiddleware, async (req, res) => {
  const { chargeId } = req.body;
  if (!chargeId) return res.status(400).json({ error: 'Thieu chargeId' });

  const charges = readJSON('charge-requests.json');
  const charge = charges.find(c => c.id === chargeId && c.userId === req.user.id);
  
  if (!charge) return res.status(404).json({ error: 'Khong tim thay yeu cau nap tien' });
  if (charge.status !== 'pending') return res.json({ success: true, charge });

  const payments = readJSON('payments.json');
  if (!payments.sepayApiToken) return res.status(400).json({ error: 'Chưa cấu hình SePay' });

  // Lấy danh sách các giao dịch SePay đã dùng
  const usedTxnIds = charges.filter(c => c.sepay_transaction_id).map(c => c.sepay_transaction_id);

  try {
    const txn = await sepay.findTransactionByContent(payments.sepayApiToken, {
      contentKeyword: charge.transactionCode,
      amount: charge.amount,
      accountNumber: payments.accountNumber,
      usedTxnIds
    });

    if (txn) {
      // Khớp giao dịch! Cập nhật trạng thái và cộng tiền
      charge.status = 'confirmed';
      charge.confirmedAt = new Date().toISOString();
      charge.sepay_transaction_id = String(txn.id);

      const users = readJSON('users.json');
      const user = users.find(u => u.id === charge.userId);
      if (user) {
        user.deposit_balance = (user.deposit_balance || 0) + charge.amount;
        writeJSON('users.json', users);
      }
      writeJSON('charge-requests.json', charges);
      
      return res.json({ success: true, charge, matched: true });
    }

    res.json({ success: true, charge, matched: false, message: 'Chưa tìm thấy giao dịch. Vui lòng đợi vài phút hoặc liên hệ admin.' });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: 'Lỗi khi kiểm tra giao dịch' });
  }
});

app.post('/api/charge/request', authMiddleware, (req, res) => {
  const { amount, method, transactionCode } = req.body;
  if (!amount || !method || !transactionCode) return res.status(400).json({ error: 'Thieu thong tin' });
  if (amount < 10000) return res.status(400).json({ error: 'So tien toi thieu 10,000d' });
  const charges = readJSON('charge-requests.json');
  const charge = {
    id: 'charge-' + Date.now(),
    userId: req.user.id,
    username: req.user.username,
    amount,
    method,
    transactionCode,
    status: 'pending',
    createdAt: new Date().toISOString()
  };
  charges.push(charge);
  writeJSON('charge-requests.json', charges);
  res.json({ success: true, charge });
});

app.get('/api/user/charges', authMiddleware, (req, res) => {
  const charges = readJSON('charge-requests.json');
  res.json(charges.filter(c => c.userId === req.user.id));
});

app.get('/api/admin/dashboard', adminMiddleware, (req, res) => {
  const users = readJSON('users.json');
  const accounts = readJSON('accounts.json');
  const orders = readJSON('orders.json');
  const charges = readJSON('charge-requests.json');
  const totalRevenue = orders.reduce((s, o) => s + o.price, 0);
  const pendingCharges = charges.filter(c => c.status === 'pending');
  const totalUsers = users.filter(u => u.role !== 'admin').length;
  const totalAccounts = accounts.filter(a => a.active).length;
  const totalSold = accounts.reduce((s, a) => s + a.sold, 0);
  res.json({ totalRevenue, totalOrders: orders.length, totalUsers, totalAccounts, totalSold, pendingCharges: pendingCharges.length, recentOrders: orders.slice(-10).reverse(), recentCharges: charges.slice(-10).reverse() });
});

app.get('/api/admin/accounts', adminMiddleware, (req, res) => {
  const accounts = readJSON('accounts.json');
  res.json(accounts);
});

app.post('/api/admin/accounts', adminMiddleware, (req, res) => {
  const accounts = readJSON('accounts.json');
  const { gameId, type, title, description, price, image, coverImage, info, accountList } = req.body;
  
  if (!gameId || !title || !price || !accountList) {
    return res.status(400).json({ error: 'Thiếu thông tin bắt buộc hoặc danh sách tài khoản' });
  }

  // Split account list by new lines and filter empty lines
  const rawLines = accountList.split(/\r?\n/).filter(line => line.trim().length > 0);
  
  if (rawLines.length === 0) {
    return res.status(400).json({ error: 'Danh sách tài khoản trống' });
  }

  const newAccount = {
    id: 'acc-' + Date.now(),
    gameId, 
    type: type || 'tự chọn', 
    title, 
    description: description || '',
    price: Number(price), 
    image: image || '/img/default-game.jpg',
    coverImage: coverImage || '',
    info: info || '',
    sold: 0, 
    stock: rawLines.length,
    credentials: rawLines, // Store the list of accounts
    active: true, 
    createdAt: new Date().toISOString()
  };

  accounts.push(newAccount);
  writeJSON('accounts.json', accounts);
  res.json({ success: true, account: newAccount });
});

app.put('/api/admin/accounts/:id', adminMiddleware, (req, res) => {
  const accounts = readJSON('accounts.json');
  const idx = accounts.findIndex(a => a.id === req.params.id);
  if (idx === -1) return res.status(404).json({ error: 'Khong tim thay' });
  const updates = req.body;
  Object.keys(updates).forEach(k => { if (k !== 'id') accounts[idx][k] = updates[k]; });
  writeJSON('accounts.json', accounts);
  res.json({ success: true, account: accounts[idx] });
});

app.delete('/api/admin/accounts/:id', adminMiddleware, (req, res) => {
  let accounts = readJSON('accounts.json');
  accounts = accounts.filter(a => a.id !== req.params.id);
  writeJSON('accounts.json', accounts);
  res.json({ success: true });
});

app.get('/api/admin/games', adminMiddleware, (req, res) => {
  res.json(readJSON('games.json'));
});

app.post('/api/admin/games', adminMiddleware, (req, res) => {
  const games = readJSON('games.json');
  const { name, slug, image, icon, order, category, coverGradient, coverImage } = req.body;
  if (!name) return res.status(400).json({ error: 'Thieu ten game' });
  const game = {
    id: slug || name.toLowerCase().replace(/\s+/g, '-'),
    name, slug: slug || name.toLowerCase().replace(/\s+/g, '-'),
    image: image || '/img/default-game.jpg',
    coverImage: coverImage || '',
    coverGradient: coverGradient || 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
    icon: icon || '🎮',
    category: category || 'khac',
    order: Number(order) || games.length + 1,
    active: true
  };
  games.push(game);
  writeJSON('games.json', games);
  res.json({ success: true, game });
});

app.put('/api/admin/games/:id', adminMiddleware, (req, res) => {
  const games = readJSON('games.json');
  const idx = games.findIndex(g => g.id === req.params.id);
  if (idx === -1) return res.status(404).json({ error: 'Khong tim thay' });
  Object.keys(req.body).forEach(k => { if (k !== 'id') games[idx][k] = req.body[k]; });
  writeJSON('games.json', games);
  res.json({ success: true, game: games[idx] });
});

app.delete('/api/admin/games/:id', adminMiddleware, (req, res) => {
  let games = readJSON('games.json');
  games = games.filter(g => g.id !== req.params.id);
  writeJSON('games.json', games);
  res.json({ success: true });
});

app.get('/api/admin/charges', adminMiddleware, (req, res) => {
  res.json(readJSON('charge-requests.json'));
});

app.post('/api/admin/charges/:id/confirm', adminMiddleware, (req, res) => {
  const charges = readJSON('charge-requests.json');
  const users = readJSON('users.json');
  const charge = charges.find(c => c.id === req.params.id);
  if (!charge) return res.status(404).json({ error: 'Khong tim thay' });
  charge.status = 'confirmed';
  charge.confirmedAt = new Date().toISOString();
  const user = users.find(u => u.id === charge.userId);
  if (user) user.deposit_balance = (user.deposit_balance || 0) + charge.amount;
  writeJSON('charge-requests.json', charges);
  writeJSON('users.json', users);
  res.json({ success: true, charge });
});

app.post('/api/admin/charges/:id/reject', adminMiddleware, (req, res) => {
  const charges = readJSON('charge-requests.json');
  const charge = charges.find(c => c.id === req.params.id);
  if (!charge) return res.status(404).json({ error: 'Khong tim thay' });
  charge.status = 'rejected';
  charge.rejectedAt = new Date().toISOString();
  writeJSON('charge-requests.json', charges);
  res.json({ success: true, charge });
});

app.get('/api/admin/orders', adminMiddleware, (req, res) => {
  res.json(readJSON('orders.json'));
});

app.get('/api/admin/users', adminMiddleware, (req, res) => {
  const users = readJSON('users.json');
  res.json(users.map(({ password, ...rest }) => rest));
});

app.post('/api/admin/users/:id/toggle', adminMiddleware, (req, res) => {
  const users = readJSON('users.json');
  const user = users.find(u => u.id === req.params.id);
  if (!user) return res.status(404).json({ error: 'Khong tim thay' });
  user.active = !user.active;
  writeJSON('users.json', users);
  res.json({ success: true, active: user.active });
});

app.put('/api/admin/payments', adminMiddleware, (req, res) => {
  writeJSON('payments.json', req.body);
  res.json({ success: true });
});

app.post('/api/admin/upload', adminMiddleware, upload.single('image'), (req, res) => {
  if (!req.file) return res.status(400).json({ error: 'Khong co file' });
  res.json({ success: true, path: '/uploads/' + req.file.filename });
});

app.get('/admin', (req, res) => {
  res.sendFile(path.join(__dirname, 'admin', 'index.html'));
});

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(PORT, () => {
  console.log(`Shop Game running at http://localhost:${PORT}`);
  console.log(`Admin Dashboard at http://localhost:${PORT}/admin`);
});
