import { existsSync, mkdirSync, rmSync } from "node:fs";
import { dirname } from "node:path";
import { Database } from "bun:sqlite";

export interface Organization {
  id: string;
  slug: string;
  name: string;
  plan: string;
  industry: string;
  createdAt: string;
}

export interface User {
  id: string;
  orgId: string;
  fullName: string;
  email: string;
  role: string;
  timezone: string;
}

export interface Project {
  id: string;
  orgId: string;
  key: string;
  name: string;
  status: string;
  ownerUserId: string;
  dueDate: string | null;
}

export interface TaskRecord {
  id: string;
  orgId: string;
  projectId: string;
  assigneeUserId: string | null;
  title: string;
  description: string;
  status: string;
  priority: string;
  storyPoints: number | null;
  dueDate: string | null;
  createdAt: string;
  updatedAt: string;
}

export interface Label {
  id: string;
  orgId: string;
  name: string;
  color: string;
}

export interface CommentRecord {
  id: string;
  taskId: string;
  authorUserId: string;
  body: string;
  createdAt: string;
}

const organizations: Organization[] = [
  {
    id: "org_acme",
    slug: "acme-logistics",
    name: "Acme Logistics",
    plan: "enterprise",
    industry: "Logistics",
    createdAt: "2026-01-03T09:00:00.000Z",
  },
  {
    id: "org_northstar",
    slug: "northstar-health",
    name: "Northstar Health",
    plan: "growth",
    industry: "Healthcare",
    createdAt: "2026-01-11T10:15:00.000Z",
  },
  {
    id: "org_summit",
    slug: "summit-edu",
    name: "Summit Education",
    plan: "starter",
    industry: "Education",
    createdAt: "2026-01-20T08:30:00.000Z",
  },
];

const users: User[] = [
  {
    id: "user_acme_1",
    orgId: "org_acme",
    fullName: "Maya Patel",
    email: "maya@acme.example",
    role: "org_admin",
    timezone: "Europe/Dublin",
  },
  {
    id: "user_acme_2",
    orgId: "org_acme",
    fullName: "Jonas Weber",
    email: "jonas@acme.example",
    role: "project_manager",
    timezone: "Europe/Berlin",
  },
  {
    id: "user_acme_3",
    orgId: "org_acme",
    fullName: "Elena Rossi",
    email: "elena@acme.example",
    role: "engineer",
    timezone: "Europe/Rome",
  },
  {
    id: "user_northstar_1",
    orgId: "org_northstar",
    fullName: "Samir Khan",
    email: "samir@northstar.example",
    role: "org_admin",
    timezone: "America/New_York",
  },
  {
    id: "user_northstar_2",
    orgId: "org_northstar",
    fullName: "Leah Morris",
    email: "leah@northstar.example",
    role: "analyst",
    timezone: "America/Chicago",
  },
  {
    id: "user_summit_1",
    orgId: "org_summit",
    fullName: "Owen Doyle",
    email: "owen@summit.example",
    role: "org_admin",
    timezone: "Europe/Dublin",
  },
];

const projects: Project[] = [
  {
    id: "proj_acme_ops",
    orgId: "org_acme",
    key: "OPS",
    name: "Operations Platform",
    status: "active",
    ownerUserId: "user_acme_2",
    dueDate: "2026-04-30",
  },
  {
    id: "proj_acme_mobile",
    orgId: "org_acme",
    key: "MOB",
    name: "Courier Mobile App",
    status: "active",
    ownerUserId: "user_acme_1",
    dueDate: "2026-05-20",
  },
  {
    id: "proj_northstar_portal",
    orgId: "org_northstar",
    key: "PAT",
    name: "Patient Intake Portal",
    status: "active",
    ownerUserId: "user_northstar_1",
    dueDate: "2026-05-07",
  },
  {
    id: "proj_summit_reporting",
    orgId: "org_summit",
    key: "REP",
    name: "Teacher Reporting",
    status: "planning",
    ownerUserId: "user_summit_1",
    dueDate: "2026-06-12",
  },
];

const tasks: TaskRecord[] = [
  {
    id: "task_1001",
    orgId: "org_acme",
    projectId: "proj_acme_ops",
    assigneeUserId: "user_acme_3",
    title: "Add delivery exception workflow",
    description: "Support driver-reported delivery exceptions with customer-visible status updates.",
    status: "in_progress",
    priority: "high",
    storyPoints: 8,
    dueDate: "2026-03-10",
    createdAt: "2026-03-01T09:00:00.000Z",
    updatedAt: "2026-03-03T10:15:00.000Z",
  },
  {
    id: "task_1002",
    orgId: "org_acme",
    projectId: "proj_acme_ops",
    assigneeUserId: "user_acme_2",
    title: "Reconcile warehouse inventory feed",
    description: "Normalize nightly inventory import and surface failures in the admin dashboard.",
    status: "todo",
    priority: "urgent",
    storyPoints: 5,
    dueDate: "2026-03-06",
    createdAt: "2026-03-01T12:30:00.000Z",
    updatedAt: "2026-03-02T16:00:00.000Z",
  },
  {
    id: "task_1003",
    orgId: "org_acme",
    projectId: "proj_acme_mobile",
    assigneeUserId: "user_acme_3",
    title: "Implement offline proof-of-delivery queue",
    description: "Queue signatures and photos when couriers lose connectivity.",
    status: "blocked",
    priority: "high",
    storyPoints: 13,
    dueDate: "2026-03-18",
    createdAt: "2026-02-25T08:00:00.000Z",
    updatedAt: "2026-03-03T09:10:00.000Z",
  },
  {
    id: "task_1004",
    orgId: "org_acme",
    projectId: "proj_acme_mobile",
    assigneeUserId: null,
    title: "Refresh courier onboarding copy",
    description: "Rewrite first-run guidance for new regional couriers.",
    status: "todo",
    priority: "medium",
    storyPoints: 2,
    dueDate: "2026-03-21",
    createdAt: "2026-03-02T14:20:00.000Z",
    updatedAt: "2026-03-02T14:20:00.000Z",
  },
  {
    id: "task_2001",
    orgId: "org_northstar",
    projectId: "proj_northstar_portal",
    assigneeUserId: "user_northstar_2",
    title: "Audit intake form validation gaps",
    description: "Compare API validation with product requirements for intake submissions.",
    status: "in_review",
    priority: "high",
    storyPoints: 3,
    dueDate: "2026-03-12",
    createdAt: "2026-03-01T11:00:00.000Z",
    updatedAt: "2026-03-03T13:00:00.000Z",
  },
  {
    id: "task_2002",
    orgId: "org_northstar",
    projectId: "proj_northstar_portal",
    assigneeUserId: "user_northstar_1",
    title: "Prepare HIPAA access log export",
    description: "Generate downloadable audit log extracts for compliance reviews.",
    status: "todo",
    priority: "urgent",
    storyPoints: 8,
    dueDate: "2026-03-08",
    createdAt: "2026-02-28T10:45:00.000Z",
    updatedAt: "2026-03-02T18:30:00.000Z",
  },
  {
    id: "task_3001",
    orgId: "org_summit",
    projectId: "proj_summit_reporting",
    assigneeUserId: "user_summit_1",
    title: "Define grade export CSV format",
    description: "Align export columns with district reporting requirements.",
    status: "todo",
    priority: "medium",
    storyPoints: 3,
    dueDate: "2026-03-25",
    createdAt: "2026-03-02T09:30:00.000Z",
    updatedAt: "2026-03-02T09:30:00.000Z",
  },
];

const labels: Label[] = [
  { id: "label_backend", orgId: "org_acme", name: "backend", color: "#0f766e" },
  { id: "label_mobile", orgId: "org_acme", name: "mobile", color: "#1d4ed8" },
  { id: "label_compliance", orgId: "org_northstar", name: "compliance", color: "#b45309" },
  { id: "label_reporting", orgId: "org_summit", name: "reporting", color: "#7c3aed" },
];

const taskLabels = [
  { taskId: "task_1001", labelId: "label_backend" },
  { taskId: "task_1002", labelId: "label_backend" },
  { taskId: "task_1003", labelId: "label_mobile" },
  { taskId: "task_2002", labelId: "label_compliance" },
  { taskId: "task_3001", labelId: "label_reporting" },
];

const comments: CommentRecord[] = [
  {
    id: "comment_1",
    taskId: "task_1001",
    authorUserId: "user_acme_2",
    body: "Driver ops needs an exception code for failed building access.",
    createdAt: "2026-03-03T09:30:00.000Z",
  },
  {
    id: "comment_2",
    taskId: "task_1003",
    authorUserId: "user_acme_1",
    body: "Blocked until we settle image retention policy for offline uploads.",
    createdAt: "2026-03-03T09:40:00.000Z",
  },
  {
    id: "comment_3",
    taskId: "task_2002",
    authorUserId: "user_northstar_2",
    body: "Compliance requested a CSV and JSON version of the export.",
    createdAt: "2026-03-02T17:15:00.000Z",
  },
];

function createSchema(db: Database) {
  db.exec(`
    PRAGMA foreign_keys = ON;

    CREATE TABLE IF NOT EXISTS organizations (
      id TEXT PRIMARY KEY,
      slug TEXT NOT NULL UNIQUE,
      name TEXT NOT NULL,
      plan TEXT NOT NULL,
      industry TEXT NOT NULL,
      created_at TEXT NOT NULL
    );

    CREATE TABLE IF NOT EXISTS users (
      id TEXT PRIMARY KEY,
      org_id TEXT NOT NULL,
      full_name TEXT NOT NULL,
      email TEXT NOT NULL UNIQUE,
      role TEXT NOT NULL,
      timezone TEXT NOT NULL,
      FOREIGN KEY (org_id) REFERENCES organizations(id) ON DELETE CASCADE
    );

    CREATE TABLE IF NOT EXISTS projects (
      id TEXT PRIMARY KEY,
      org_id TEXT NOT NULL,
      key TEXT NOT NULL,
      name TEXT NOT NULL,
      status TEXT NOT NULL,
      owner_user_id TEXT NOT NULL,
      due_date TEXT,
      FOREIGN KEY (org_id) REFERENCES organizations(id) ON DELETE CASCADE,
      FOREIGN KEY (owner_user_id) REFERENCES users(id),
      UNIQUE (org_id, key)
    );

    CREATE TABLE IF NOT EXISTS tasks (
      id TEXT PRIMARY KEY,
      org_id TEXT NOT NULL,
      project_id TEXT NOT NULL,
      assignee_user_id TEXT,
      title TEXT NOT NULL,
      description TEXT NOT NULL,
      status TEXT NOT NULL,
      priority TEXT NOT NULL,
      story_points INTEGER,
      due_date TEXT,
      created_at TEXT NOT NULL,
      updated_at TEXT NOT NULL,
      FOREIGN KEY (org_id) REFERENCES organizations(id) ON DELETE CASCADE,
      FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
      FOREIGN KEY (assignee_user_id) REFERENCES users(id)
    );

    CREATE TABLE IF NOT EXISTS labels (
      id TEXT PRIMARY KEY,
      org_id TEXT NOT NULL,
      name TEXT NOT NULL,
      color TEXT NOT NULL,
      FOREIGN KEY (org_id) REFERENCES organizations(id) ON DELETE CASCADE,
      UNIQUE (org_id, name)
    );

    CREATE TABLE IF NOT EXISTS task_labels (
      task_id TEXT NOT NULL,
      label_id TEXT NOT NULL,
      PRIMARY KEY (task_id, label_id),
      FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
      FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE
    );

    CREATE TABLE IF NOT EXISTS comments (
      id TEXT PRIMARY KEY,
      task_id TEXT NOT NULL,
      author_user_id TEXT NOT NULL,
      body TEXT NOT NULL,
      created_at TEXT NOT NULL,
      FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
      FOREIGN KEY (author_user_id) REFERENCES users(id)
    );
  `);
}

export function openDatabase(dbPath: string): Database {
  mkdirSync(dirname(dbPath), { recursive: true });
  const db = new Database(dbPath, { create: true });
  createSchema(db);
  return db;
}

function insertSeedData(db: Database) {
  const insertOrganization = db.query(
    "INSERT INTO organizations (id, slug, name, plan, industry, created_at) VALUES (?, ?, ?, ?, ?, ?)",
  );
  const insertUser = db.query(
    "INSERT INTO users (id, org_id, full_name, email, role, timezone) VALUES (?, ?, ?, ?, ?, ?)",
  );
  const insertProject = db.query(
    "INSERT INTO projects (id, org_id, key, name, status, owner_user_id, due_date) VALUES (?, ?, ?, ?, ?, ?, ?)",
  );
  const insertTask = db.query(
    "INSERT INTO tasks (id, org_id, project_id, assignee_user_id, title, description, status, priority, story_points, due_date, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  );
  const insertLabel = db.query(
    "INSERT INTO labels (id, org_id, name, color) VALUES (?, ?, ?, ?)",
  );
  const insertTaskLabel = db.query(
    "INSERT INTO task_labels (task_id, label_id) VALUES (?, ?)",
  );
  const insertComment = db.query(
    "INSERT INTO comments (id, task_id, author_user_id, body, created_at) VALUES (?, ?, ?, ?, ?)",
  );

  const seed = db.transaction(() => {
    for (const org of organizations) {
      insertOrganization.run(
        org.id,
        org.slug,
        org.name,
        org.plan,
        org.industry,
        org.createdAt,
      );
    }

    for (const user of users) {
      insertUser.run(
        user.id,
        user.orgId,
        user.fullName,
        user.email,
        user.role,
        user.timezone,
      );
    }

    for (const project of projects) {
      insertProject.run(
        project.id,
        project.orgId,
        project.key,
        project.name,
        project.status,
        project.ownerUserId,
        project.dueDate,
      );
    }

    for (const task of tasks) {
      insertTask.run(
        task.id,
        task.orgId,
        task.projectId,
        task.assigneeUserId,
        task.title,
        task.description,
        task.status,
        task.priority,
        task.storyPoints,
        task.dueDate,
        task.createdAt,
        task.updatedAt,
      );
    }

    for (const label of labels) {
      insertLabel.run(label.id, label.orgId, label.name, label.color);
    }

    for (const assignment of taskLabels) {
      insertTaskLabel.run(assignment.taskId, assignment.labelId);
    }

    for (const comment of comments) {
      insertComment.run(
        comment.id,
        comment.taskId,
        comment.authorUserId,
        comment.body,
        comment.createdAt,
      );
    }
  });

  seed();
}

export function ensureSeededDatabase(dbPath: string) {
  const db = openDatabase(dbPath);
  const count = db.query("SELECT COUNT(*) AS count FROM organizations").get() as { count: number };
  if (count.count === 0) {
    insertSeedData(db);
  }

  return db;
}

export function reseedDatabase(dbPath: string) {
  mkdirSync(dirname(dbPath), { recursive: true });
  if (existsSync(dbPath)) {
    rmSync(dbPath);
  }

  const db = openDatabase(dbPath);
  insertSeedData(db);
  return db;
}
