import Database from 'better-sqlite3';
import bcrypt from 'bcryptjs';
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { config } from './config.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const dataDir = path.join(__dirname, '..', 'data');
fs.mkdirSync(dataDir, { recursive: true });

export const db = new Database(path.join(dataDir, 'app.db'));
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');

db.exec(`
  -- Пользователи системы. role: 'admin' | 'user'
  CREATE TABLE IF NOT EXISTS users (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    email         TEXT NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    role          TEXT NOT NULL DEFAULT 'user',
    created_at    TEXT NOT NULL DEFAULT (datetime('now'))
  );

  -- Профиль пользователя (КТО отвечает): подставляется в промпт.
  CREATE TABLE IF NOT EXISTS profiles (
    user_id   INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
    full_name TEXT NOT NULL DEFAULT '',
    company   TEXT NOT NULL DEFAULT '',
    position  TEXT NOT NULL DEFAULT '',
    signature TEXT NOT NULL DEFAULT ''
  );

  -- Почтовые настройки пользователя. Пароли хранятся в зашифрованном виде.
  CREATE TABLE IF NOT EXISTS mail_accounts (
    user_id       INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
    imap_host     TEXT NOT NULL DEFAULT '',
    imap_port     INTEGER NOT NULL DEFAULT 993,
    imap_secure   INTEGER NOT NULL DEFAULT 1,
    imap_user     TEXT NOT NULL DEFAULT '',
    imap_pass_enc TEXT NOT NULL DEFAULT '',
    smtp_host     TEXT NOT NULL DEFAULT '',
    smtp_port     INTEGER NOT NULL DEFAULT 465,
    smtp_secure   INTEGER NOT NULL DEFAULT 1,
    smtp_user     TEXT NOT NULL DEFAULT '',
    smtp_pass_enc TEXT NOT NULL DEFAULT ''
  );

  -- Обучающие переписки (ГЛОБАЛЬНО, общие для всех). Меняет только admin.
  CREATE TABLE IF NOT EXISTS training_files (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    filename   TEXT NOT NULL,
    content    TEXT NOT NULL,
    created_at TEXT NOT NULL DEFAULT (datetime('now'))
  );

  -- Глобальные настройки приложения (ключ-значение): API ключ, модель, базовый стиль.
  CREATE TABLE IF NOT EXISTS app_settings (
    key   TEXT PRIMARY KEY,
    value TEXT NOT NULL DEFAULT ''
  );

  -- Журнал писем по каждому пользователю.
  -- status: 'pending' (ждёт одобрения) | 'sent' | 'rejected' | 'error'
  CREATE TABLE IF NOT EXISTS emails (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id      INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    message_id   TEXT,
    from_addr    TEXT NOT NULL DEFAULT '',
    from_name    TEXT NOT NULL DEFAULT '',
    subject      TEXT NOT NULL DEFAULT '',
    body         TEXT NOT NULL DEFAULT '',
    draft_reply  TEXT NOT NULL DEFAULT '',
    status       TEXT NOT NULL DEFAULT 'pending',
    error        TEXT NOT NULL DEFAULT '',
    received_at  TEXT NOT NULL DEFAULT (datetime('now')),
    sent_at      TEXT,
    UNIQUE(user_id, message_id)
  );

  CREATE INDEX IF NOT EXISTS idx_emails_user_status ON emails(user_id, status);
`);

// --- Миграции: добавляем недостающие колонки в существующую БД ---
function ensureColumn(table, column, definition) {
  const cols = db.prepare(`PRAGMA table_info(${table})`).all();
  if (!cols.some((c) => c.name === column)) {
    db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
  }
}
// Куда слать ответ (для анкет — отличается от отправителя) и тип письма.
ensureColumn('emails', 'reply_to', "TEXT NOT NULL DEFAULT ''");
ensureColumn('emails', 'kind', "TEXT NOT NULL DEFAULT 'normal'");
// Включён ли опрос почты у пользователя и адрес отправителя (From).
ensureColumn('mail_accounts', 'poll_enabled', 'INTEGER NOT NULL DEFAULT 0');
ensureColumn('mail_accounts', 'from_email', "TEXT NOT NULL DEFAULT ''");

// --- Хелперы для глобальных настроек ---
export function getSetting(key, fallback = '') {
  const row = db.prepare('SELECT value FROM app_settings WHERE key = ?').get(key);
  return row ? row.value : fallback;
}

export function setSetting(key, value) {
  db.prepare(`
    INSERT INTO app_settings (key, value) VALUES (?, ?)
    ON CONFLICT(key) DO UPDATE SET value = excluded.value
  `).run(key, String(value ?? ''));
}

// --- Первоначальное заполнение ---
export function seed() {
  // Создаём первого админа, если пользователей ещё нет.
  const userCount = db.prepare('SELECT COUNT(*) AS n FROM users').get().n;
  if (userCount === 0) {
    const hash = bcrypt.hashSync(config.admin.password, 10);
    const info = db.prepare(
      'INSERT INTO users (email, password_hash, role) VALUES (?, ?, ?)'
    ).run(config.admin.email, hash, 'admin');
    db.prepare('INSERT INTO profiles (user_id) VALUES (?)').run(info.lastInsertRowid);
    db.prepare('INSERT INTO mail_accounts (user_id) VALUES (?)').run(info.lastInsertRowid);
    console.log(`[seed] Создан администратор: ${config.admin.email}`);
  }

  // Значения по умолчанию для глобальных настроек.
  if (getSetting('claude_model') === '') setSetting('claude_model', config.claudeModel);
  if (getSetting('anthropic_api_key') === '' && config.anthropicApiKey) {
    setSetting('anthropic_api_key', config.anthropicApiKey);
  }
  if (getSetting('base_style_prompt') === '') {
    setSetting('base_style_prompt',
      'Ты — вежливый деловой ассистент. Отвечай на письма в том же стиле, ' +
      'тоне и структуре, что и в обучающих примерах. Пиши по-деловому, по существу.');
  }

  // --- Настройки обработки анкет (application form) ---
  if (getSetting('apply_domain') === '') {
    setSetting('apply_domain', 'novabeyondapply.com');
  }
  if (getSetting('rate_table') === '') {
    setSetting('rate_table', JSON.stringify({
      PH: { full: '2100 PHP/hour', part: '1800 PHP/hour' },
      CA: { full: 'CAD 32 per hour', part: 'CAD 30 per hour' },
      AE: { full: 'AED 160 per hour', part: 'AED 120 per hour' },
      default: { full: '$34 per hour', part: '$29 per hour' },
    }, null, 2));
  }
  if (getSetting('template_fulltime') === '') {
    setSetting('template_fulltime',
      'Hi {first_name},\n\n' +
      'Thank you for your application. We are glad to move forward with you for a Full-Time position.\n\n' +
      'Compensation: {rate}\n\n' +
      'Please reply to confirm, and we will send you the next steps.\n\n' +
      'Best regards,\nHR Team');
  }
  if (getSetting('poll_interval_seconds') === '') {
    setSetting('poll_interval_seconds', '60');
  }
  if (getSetting('template_parttime') === '') {
    setSetting('template_parttime',
      'Hi {first_name},\n\n' +
      'Thank you for your application. We are glad to move forward with you for a Part-Time position.\n\n' +
      'Compensation: {rate}\n\n' +
      'Please reply to confirm, and we will send you the next steps.\n\n' +
      'Best regards,\nHR Team');
  }
}
