/**
 * Seed demo data: Form 16 submissions and other workflow requests.
 * Data is inserted into database tables only (no hardcoded data in app code).
 *
 * Prerequisites:
 * - Run seed:admin-user (for admin user)
 * - Run seed:dealer-user (for dealer user + dealer record for Form 16)
 *
 * Usage: npm run seed:demo-requests
 */

import { Op } from 'sequelize';
import { sequelize } from '../config/database';
import {
  User,
  WorkflowRequest,
  Form16aSubmission,
  Form16CreditNote,
  Activity,
  Document,
  Dealer,
} from '../models';
import { Priority, WorkflowStatus } from '../types/common.types';
import { generateRequestNumber } from '../utils/helpers';
import logger from '../utils/logger';

const DEMO_MARKER_TITLE_PREFIX = 'Form 16A - 2024-25'; // Used to detect existing demo Form 16 data
const DEMO_CUSTOM_TITLE = '[Demo] Sample workflow request';

async function getOrResolveUsers(): Promise<{ adminUser: User | null; dealerUser: User | null; dealerCode: string | null }> {
  const adminUser = await User.findOne({ where: { email: 'admin@example.com' } });
  const dealerUser = await User.findOne({ where: { email: 'testreflow@example.com' } });
  let dealerCode: string | null = null;
  if (dealerUser) {
    const dealer = await Dealer.findOne({
      where: { dealerPrincipalEmailId: 'testreflow@example.com', isActive: true },
      attributes: ['salesCode', 'dlrcode'],
    });
    dealerCode = dealer?.salesCode ?? dealer?.dlrcode ?? null;
  }
  return { adminUser, dealerUser, dealerCode };
}

async function hasExistingDemoForm16(): Promise<boolean> {
  const count = await WorkflowRequest.count({
    where: {
      templateType: 'FORM_16',
      title: { [Op.like]: `${DEMO_MARKER_TITLE_PREFIX}%` },
    },
  });
  return count >= 2;
}

/** Demo dealers used for "non-submitted dealers" list: active dealers with no Form 16 submission for the demo FY/quarter. */
const DEMO_NON_SUBMITTED_DEALERS = [
  { dlrcode: 'DEMO-NOSUB-001', dealership: 'Demo Motors Mumbai', dealerPrincipalName: 'Demo Mumbai', dealerPrincipalEmailId: 'demo.nosub.1@example.com', state: 'Maharashtra', city: 'Mumbai' },
  { dlrcode: 'DEMO-NOSUB-002', dealership: 'Demo Enfield Delhi', dealerPrincipalName: 'Demo Delhi', dealerPrincipalEmailId: 'demo.nosub.2@example.com', state: 'Delhi', city: 'New Delhi' },
  { dlrcode: 'DEMO-NOSUB-003', dealership: 'Demo Royal Bangalore', dealerPrincipalName: 'Demo Bangalore', dealerPrincipalEmailId: 'demo.nosub.3@example.com', state: 'Karnataka', city: 'Bengaluru' },
];

async function ensureDemoNonSubmittedDealers(): Promise<void> {
  for (const data of DEMO_NON_SUBMITTED_DEALERS) {
    const [dealer] = await Dealer.findOrCreate({
      where: { dlrcode: data.dlrcode },
      defaults: {
        ...data,
        salesCode: data.dlrcode,
        isActive: true,
      } as any,
    });
    if (dealer && !dealer.isActive) {
      await dealer.update({ isActive: true });
    }
  }
  logger.info('[Seed Demo] Demo non-submitted dealers ensured (they have no Form 16 submissions for 2024-25).');
}

async function seedDemoRequests(): Promise<void> {
  // Always ensure demo dealers exist first (for both submission and non-submitted lists).
  // These dealers are in the dealers table; only the test dealer gets Form 16 submissions below.
  await ensureDemoNonSubmittedDealers();

  const { adminUser, dealerUser, dealerCode } = await getOrResolveUsers();
  const initiatorId = adminUser?.userId ?? dealerUser?.userId;
  if (!initiatorId) {
    logger.warn('[Seed Demo] No admin or dealer user found. Run seed:admin-user and seed:dealer-user first.');
    return;
  }

  if (await hasExistingDemoForm16()) {
    logger.info('[Seed Demo] Demo Form 16 requests already present. Skipping to avoid duplicates.');
    return;
  }

  const now = new Date();

  // ---- 1) Create a few CUSTOM (non–Form 16) requests so "other requests" are visible ----
  for (let i = 1; i <= 2; i++) {
    const requestNumber = await generateRequestNumber();
    await WorkflowRequest.create({
      requestNumber,
      initiatorId,
      templateType: 'CUSTOM',
      workflowType: 'NON_TEMPLATIZED',
      title: `${DEMO_CUSTOM_TITLE} ${i}`,
      description: `Demo workflow request for testing. Created by seed script.`,
      priority: Priority.STANDARD,
      status: i === 1 ? WorkflowStatus.PENDING : WorkflowStatus.PENDING,
      currentLevel: 1,
      totalLevels: 1,
      totalTatHours: 48,
      submissionDate: now,
      isDraft: false,
      isDeleted: false,
      isPaused: false,
    });
  }

  // ---- 2) Create Form 16 requests + submissions (and optional credit notes / activity / docs) ----
  if (!dealerUser || !dealerCode) {
    logger.warn('[Seed Demo] Dealer user or dealer code missing. Form 16 demo requests skipped. Run seed:dealer-user.');
  } else {
    const form16InitiatorId = dealerUser.userId;
    const form16Demos = [
      { fy: '2024-25', quarter: 'Q1', deductor: 'Royal Enfield Motors Ltd', tds: 15000, total: 150000, cnAmount: 15000, withCreditNote: true, withdrawn: false },
      { fy: '2024-25', quarter: 'Q2', deductor: 'Royal Enfield Motors Ltd', tds: 18000, total: 180000, cnAmount: 18000, withCreditNote: true, withdrawn: true },
      { fy: '2024-25', quarter: 'Q3', deductor: 'Royal Enfield Motors Ltd', tds: 12000, total: 120000, cnAmount: null, withCreditNote: false, withdrawn: false },
    ];

    for (const demo of form16Demos) {
      const requestNumber = await generateRequestNumber();
      const title = `Form 16A - ${demo.fy} ${demo.quarter}`;
      const description = `Form 16A TDS certificate submission. Deductor: ${demo.deductor}.`;

      const workflow = await WorkflowRequest.create({
        requestNumber,
        initiatorId: form16InitiatorId,
        templateType: 'FORM_16',
        workflowType: 'FORM_16',
        title,
        description,
      priority: Priority.STANDARD,
      status: demo.withCreditNote && !demo.withdrawn ? WorkflowStatus.CLOSED : WorkflowStatus.PENDING,
        currentLevel: 1,
        totalLevels: 1,
        totalTatHours: 0,
        submissionDate: now,
        closureDate: demo.withCreditNote && !demo.withdrawn ? now : undefined,
        isDraft: false,
        isDeleted: false,
        isPaused: false,
      });

      const requestId = (workflow as any).requestId;
      const form16aNumber = `DEMO-F16-${demo.quarter}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;

      const submission = await Form16aSubmission.create({
        requestId,
        dealerCode,
        form16aNumber,
        financialYear: demo.fy,
        quarter: demo.quarter,
        version: 1,
        tdsAmount: demo.tds,
        totalAmount: demo.total,
        tanNumber: 'BLRE00001E',
        deductorName: demo.deductor,
        documentUrl: 'https://example.com/demo-form16a.pdf',
        status: 'pending',
        submittedDate: now,
      });

      // Activity: dealer submitted Form 16
      await Activity.create({
        requestId,
        userId: form16InitiatorId,
        userName: (dealerUser as any).displayName || (dealerUser as any).firstName + ' ' + (dealerUser as any).lastName || 'Dealer',
        activityType: 'FORM_16_SUBMITTED',
        activityDescription: `Dealer submitted Form 16A for ${demo.fy} ${demo.quarter}. Certificate: ${form16aNumber}.`,
        activityCategory: 'submission',
        isSystemEvent: false,
      });

      // Document: attached Form 16 (placeholder so Docs tab shows an entry)
      await Document.create({
        requestId,
        uploadedBy: form16InitiatorId,
        fileName: `form16a-${demo.quarter}.pdf`,
        originalFileName: `Form16A_${demo.fy}_${demo.quarter}.pdf`,
        fileType: 'application/pdf',
        fileExtension: 'pdf',
        fileSize: 1024,
        filePath: `form16-demo/${requestId}/form16a.pdf`,
        mimeType: 'application/pdf',
        checksum: 'demo-checksum-' + requestId.slice(0, 8),
        isGoogleDoc: false,
        category: 'SUPPORTING',
        version: 1,
        isDeleted: false,
        downloadCount: 0,
        uploadedAt: now,
      });

      if (demo.withCreditNote && demo.cnAmount != null) {
        const creditNote = await Form16CreditNote.create({
          submissionId: submission.id,
          creditNoteNumber: `DEMO-CN-${demo.quarter}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
          sapDocumentNumber: `SAP-${demo.quarter}-DEMO`,
          amount: demo.cnAmount,
          issueDate: now.toISOString().slice(0, 10) as unknown as Date,
          financialYear: demo.fy,
          quarter: demo.quarter,
          status: demo.withdrawn ? 'withdrawn' : 'issued',
          issuedBy: adminUser?.userId,
          createdAt: now,
          updatedAt: now,
        });
        await Activity.create({
          requestId,
          userId: adminUser?.userId ?? undefined,
          userName: 'RE Admin',
          activityType: demo.withdrawn ? 'CREDIT_NOTE_WITHDRAWN' : 'CREDIT_NOTE_ISSUED',
          activityDescription: demo.withdrawn
            ? `Credit note ${creditNote.creditNoteNumber} was withdrawn by RE user.`
            : `Credit note ${creditNote.creditNoteNumber} generated for ${demo.fy} ${demo.quarter}.`,
          activityCategory: 'workflow',
          isSystemEvent: false,
        });
      }
    }
  }

  logger.info('[Seed Demo] Demo requests, Form 16 submissions, and non-submitted dealers demo data created successfully.');
}

if (require.main === module) {
  sequelize
    .authenticate()
    .then(() => seedDemoRequests())
    .then(() => process.exit(0))
    .catch((err) => {
      logger.error('[Seed Demo] Failed:', err);
      process.exit(1);
    });
}

export { seedDemoRequests, ensureDemoNonSubmittedDealers };
