import { sequelize } from '@config/database';
import { QueryTypes } from 'sequelize';
import logger from '@utils/logger';
import { ActivityType } from '@models/ActivityType';

/**
 * Default activity types from CLAIM_TYPES array
 * These will be seeded into the database with default item_code values (1-13)
 */
const DEFAULT_ACTIVITY_TYPES = [
  { title: 'Riders Mania Claims', itemCode: '1', taxationType: 'Non GST', sapRefNo: 'ZRDM', creditPostingOn: 'Spares' },
  { title: 'Marketing Cost – Bike to Vendor', itemCode: '2', taxationType: 'Non GST', sapRefNo: 'ZMBV', creditPostingOn: 'Vehicles' },
  { title: 'Media Bike Service', itemCode: '3', taxationType: 'GST', sapRefNo: 'ZMBS', creditPostingOn: 'Spares' },
  { title: 'ARAI Motorcycle Liquidation', itemCode: '4', taxationType: 'GST', sapRefNo: 'ZAML', creditPostingOn: 'Vehicles' },
  { title: 'ARAI Certification – STA Approval CNR', itemCode: '5', taxationType: 'Non GST', sapRefNo: 'ZACS', creditPostingOn: 'Vehicles' },
  { title: 'Procurement of Spares/Apparel/GMA for Events', itemCode: '6', taxationType: 'GST', sapRefNo: 'ZPPE', creditPostingOn: 'Spares' },
  { title: 'Fuel for Media Bike Used for Event', itemCode: '7', taxationType: 'Non GST', sapRefNo: 'ZFMB', creditPostingOn: 'Vehicles' },
  { title: 'Motorcycle Buyback and Goodwill Support', itemCode: '8', taxationType: 'Non GST', sapRefNo: 'ZMBG', creditPostingOn: 'Vehicles' },
  { title: 'Liquidation of Used Motorcycle', itemCode: '9', taxationType: 'GST', sapRefNo: 'ZLUM', creditPostingOn: 'Vehicles' },
  { title: 'Motorcycle Registration CNR (Owned or Gifted by RE)', itemCode: '10', taxationType: 'GST', sapRefNo: 'ZMRC', creditPostingOn: 'Vehicles' },
  { title: 'Legal Claims Reimbursement', itemCode: '11', taxationType: 'Non GST', sapRefNo: 'ZLCR', creditPostingOn: 'Vehicles' },
  { title: 'Service Camp Claims', itemCode: '12', taxationType: 'Non GST', sapRefNo: 'ZSCC', creditPostingOn: 'Spares' },
  { title: 'Corporate Claims – Institutional Sales PD', itemCode: '13', taxationType: 'Non GST', sapRefNo: 'ZCCN', creditPostingOn: 'Vehicles' },
  { title: 'Corporate Claims – Institutional Sales PD', itemCode: '14', taxationType: 'GST', sapRefNo: 'ZCCG', creditPostingOn: 'Vehicles' }
];

/**
 * Seed default activity types if table is empty
 * Called automatically on server startup
 */
export async function seedDefaultActivityTypes(): Promise<void> {
  try {
    // Check if activity_types table exists
    const tableExists = await sequelize.query(
      `SELECT EXISTS (
        SELECT FROM information_schema.tables 
        WHERE table_schema = 'public' 
        AND table_name = 'activity_types'
      )`,
      { type: QueryTypes.SELECT }
    );

    const exists = tableExists && tableExists.length > 0 && (tableExists[0] as any).exists;

    if (!exists) {
      logger.warn('[ActivityType Seed] ⚠️  activity_types table does not exist. Please run migrations first (npm run migrate). Skipping seed.');
      return;
    }

    logger.info('[ActivityType Seed] Seeding default activity types (duplicates will be skipped automatically)...');

    // Get system user ID (first admin user) for created_by
    const systemUser = await sequelize.query(
      `SELECT user_id FROM users WHERE role = 'ADMIN' ORDER BY created_at ASC LIMIT 1`,
      { type: QueryTypes.SELECT }
    );

    let systemUserId: string | null = null;
    if (systemUser && systemUser.length > 0) {
      systemUserId = (systemUser[0] as any).user_id;
    }

    const hasAdminUser = !!systemUserId;
    if (!hasAdminUser) {
      logger.warn('[ActivityType Seed] No admin user found. New activity types will be skipped (created_by is required). Create an admin user and restart to seed them.');
    }

    // Insert default activity types with proper handling
    let createdCount = 0;
    let updatedCount = 0;
    let skippedCount = 0;

    for (const activityType of DEFAULT_ACTIVITY_TYPES) {
      const { title, itemCode, taxationType, sapRefNo, creditPostingOn } = activityType;
      try {
        // Check if activity type already exists (active or inactive)
        const existing = await ActivityType.findOne({
          where: { title, sapRefNo } // Match on both title and sapRefNo since title "Corporate Claims..." is duplicated
        });

        if (existing) {
          // Identify fields to update (only need systemUserId for updatedBy)
          const updates: any = {};
          if (existing.itemCode !== itemCode) updates.itemCode = itemCode;
          if (existing.taxationType !== taxationType) updates.taxationType = taxationType;
          if (existing.sapRefNo !== sapRefNo) updates.sapRefNo = sapRefNo;
          if (existing.creditPostingOn !== creditPostingOn) updates.creditPostingOn = creditPostingOn;
          if (systemUserId) updates.updatedBy = systemUserId;

          if (!existing.isActive) {
            updates.isActive = true;
            await existing.update(updates);
            updatedCount++;
            logger.debug(`[ActivityType Seed] Reactivated existing activity type: ${title} (updates: ${JSON.stringify(updates)})`);
          } else {
            if (Object.keys(updates).length > 0) {
              await existing.update(updates);
              logger.debug(`[ActivityType Seed] Updated fields for existing activity type: ${title} (updates: ${JSON.stringify(updates)})`);
              updatedCount++;
            } else {
              skippedCount++;
              logger.debug(`[ActivityType Seed] Activity type already exists and active: ${title}`);
            }
          }
        } else {
          // Create new only when we have an admin user (created_by FK requires valid user_id)
          if (!hasAdminUser) {
            skippedCount++;
            logger.debug(`[ActivityType Seed] Skipped creating ${title} (no admin user for created_by)`);
            continue;
          }
          await ActivityType.create({
            title,
            itemCode: itemCode,
            taxationType: taxationType,
            sapRefNo: sapRefNo,
            creditPostingOn: creditPostingOn,
            isActive: true,
            createdBy: systemUserId!
          } as any);
          createdCount++;
          logger.debug(`[ActivityType Seed] Created new activity type: ${title} (item_code: ${itemCode}, sap_ref: ${sapRefNo})`);
        }
      } catch (error: any) {
        // Log error but continue with other activity types
        logger.warn(`[ActivityType Seed] Error processing ${title}: ${error?.message || String(error)}`);
        skippedCount++;
      }
    }

    // Verify how many are now active
    const result = await sequelize.query(
      'SELECT COUNT(*) as count FROM activity_types WHERE is_active = true',
      { type: QueryTypes.SELECT }
    );
    const totalCount = result && (result[0] as any).count ? (result[0] as any).count : 0;

    logger.info(`[ActivityType Seed] ✅ Activity type seeding complete. Created: ${createdCount}, Reactivated: ${updatedCount}, Skipped: ${skippedCount}, Total active: ${totalCount}`);
  } catch (error: any) {
    logger.error('[ActivityType Seed] ❌ Error seeding activity types:', {
      message: error?.message || String(error),
      stack: error?.stack,
      name: error?.name
    });
    // Don't throw - let server start even if seeding fails
  }
}

