import { getDb, queryOne, queryAll, execute, saveDb } from '../db/database';
import type { User, UserPublic } from '@network-tool/shared-types';
import { hashPassword, verifyPassword, generateToken } from '@network-tool/shared-crypto';

const JWT_SECRET = process.env.JWT_SECRET || 'network-tool-dev-secret-change-in-production';
export { JWT_SECRET };

export class AuthService {
  async register(data: { email: string; password: string }) {
    const db = await getDb();
    if (queryOne(db, 'SELECT id FROM users WHERE email = ?', [data.email])) {
      throw new Error('EMAIL_EXISTS');
    }
    const hash = await hashPassword(data.password);
    const result = execute(db, 'INSERT INTO users (email, password_hash) VALUES (?, ?)', [data.email, hash]);
    const user = queryOne<User>(db, 'SELECT * FROM users WHERE id = ?', [result.lastInsertRowid])!;
    saveDb();
    const token = generateToken({ user_id: user.id, email: user.email, role: user.role }, JWT_SECRET);
    return { user: this.public(user), token };
  }

  async login(data: { email: string; password: string }) {
    const db = await getDb();
    const user = queryOne<User>(db, 'SELECT * FROM users WHERE email = ?', [data.email]);
    if (!user) throw new Error('INVALID_CREDENTIALS');
    if (!(await verifyPassword(data.password, user.password_hash))) throw new Error('INVALID_CREDENTIALS');
    const token = generateToken({ user_id: user.id, email: user.email, role: user.role }, JWT_SECRET);
    return { user: this.public(user), token };
  }

  async getMe(userId: number): Promise<UserPublic | null> {
    const db = await getDb();
    const user = queryOne<User>(db, 'SELECT * FROM users WHERE id = ?', [userId]);
    return user ? this.public(user) : null;
  }

  async listUsers(): Promise<UserPublic[]> {
    const db = await getDb();
    return queryAll<User>(db, 'SELECT * FROM users ORDER BY created_at DESC').map(u => this.public(u));
  }

  private public(u: User): UserPublic {
    return { id: u.id, email: u.email, role: u.role, created_at: u.created_at };
  }
}
