import Database from "better-sqlite3";
import fs from "node:fs";
import path from "node:path";
import { env } from "../env";

fs.mkdirSync(path.dirname(env.dbPath), { recursive: true });

export const db = new Database(env.dbPath);
db.pragma("journal_mode = WAL");
db.pragma("foreign_keys = ON");

db.exec(`
  CREATE TABLE IF NOT EXISTS employees (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    email TEXT NOT NULL UNIQUE,
    name TEXT,
    active INTEGER NOT NULL DEFAULT 1,
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
  );

  CREATE TABLE IF NOT EXISTS attendance_events (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    employee_id INTEGER NOT NULL REFERENCES employees(id),
    type TEXT NOT NULL CHECK (type IN ('clock_in', 'clock_out', 'break_start', 'break_end')),
    ts TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
  );

  CREATE INDEX IF NOT EXISTS idx_attendance_employee_ts
    ON attendance_events (employee_id, ts);

  CREATE TABLE IF NOT EXISTS shift_slots (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    date TEXT NOT NULL,
    start_time TEXT NOT NULL,
    end_time TEXT NOT NULL,
    capacity INTEGER NOT NULL,
    status TEXT NOT NULL CHECK (status IN ('open', 'full', 'closed')) DEFAULT 'open',
    note TEXT NOT NULL DEFAULT '',
    generated INTEGER NOT NULL DEFAULT 0,
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
  );

  CREATE UNIQUE INDEX IF NOT EXISTS idx_shift_slots_key
    ON shift_slots (date, start_time, end_time);

  CREATE TABLE IF NOT EXISTS shift_signups (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    slot_id INTEGER NOT NULL REFERENCES shift_slots(id),
    employee_id INTEGER NOT NULL REFERENCES employees(id),
    status TEXT NOT NULL CHECK (status IN ('approved', 'cancelled')) DEFAULT 'approved',
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    cancelled_at TEXT,
    cancelled_by TEXT
  );

  CREATE INDEX IF NOT EXISTS idx_shift_signups_slot
    ON shift_signups (slot_id, status);

  CREATE INDEX IF NOT EXISTS idx_shift_signups_employee
    ON shift_signups (employee_id, status);

  CREATE TABLE IF NOT EXISTS pay_rates (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    employee_id INTEGER NOT NULL REFERENCES employees(id),
    hourly_rate REAL NOT NULL,
    valid_from TEXT NOT NULL,
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    UNIQUE (employee_id, valid_from)
  );

  CREATE INDEX IF NOT EXISTS idx_pay_rates_employee
    ON pay_rates (employee_id, valid_from);

  CREATE TABLE IF NOT EXISTS month_closures (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    employee_id INTEGER NOT NULL REFERENCES employees(id),
    period TEXT NOT NULL,
    status TEXT NOT NULL CHECK (status IN ('waiting_employee', 'confirmed', 'locked')) DEFAULT 'waiting_employee',
    employee_confirmed_at TEXT,
    locked_at TEXT,
    UNIQUE (employee_id, period)
  );

  CREATE TABLE IF NOT EXISTS payroll (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    employee_id INTEGER NOT NULL REFERENCES employees(id),
    period TEXT NOT NULL,
    worked_minutes INTEGER NOT NULL DEFAULT 0,
    base_amount REAL NOT NULL DEFAULT 0,
    tips_amount REAL NOT NULL DEFAULT 0,
    bonus_amount REAL NOT NULL DEFAULT 0,
    other_amount REAL NOT NULL DEFAULT 0,
    final_amount REAL NOT NULL DEFAULT 0,
    status TEXT NOT NULL CHECK (status IN ('draft', 'ready', 'paid')) DEFAULT 'draft',
    payment_date TEXT,
    updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    UNIQUE (employee_id, period)
  );
`);
