const Database = require('better-sqlite3');
const path     = require('path');
const fs       = require('fs');

const dbPath = process.env.DB_PATH || path.join(__dirname, '..', 'data', 'cpas.db');
const dir    = path.dirname(dbPath);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

const db = new Database(dbPath);
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');

const schema = fs.readFileSync(path.join(__dirname, 'schema.sql'), 'utf8');
db.exec(schema);

// ── Migrations for existing DBs ──────────────────────────────────────────────
const cols = db.prepare('PRAGMA table_info(violations)').all().map(c => c.name);
if (!cols.includes('negated'))             db.exec("ALTER TABLE violations ADD COLUMN negated INTEGER NOT NULL DEFAULT 0");
if (!cols.includes('negated_at'))          db.exec("ALTER TABLE violations ADD COLUMN negated_at DATETIME");
if (!cols.includes('prior_active_points')) db.exec("ALTER TABLE violations ADD COLUMN prior_active_points INTEGER");
if (!cols.includes('prior_tier_label'))    db.exec("ALTER TABLE violations ADD COLUMN prior_tier_label TEXT");
if (!cols.includes('acknowledged_by'))     db.exec("ALTER TABLE violations ADD COLUMN acknowledged_by TEXT");
if (!cols.includes('acknowledged_date'))   db.exec("ALTER TABLE violations ADD COLUMN acknowledged_date TEXT");
// Financial amount in question (record-keeping / repayment for chargeback, receipt negligence, etc.)
if (!cols.includes('amount'))              db.exec("ALTER TABLE violations ADD COLUMN amount TEXT");

// Employee notes column (free-text, does not affect scoring)
const empCols = db.prepare('PRAGMA table_info(employees)').all().map(c => c.name);
if (!empCols.includes('notes')) db.exec("ALTER TABLE employees ADD COLUMN notes TEXT");

// Ensure resolutions table exists
db.exec(`CREATE TABLE IF NOT EXISTS violation_resolutions (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    violation_id    INTEGER NOT NULL REFERENCES violations(id) ON DELETE CASCADE,
    resolution_type TEXT    NOT NULL,
    details         TEXT,
    resolved_by     TEXT,
    created_at      DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

// ── Feature: Violation Amendments ────────────────────────────────────────────
// Stores a field-level diff every time a violation's editable fields are changed.
db.exec(`CREATE TABLE IF NOT EXISTS violation_amendments (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    violation_id INTEGER NOT NULL REFERENCES violations(id) ON DELETE CASCADE,
    changed_by   TEXT,
    field_name   TEXT    NOT NULL,
    old_value    TEXT,
    new_value    TEXT,
    created_at   DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

// ── Feature: Audit Log ───────────────────────────────────────────────────────
// Append-only record of every write action across the system.
db.exec(`CREATE TABLE IF NOT EXISTS audit_log (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    action       TEXT    NOT NULL,
    entity_type  TEXT    NOT NULL,
    entity_id    INTEGER,
    performed_by TEXT,
    details      TEXT,
    created_at   DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

// ── Feature: Custom Violation Types ──────────────────────────────────────────
// Persisted violation type definitions created via the UI. type_key is prefixed
// with 'custom_' to prevent collisions with hardcoded violation keys.
db.exec(`CREATE TABLE IF NOT EXISTS violation_types (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    type_key    TEXT    NOT NULL UNIQUE,
    name        TEXT    NOT NULL,
    category    TEXT    NOT NULL DEFAULT 'Custom',
    chapter     TEXT,
    description TEXT,
    min_points  INTEGER NOT NULL DEFAULT 1,
    max_points  INTEGER NOT NULL DEFAULT 1,
    fields      TEXT    NOT NULL DEFAULT '["description"]',
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

// ── Feature: Authentication ──────────────────────────────────────────────────
// User accounts and login sessions. Passwords are stored as scrypt hashes
// (see auth.js). The bootstrap admin account is created/synced from the
// ADMIN_USERNAME / ADMIN_PASSWORD environment variables on startup.
db.exec(`CREATE TABLE IF NOT EXISTS users (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    username      TEXT    NOT NULL UNIQUE COLLATE NOCASE,
    password_hash TEXT    NOT NULL,
    role          TEXT    NOT NULL DEFAULT 'user',
    created_at    DATETIME DEFAULT CURRENT_TIMESTAMP
)`);

db.exec(`CREATE TABLE IF NOT EXISTS sessions (
    token      TEXT    PRIMARY KEY,
    user_id    INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    expires_at DATETIME NOT NULL
)`);

// The old `active_cpas_scores` view implemented a naive per-violation 90-day
// window. CPAS standing now follows the clean-cycle roll-off model (see
// lib/rolloff.js), which is order-dependent and computed in JS, so the view is
// retired here to keep a single source of truth.
db.exec('DROP VIEW IF EXISTS active_cpas_scores;');

console.log('[DB] Connected:', dbPath);
module.exports = db;
