'use strict';

const fs = require('node:fs/promises');
const path = require('node:path');
const readline = require('node:readline/promises');
const mysql = require('mysql2/promise');
const config = require('../src/config');
const { hashPassword } = require('../src/security');
const { isValidUsername, isStrongEnoughPassword, normalizeUsername } = require('../src/utils');

function arg(name) {
  const prefix = `--${name}=`;
  const value = process.argv.find((item) => item.startsWith(prefix));
  return value ? value.slice(prefix.length) : null;
}

async function main() {
  const schema = await fs.readFile(path.join(config.rootDir, 'database/schema.sql'), 'utf8');
  const products = JSON.parse(await fs.readFile(path.join(config.rootDir, 'database/seed-products.json'), 'utf8'));

  let connection;
  try {
    const rootConnection = await mysql.createConnection({
      host: config.db.host,
      port: config.db.port,
      user: config.db.user,
      password: config.db.password,
      charset: 'utf8mb4',
    });
    await rootConnection.query(`CREATE DATABASE IF NOT EXISTS \`${config.db.name.replaceAll('`', '')}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`);
    await rootConnection.end();
  } catch (error) {
    console.log('تعذر إنشاء قاعدة جديدة تلقائيًا، سيتم استخدام القاعدة الموجودة في ملف .env.');
  }

  connection = await mysql.createConnection({
    host: config.db.host,
    port: config.db.port,
    user: config.db.user,
    password: config.db.password,
    database: config.db.name,
    charset: 'utf8mb4',
    multipleStatements: true,
    decimalNumbers: true,
  });

  await connection.query(schema);
  const [[productCount]] = await connection.query('SELECT COUNT(*) AS count FROM products');
  if (productCount.count === 0) {
    const values = products.map((product) => [
      product.sortOrder,
      product.name,
      product.defaultUnit || null,
      product.defaultCost ?? null,
      product.defaultSalePrice ?? null,
      product.defaultNote || null,
    ]);
    await connection.query(
      `INSERT INTO products (sort_order, name, default_unit, default_cost, default_sale_price, default_note)
       VALUES ?`,
      [values],
    );
    console.log(`تمت إضافة ${values.length} صنفًا من ملف الإكسل.`);
  }

  const [[adminCount]] = await connection.query('SELECT COUNT(*) AS count FROM admins');
  if (adminCount.count === 0) {
    let username = arg('admin-user') || process.env.SETUP_ADMIN_USERNAME || '';
    let password = arg('admin-pass') || process.env.SETUP_ADMIN_PASSWORD || '';
    if ((!username || !password) && process.stdin.isTTY) {
      const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
      username = username || await rl.question('اسم مستخدم الأدمن: ');
      password = password || await rl.question('كلمة مرور الأدمن (8 أحرف على الأقل): ');
      rl.close();
    }
    username = normalizeUsername(username);
    if (!isValidUsername(username) || !isStrongEnoughPassword(password)) {
      throw new Error('لم يتم إنشاء الأدمن. شغّل الأمر مع --admin-user و --admin-pass وكلمة مرور 8 أحرف على الأقل.');
    }
    await connection.execute('INSERT INTO admins (username, password_hash) VALUES (?, ?)', [username, await hashPassword(password)]);
    console.log(`تم إنشاء حساب الأدمن: ${username}`);
  } else {
    console.log('حساب الأدمن موجود مسبقًا، لم يتم تغييره.');
  }

  await connection.end();
  console.log('تم تجهيز قاعدة البيانات بنجاح. شغّل النظام بالأمر: npm start');
}

main().catch((error) => {
  console.error('فشل التجهيز:', error.message);
  process.exitCode = 1;
});
