import { getDefaultPermissions } from "../../lib/auth/rbac.ts";
import {
  createSqlClient,
  deterministicId,
  type SqlClient,
} from "../../../scripts/lib/seed-utils.ts";

type UserRow = {
  id: string;
  email: string;
};

const DEFAULT_ORGANIZATION = {
  id: deterministicId("organization:alla-demo"),
  name: "ALLA Demo",
  slug: "alla-demo",
  membershipId: deterministicId("membership:alla-demo:super-admin"),
};

async function resolveSuperAdmin(sql: SqlClient): Promise<UserRow> {
  const email = process.env.SUPER_ADMIN_EMAIL?.trim().toLowerCase();

  if (!email) {
    throw new Error(
      "SUPER_ADMIN_EMAIL is required before running system organization seed.",
    );
  }

  const [user] = await sql<UserRow[]>`
    select id, email
    from users
    where email = ${email}
    limit 1
  `;

  if (!user) {
    throw new Error("Super admin user not found. Run seed-super-admin first.");
  }

  return user;
}

async function ensureOrganization(sql: SqlClient, superAdmin: UserRow) {
  await sql`
    insert into organizations (
      id,
      name,
      slug,
      plan,
      created_by
    ) values (
      ${DEFAULT_ORGANIZATION.id},
      ${DEFAULT_ORGANIZATION.name},
      ${DEFAULT_ORGANIZATION.slug},
      ${"enterprise"},
      ${superAdmin.id}
    )
    on conflict (slug) do update
    set
      name = excluded.name,
      plan = excluded.plan,
      updated_at = now()
  `;

  const membershipPermissions = getDefaultPermissions("admin", "crm_admin");
  const [existingMembership] = await sql<{ id: string }[]>`
    select id
    from memberships
    where user_id = ${superAdmin.id}
      and organization_id = ${DEFAULT_ORGANIZATION.id}
    limit 1
  `;

  if (existingMembership) {
    await sql`
      update memberships
      set
        role = ${"admin"},
        business_role = ${"crm_admin"},
        permissions = ${sql.array(membershipPermissions)},
        updated_at = now()
      where id = ${existingMembership.id}
    `;
  } else {
    await sql`
      insert into memberships (
        id,
        user_id,
        organization_id,
        role,
        business_role,
        permissions,
        branch_scope_ids,
        product_type_scope_ids
      ) values (
        ${DEFAULT_ORGANIZATION.membershipId},
        ${superAdmin.id},
        ${DEFAULT_ORGANIZATION.id},
        ${"admin"},
        ${"crm_admin"},
        ${sql.array(membershipPermissions)},
        ${sql.array([])},
        ${sql.array([])}
      )
    `;
  }

  await sql`
    update users
    set
      active_organization_id = ${DEFAULT_ORGANIZATION.id},
      updated_at = now()
    where id = ${superAdmin.id}
  `;
}

async function main() {
  const sql = createSqlClient();

  try {
    const superAdmin = await resolveSuperAdmin(sql);
    await ensureOrganization(sql, superAdmin);
    console.log(`[seed:system-org] Ready ${DEFAULT_ORGANIZATION.name}`);
  } finally {
    await sql.end();
  }
}

main().catch((error) => {
  console.error(
    "[seed:system-org] Failed:",
    error instanceof Error ? error.message : String(error),
  );
  process.exitCode = 1;
});
