/**
 * Shared seed bootstrap: ports + system roles + super admin profile.
 *
 * Both the realistic seed (`seed.ts`) and the synthetic seed
 * (`seed-synthetic.ts`) call into this so we don't drift on the
 * permission maps or the operator account ids.
 *
 * Idempotent. Returns the resolved port ids so callers can chain
 * per-port fixture builders.
 */

import { and, eq } from 'drizzle-orm';
import { db } from './index';
import { ports } from './schema/ports';
import { roles, userProfiles } from './schema/users';
import { systemSettings } from './schema/system';
import {
  ALL_PERMISSIONS,
  DIRECTOR_PERMISSIONS,
  SALES_MANAGER_PERMISSIONS,
  SALES_AGENT_PERMISSIONS,
  VIEWER_PERMISSIONS,
  RESIDENTIAL_PARTNER_PERMISSIONS,
} from './seed-permissions';

export interface BootstrappedPort {
  id: string;
  name: string;
  slug: string;
}

interface PortBrandingSeed {
  logoUrl?: string;
  emailBackgroundUrl?: string;
  appName?: string;
  emailHeaderHtml?: string;
  emailFooterHtml?: string;
}

export const PORT_DEFINITIONS: Array<{
  name: string;
  slug: string;
  primaryColor: string;
  defaultCurrency: string;
  timezone: string;
  branding?: PortBrandingSeed;
}> = [
  {
    name: 'Port Nimara',
    slug: 'port-nimara',
    primaryColor: '#0F4C81',
    defaultCurrency: 'USD',
    timezone: 'America/Anguilla',
    branding: {
      logoUrl:
        'https://s3.portnimara.com/images/Port%20Nimara%20New%20Logo-Circular%20Frame_250px.png',
      emailBackgroundUrl: 'https://s3.portnimara.com/images/Overhead_1_blur.png',
      appName: 'Port Nimara CRM',
    },
  },
  {
    name: 'Port Amador',
    slug: 'port-amador',
    primaryColor: '#D97706',
    defaultCurrency: 'USD',
    timezone: 'America/Panama',
    // Branding intentionally left empty - admin uploads their own assets
    // via /admin/branding rather than inheriting Port Nimara's look.
  },
];

export const SUPER_ADMIN_USER_ID = 'super-admin-matt-portnimara';

export async function seedBootstrap(): Promise<BootstrappedPort[]> {
  console.log('Bootstrap: ports + roles + super admin profile');

  // ── Ports ──────────────────────────────────────────────────────────────────
  const portIds: BootstrappedPort[] = [];
  for (const def of PORT_DEFINITIONS) {
    const [inserted] = await db
      .insert(ports)
      .values({
        id: crypto.randomUUID(),
        name: def.name,
        slug: def.slug,
        logoUrl: null,
        primaryColor: def.primaryColor,
        defaultCurrency: def.defaultCurrency,
        timezone: def.timezone,
        settings: {},
        isActive: true,
      })
      .onConflictDoNothing()
      .returning();

    let portId: string | null = null;
    if (inserted) {
      console.log(`  Port created: ${def.name} (${inserted.id})`);
      portIds.push({ id: inserted.id, name: def.name, slug: def.slug });
      portId = inserted.id;
    } else {
      const [existing] = await db.select().from(ports).where(eq(ports.slug, def.slug)).limit(1);
      if (existing) {
        console.log(`  Port exists:  ${def.name} (${existing.id})`);
        portIds.push({ id: existing.id, name: def.name, slug: def.slug });
        portId = existing.id;
      }
    }

    // Seed branding settings idempotently. `onConflictDoNothing` so an
    // admin who's tweaked the values via /admin/branding doesn't get
    // their work overwritten by a re-seed.
    if (portId && def.branding) {
      const brandingPairs: Array<[string, unknown]> = [];
      if (def.branding.logoUrl) brandingPairs.push(['branding_logo_url', def.branding.logoUrl]);
      if (def.branding.emailBackgroundUrl)
        brandingPairs.push(['branding_email_background_url', def.branding.emailBackgroundUrl]);
      if (def.branding.appName) brandingPairs.push(['branding_app_name', def.branding.appName]);
      if (def.branding.emailHeaderHtml)
        brandingPairs.push(['branding_email_header_html', def.branding.emailHeaderHtml]);
      if (def.branding.emailFooterHtml)
        brandingPairs.push(['branding_email_footer_html', def.branding.emailFooterHtml]);
      brandingPairs.push(['branding_primary_color', def.primaryColor]);

      for (const [key, value] of brandingPairs) {
        // Skip when an existing row is already present - preserves admin
        // edits across re-seeds. Pair (key, portId) is uniquely indexed.
        const existing = await db.query.systemSettings.findFirst({
          where: and(eq(systemSettings.key, key), eq(systemSettings.portId, portId)),
        });
        if (existing) continue;
        await db.insert(systemSettings).values({
          key,
          value: value as Record<string, unknown>,
          portId,
          updatedBy: SUPER_ADMIN_USER_ID,
        });
      }
      console.log(`  Branding seeded for ${def.name} (${brandingPairs.length} keys)`);
    }
  }

  // ── System roles ──────────────────────────────────────────────────────────
  const systemRoles = [
    {
      id: crypto.randomUUID(),
      name: 'super_admin',
      description: 'Full system access. Bypasses all permission checks.',
      permissions: ALL_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
    {
      id: crypto.randomUUID(),
      name: 'director',
      description: 'Senior sales title. Full sales access, no admin/settings (Super-Admin only).',
      permissions: DIRECTOR_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
    {
      id: crypto.randomUUID(),
      name: 'sales_manager',
      description: 'Full sales access. Can view all reminders, assign tasks, and export reports.',
      permissions: SALES_MANAGER_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
    {
      id: crypto.randomUUID(),
      name: 'sales_agent',
      description:
        'Standard sales role. View/create/edit clients and interests, manage own reminders.',
      permissions: SALES_AGENT_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
    {
      id: crypto.randomUUID(),
      name: 'viewer',
      description: 'Read-only access to all records.',
      permissions: VIEWER_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
    {
      id: crypto.randomUUID(),
      name: 'residential_partner',
      description:
        'External partner who handles residential inquiries. Sees only the residential pages - no marina clients, yachts, berths, or financial data.',
      permissions: RESIDENTIAL_PARTNER_PERMISSIONS,
      isGlobal: true,
      isSystem: true,
    },
  ];

  for (const role of systemRoles) {
    await db.insert(roles).values(role).onConflictDoNothing();
  }
  console.log(`  Roles ensured: ${systemRoles.map((r) => r.name).join(', ')}`);

  // ── Super admin profile placeholder ───────────────────────────────────────
  await db
    .insert(userProfiles)
    .values({
      id: crypto.randomUUID(),
      userId: SUPER_ADMIN_USER_ID,
      displayName: 'Matt',
      avatarUrl: null,
      phone: null,
      isSuperAdmin: true,
      isActive: true,
      lastLoginAt: null,
      preferences: {},
    })
    .onConflictDoNothing();
  console.log(`  Super admin profile ensured (user_id: ${SUPER_ADMIN_USER_ID})`);

  return portIds;
}
