import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';
import { Request, Response, NextFunction } from 'express';
import config from '../config';
import { getDb } from '../database/database';

export interface AuthPayload {
  id: number;
  username: string;
}

export function login(username: string, password: string): string | null {
  const db = getDb();
  const row = db.prepare('SELECT id, username, password_hash FROM admins WHERE username = ?').get(username) as any;

  if (!row) return null;

  const valid = bcrypt.compareSync(password, row.password_hash);
  if (!valid) return null;

  // Update last login
  db.prepare('UPDATE admins SET last_login = datetime(\'now\') WHERE id = ?').run(row.id);

  // Generate JWT
  const payload: AuthPayload = { id: row.id, username: row.username };
  const token = jwt.sign(payload, config.jwtSecret, { expiresIn: '24h' });

  return token;
}

export function verifyToken(token: string): AuthPayload | null {
  try {
    const decoded = jwt.verify(token, config.jwtSecret) as AuthPayload;
    return decoded;
  } catch {
    return null;
  }
}

export function authMiddleware(req: Request, res: Response, next: NextFunction): void {
  const authHeader = req.headers.authorization;

  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    res.status(401).json({ error: 'Missing or invalid authorization header', code: 401 });
    return;
  }

  const token = authHeader.split(' ')[1];
  const payload = verifyToken(token);

  if (!payload) {
    res.status(401).json({ error: 'Invalid or expired token', code: 401 });
    return;
  }

  (req as any).user = payload;
  next();
}

export function changePassword(username: string, oldPassword: string, newPassword: string): { success: boolean; message: string } {
  const db = getDb();
  const row = db.prepare('SELECT id, password_hash FROM admins WHERE username = ?').get(username) as any;
  if (!row) {
    return { success: false, message: '用户不存在' };
  }

  const valid = bcrypt.compareSync(oldPassword, row.password_hash);
  if (!valid) {
    return { success: false, message: '原密码错误' };
  }

  const salt = bcrypt.genSaltSync(10);
  const hash = bcrypt.hashSync(newPassword, salt);
  db.prepare("UPDATE admins SET password_hash = ? WHERE id = ?").run(hash, row.id);
  return { success: true, message: '密码修改成功' };
}
