/**
 * Seed Dealer Users
 * Creates dealer users for claim management workflow
 * These users will act as action takers in the workflow
 */

import { sequelize } from '../config/database';
import { User } from '../models/User';
import logger from '../utils/logger';

const appDomain = process.env.APP_DOMAIN || 'royalenfield.com';

interface DealerData {
  email: string;
  dealerCode: string;
  dealerName: string;
  displayName: string;
  department?: string;
  designation?: string;
  phone?: string;
  role?: 'USER' | 'MANAGEMENT' | 'ADMIN';
}

const dealers: DealerData[] = [
  {
    email: `test.2@${appDomain}`,
    dealerCode: 'RE-MH-001',
    dealerName: 'Royal Motors Mumbai',
    displayName: 'Royal Motors Mumbai',
    department: 'Dealer Operations',
    designation: 'Dealer',
    phone: '+91-9876543210',
    role: 'USER',
  },
  {
    email: `test.4@${appDomain}`,
    dealerCode: 'RE-DL-002',
    dealerName: 'Delhi enfield center',
    displayName: 'Delhi Enfield Center',
    department: 'Dealer Operations',
    designation: 'Dealer',
    phone: '+91-9876543211',
    role: 'USER',
  },
];

async function seedDealers(): Promise<void> {
  try {
    logger.info('[Seed Dealers] Starting dealer user seeding...');

    for (const dealer of dealers) {
      // Check if user already exists
      const existingUser = await User.findOne({
        where: { email: dealer.email },
      });

      if (existingUser) {
        // User already exists (likely from Okta SSO login)
        const isOktaUser = existingUser.oktaSub && !existingUser.oktaSub.startsWith('dealer-');

        if (isOktaUser) {
          logger.info(`[Seed Dealers] User ${dealer.email} already exists as Okta user (oktaSub: ${existingUser.oktaSub}), updating dealer-specific fields only...`);
        } else {
          logger.info(`[Seed Dealers] User ${dealer.email} already exists, updating dealer information...`);
        }

        // Update existing user with dealer information
        // IMPORTANT: Preserve Okta data (oktaSub, role from Okta, etc.) and only update dealer-specific fields
        const nameParts = dealer.dealerName.split(' ');
        const firstName = nameParts[0] || dealer.dealerName;
        const lastName = nameParts.slice(1).join(' ') || '';

        // Build update object - only update fields that don't conflict with Okta data
        const updateData: any = {
          // Always update dealer code in employeeId (this is dealer-specific, safe to update)
          employeeId: dealer.dealerCode,
        };

        // Only update displayName if it's different or if current one is empty
        if (!existingUser.displayName || existingUser.displayName !== dealer.displayName) {
          updateData.displayName = dealer.displayName;
        }

        // Only update designation if current one doesn't indicate dealer role
        if (!existingUser.designation || !existingUser.designation.toLowerCase().includes('dealer')) {
          updateData.designation = dealer.designation || existingUser.designation;
        }

        // Only update department if it's not set or if we want to ensure "Dealer Operations"
        if (!existingUser.department || existingUser.department !== 'Dealer Operations') {
          updateData.department = dealer.department || existingUser.department;
        }

        // Update phone if not set
        if (!existingUser.phone && dealer.phone) {
          updateData.phone = dealer.phone;
        }

        // Update name parts if not set
        if (!existingUser.firstName && firstName) {
          updateData.firstName = firstName;
        }
        if (!existingUser.lastName && lastName) {
          updateData.lastName = lastName;
        }

        await existingUser.update(updateData);

        if (isOktaUser) {
          logger.info(`[Seed Dealers] ✅ Updated existing Okta user ${dealer.email} with dealer code: ${dealer.dealerCode}`);
          logger.info(`[Seed Dealers] Preserved Okta data: oktaSub=${existingUser.oktaSub}, role=${existingUser.role}`);
        } else {
          logger.info(`[Seed Dealers] ✅ Updated user ${dealer.email} with dealer code: ${dealer.dealerCode}`);
        }
      } else {
        // User doesn't exist - create new dealer user
        // NOTE: If dealer is an Okta user, they should login via SSO first to be created automatically
        // This creates a placeholder user that will be updated when they login via SSO
        logger.warn(`[Seed Dealers] User ${dealer.email} not found in database. Creating placeholder user...`);
        logger.warn(`[Seed Dealers] ⚠️ If this user is an Okta user, they should login via SSO first to be created automatically.`);
        logger.warn(`[Seed Dealers] ⚠️ The oktaSub will be updated when they login via SSO.`);

        // Generate a UUID for userId
        const { v4: uuidv4 } = require('uuid');
        const userId = uuidv4();

        const nameParts = dealer.dealerName.split(' ');
        const firstName = nameParts[0] || dealer.dealerName;
        const lastName = nameParts.slice(1).join(' ') || '';

        await User.create({
          userId,
          email: dealer.email.toLowerCase(),
          displayName: dealer.displayName,
          firstName,
          lastName,
          department: dealer.department || 'Dealer Operations',
          designation: dealer.designation || 'Dealer',
          phone: dealer.phone,
          role: dealer.role || 'USER',
          employeeId: dealer.dealerCode, // Store dealer code in employeeId field
          isActive: true,
          // Set placeholder oktaSub - will be updated when user logs in via SSO
          // Using a recognizable pattern so we know it's a placeholder
          oktaSub: `dealer-${dealer.dealerCode}-pending-sso`,
          emailNotificationsEnabled: true,
          pushNotificationsEnabled: false,
          inAppNotificationsEnabled: true,
          createdAt: new Date(),
          updatedAt: new Date(),
        } as any);

        logger.info(`[Seed Dealers] ⚠️ Created placeholder dealer user: ${dealer.email} (${dealer.dealerCode})`);
        logger.info(`[Seed Dealers] ⚠️ User should login via SSO to update oktaSub field with real Okta subject ID`);
      }
    }

    logger.info('[Seed Dealers] ✅ Dealer seeding completed successfully');
  } catch (error) {
    logger.error('[Seed Dealers] ❌ Error seeding dealers:', error);
    throw error;
  }
}

// Run if called directly
if (require.main === module) {
  sequelize
    .authenticate()
    .then(() => {
      logger.info('[Seed Dealers] Database connection established');
      return seedDealers();
    })
    .then(() => {
      logger.info('[Seed Dealers] Seeding completed');
      process.exit(0);
    })
    .catch((error) => {
      logger.error('[Seed Dealers] Seeding failed:', error);
      process.exit(1);
    });
}

export { seedDealers, dealers };

