import type { PrismaClient } from '@prisma/client';
import { DEFAULT_ROLES, PERMISSIONS } from '../src/config/access.js';

// Shared by prisma/seed.ts and the DB-backed tests, so both set up access the same way.

export const ROLES = [
  // System roles — required for the app to bootstrap; not deletable from the UI later.
  { name: 'admin', description: 'Full platform access', isSystem: true },
  { name: 'user', description: 'Default role for new sign-ups', isSystem: true },
  // Business roles (see Planning Module doc) — editable/removable by an admin later.
  { name: 'organization-admin', description: 'Full access within one organization', isSystem: false },
  { name: 'director', description: 'Senior oversight across projects', isSystem: false },
  { name: 'project-manager', description: 'Manages a project end to end', isSystem: false },
  { name: 'planning-manager', description: 'Owns scheduling and planning', isSystem: false },
  { name: 'site-engineer', description: 'Site execution and daily progress', isSystem: false },
  { name: 'qs', description: 'Quantity surveying — BOQ, measurements, billing', isSystem: false },
  { name: 'procurement', description: 'Material and vendor procurement', isSystem: false },
  { name: 'accounts', description: 'Project cost and finance', isSystem: false },
  { name: 'sales-executive', description: 'Pre-sales / CRM (future phase)', isSystem: false },
  { name: 'viewer', description: 'Read-only access', isSystem: false },
];

// A demo tenant for local development (Growth plan + Execution, as in the
// tenant app's mock data). Link a real Firebase user to it with
// `npm run db:assign-user -- <email> eastfield organization-admin`.
export const DEMO_ORGANIZATION = {
  name: 'Eastfield Developers',
  code: 'eastfield',
  description: 'Demo tenant for local development',
  planName: 'Growth',
  maxUsers: 12,
  moduleKeys: ['tenant_admin', 'project_core', 'tasks', 'planning', 'documents', 'boq', 'execution'],
};

export async function seedRoles(prisma: PrismaClient) {
  for (const role of ROLES) {
    await prisma.role.upsert({ where: { name: role.name }, update: {}, create: role });
  }
}

export async function seedPermissions(prisma: PrismaClient) {
  for (const permission of PERMISSIONS) {
    await prisma.permission.upsert({
      where: { name: permission.name },
      update: { module: permission.module },
      create: permission,
    });
  }
}

// The default tenant roles' access (label, data scope, module access and
// permissions) always matches the shared contract in src/config/access.ts.
export async function seedRoleAccess(prisma: PrismaClient) {
  const permissionIds = new Map(
    (await prisma.permission.findMany({ select: { id: true, name: true } })).map((p) => [p.name, p.id]),
  );
  for (const role of DEFAULT_ROLES) {
    const { id } = await prisma.role.update({
      where: { name: role.name },
      data: { label: role.label, description: role.description, scope: role.scope, modules: role.modules },
    });
    await prisma.rolePermission.deleteMany({ where: { roleId: id } });
    await prisma.rolePermission.createMany({
      data: role.permissions.map((name) => ({ roleId: id, permissionId: permissionIds.get(name)! })),
    });
  }
}

// Demo projects for the demo tenant (same as the tenant app's mock data), so
// Project access has something to grant. Organizations add their own in Projects & sites.
export const DEMO_PROJECTS = [
  { code: 'EF-01', name: 'Eastfield Residences', location: 'Hinjewadi, Pune', status: 'in_progress', progressPct: 38, sites: ['Tower A', 'Tower B', 'Tower C'] },
  { code: 'RS-02', name: 'Riverside Commercial', location: 'Kharadi, Pune', status: 'planning', progressPct: 4, sites: ['Commercial Block'] },
];

export async function seedDemoProjects(prisma: PrismaClient, organizationId: number) {
  for (const { sites, ...project } of DEMO_PROJECTS) {
    const { id } = await prisma.project.upsert({
      where: { code: project.code },
      update: {},
      create: { ...project, organizationId },
    });
    await prisma.site.createMany({ data: sites.map((name) => ({ projectId: id, name })), skipDuplicates: true });
  }
}
