import 'dotenv/config';
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
import { BRAND } from '@/lib/white-label/constants';

const prisma = new PrismaClient();

const RESOURCES = [
  'system',
  'finance',
  'hr',
  'inventory',
  'crm',
  'documents',
  'contracts',
  'workflows',
  'agents',
  'reports',
  'settings',
];

const ACTIONS = ['read', 'write', 'delete', 'approve', 'admin'];
const SCOPES = ['all', 'department', 'team', 'own'];

async function seedPermissions() {
  console.log('\n🔑 Seeding permissions...');
  
  const permissions: Array<{
    name: string;
    displayName: string;
    description: string;
    resource: string;
    action: string;
    scope: string;
  }> = [];

  for (const resource of RESOURCES) {
    for (const action of ACTIONS) {
      for (const scope of SCOPES) {
        // Skip illogical combinations
        if (action === 'admin' && scope !== 'all') continue;
        
        const name = `${resource}:${action}:${scope}`;
        const displayName = `${resource.charAt(0).toUpperCase() + resource.slice(1)} - ${action.charAt(0).toUpperCase() + action.slice(1)} (${scope})`;
        
        permissions.push({
          name,
          displayName,
          description: `Permission to ${action} ${resource} data with ${scope} scope`,
          resource,
          action,
          scope,
        });
      }
    }
  }

  for (const perm of permissions) {
    await prisma.permission.upsert({
      where: { name: perm.name },
      update: {},
      create: perm,
    });
  }

  console.log(`  ✔ Created ${permissions.length} permissions`);
}

async function seedRoles() {
  console.log('\n🎭 Seeding roles...');

  const roles = [
    {
      name: 'super_admin',
      displayName: 'Super Administrator',
      description: 'Full system access with all privileges',
      type: 'system',
      isDefault: false,
      permissions: ['system:admin:all'],
    },
    {
      name: 'admin',
      displayName: 'Administrator',
      description: 'Organization administrator with most privileges',
      type: 'system',
      isDefault: false,
      permissions: [
        'finance:admin:all',
        'hr:admin:all',
        'inventory:admin:all',
        'crm:admin:all',
        'documents:admin:all',
        'contracts:admin:all',
        'workflows:admin:all',
        'agents:admin:all',
        'reports:admin:all',
        'settings:write:all',
      ],
    },
    {
      name: 'finance_manager',
      displayName: 'Finance Manager',
      description: 'Full access to finance module',
      type: 'custom',
      isDefault: false,
      permissions: [
        'finance:admin:all',
        'reports:read:all',
        'documents:read:all',
        'contracts:read:all',
      ],
    },
    {
      name: 'hr_manager',
      displayName: 'HR Manager',
      description: 'Full access to HR module',
      type: 'custom',
      isDefault: false,
      permissions: [
        'hr:admin:all',
        'reports:read:all',
        'documents:read:all',
      ],
    },
    {
      name: 'inventory_manager',
      displayName: 'Inventory Manager',
      description: 'Full access to inventory module',
      type: 'custom',
      isDefault: false,
      permissions: [
        'inventory:admin:all',
        'reports:read:all',
        'documents:read:all',
      ],
    },
    {
      name: 'sales_manager',
      displayName: 'Sales Manager',
      description: 'Full access to CRM and sales module',
      type: 'custom',
      isDefault: false,
      permissions: [
        'crm:admin:all',
        'inventory:read:all',
        'reports:read:all',
        'documents:read:all',
        'contracts:read:all',
      ],
    },
    {
      name: 'employee',
      displayName: 'Employee',
      description: 'Standard employee with self-service access',
      type: 'system',
      isDefault: true,
      permissions: [
        'hr:read:own',
        'hr:write:own',
        'documents:read:own',
        'reports:read:own',
      ],
    },
    {
      name: 'viewer',
      displayName: 'Viewer',
      description: 'Read-only access to authorized modules',
      type: 'system',
      isDefault: false,
      permissions: [
        'finance:read:all',
        'hr:read:department',
        'inventory:read:all',
        'crm:read:all',
        'documents:read:all',
        'reports:read:all',
      ],
    },
  ];

  for (const roleData of roles) {
    const { permissions: permNames, ...role } = roleData;

    // Upsert role
    const createdRole = await prisma.role.upsert({
      where: { name: role.name },
      update: { displayName: role.displayName, description: role.description },
      create: role,
    });

    // Assign permissions
    for (const permName of permNames) {
      const permission = await prisma.permission.findUnique({
        where: { name: permName },
      });

      if (permission) {
        await prisma.rolePermission.upsert({
          where: {
            roleId_permissionId: {
              roleId: createdRole.id,
              permissionId: permission.id,
            },
          },
          update: {},
          create: {
            roleId: createdRole.id,
            permissionId: permission.id,
          },
        });
      }
    }

    console.log(`  ✔ Created role: ${role.displayName}`);
  }
}

async function seedDefaultUsers() {
  console.log('\n👤 Seeding default users...');

  // Get roles
  const superAdminRole = await prisma.role.findUnique({ where: { name: 'super_admin' } });
  const adminRole = await prisma.role.findUnique({ where: { name: 'admin' } });
  const employeeRole = await prisma.role.findUnique({ where: { name: 'employee' } });

  // Create super admin (Scott)
  const scottPassword = await bcrypt.hash('Boo02052024', 12);
  const scott = await prisma.gfsUser.upsert({
    where: { email: `scott@${BRAND.domain}` },
    update: {},
    create: {
      email: `scott@${BRAND.domain}`,
      name: 'Scott',
      passwordHash: scottPassword,
      status: 'active',
      department: 'Executive',
      title: 'Founder & CEO',
      timezone: 'America/Chicago',
    },
  });

  if (superAdminRole) {
    await prisma.userRole.upsert({
      where: {
        userId_roleId_scope: {
          userId: scott.id,
          roleId: superAdminRole.id,
          scope: 'global',
        },
      },
      update: {},
      create: {
        userId: scott.id,
        roleId: superAdminRole.id,
        scope: 'global',
      },
    });
  }
  console.log('  ✔ Created user: Scott (Super Admin)');

  // Create demo admin
  const demoPassword = await bcrypt.hash('Demo2024!', 12);
  const demo = await prisma.gfsUser.upsert({
    where: { email: 'demo@ghostfoundry.ai' },
    update: {},
    create: {
      email: 'demo@ghostfoundry.ai',
      name: 'Demo User',
      passwordHash: demoPassword,
      status: 'active',
      department: 'Operations',
      title: 'Operations Manager',
      timezone: 'UTC',
    },
  });

  if (adminRole) {
    await prisma.userRole.upsert({
      where: {
        userId_roleId_scope: {
          userId: demo.id,
          roleId: adminRole.id,
          scope: 'global',
        },
      },
      update: {},
      create: {
        userId: demo.id,
        roleId: adminRole.id,
        scope: 'global',
      },
    });
  }
  console.log('  ✔ Created user: Demo (Admin)');

  // Create test employee
  const testPassword = await bcrypt.hash('Test2024!', 12);
  const test = await prisma.gfsUser.upsert({
    where: { email: 'test@ghostfoundry.ai' },
    update: {},
    create: {
      email: 'test@ghostfoundry.ai',
      name: 'Test Employee',
      passwordHash: testPassword,
      status: 'active',
      department: 'Engineering',
      title: 'Software Engineer',
      timezone: 'UTC',
    },
  });

  if (employeeRole) {
    await prisma.userRole.upsert({
      where: {
        userId_roleId_scope: {
          userId: test.id,
          roleId: employeeRole.id,
          scope: 'global',
        },
      },
      update: {},
      create: {
        userId: test.id,
        roleId: employeeRole.id,
        scope: 'global',
      },
    });
  }
  console.log('  ✔ Created user: Test Employee');
}

async function main() {
  console.log(`\n👻 ${BRAND.companyName} RBAC Seed`);
  console.log('=====================================');

  try {
    await seedPermissions();
    await seedRoles();
    await seedDefaultUsers();

    console.log('\n✅ RBAC seed completed successfully!');
    console.log('\n🔑 Login credentials:');
    console.log(`   Super Admin: scott@${BRAND.domain} / Boo02052024`);
    console.log('   Admin:       demo@ghostfoundry.ai / Demo2024!');
    console.log('   Employee:    test@ghostfoundry.ai / Test2024!');
  } catch (error) {
    console.error('\n❌ Error seeding RBAC:', error);
    throw error;
  } finally {
    await prisma.$disconnect();
  }
}

main();
