import type { Knex } from 'knex';
import * as bcrypt from 'bcrypt';
import { v4 as uuidv4 } from 'uuid';
import { ethers } from 'ethers';
import * as crypto from 'crypto';

// Simple encryption for demo purposes (in production use proper key management)
const ENCRYPTION_KEY = process.env.WALLET_ENCRYPTION_KEY || 'goa-gel-demo-encryption-key-32b';

function encryptPrivateKey(privateKey: string): string {
  const iv = crypto.randomBytes(16);
  const key = crypto.scryptSync(ENCRYPTION_KEY, 'salt', 32);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let encrypted = cipher.update(privateKey, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return iv.toString('hex') + ':' + encrypted;
}

function generateWallet(): { address: string; encryptedPrivateKey: string } {
  const wallet = ethers.Wallet.createRandom();
  return {
    address: wallet.address,
    encryptedPrivateKey: encryptPrivateKey(wallet.privateKey),
  };
}

export async function seed(knex: Knex): Promise<void> {
  // Clear existing data (in reverse order of dependencies)
  await knex('application_logs').del().catch(() => {});
  await knex('blockchain_events').del().catch(() => {});
  await knex('wallets').del().catch(() => {});
  await knex('users').del().catch(() => {});
  await knex('approvals').del();
  await knex('workflow_states').del();
  await knex('document_versions').del();
  await knex('documents').del();
  await knex('license_requests').del();
  await knex('webhooks').del();
  await knex('workflows').del();
  await knex('departments').del();
  await knex('applicants').del();

  // Generate wallets for departments
  const fireDeptWallet = generateWallet();
  const tourismDeptWallet = generateWallet();
  const municipalityWallet = generateWallet();
  const healthDeptWallet = generateWallet();

  // Create departments with IDs we can reference
  const fireDeptId = uuidv4();
  const tourismDeptId = uuidv4();
  const municipalityId = uuidv4();
  const healthDeptId = uuidv4();

  const departments = [
    {
      id: fireDeptId,
      code: 'FIRE_DEPT',
      name: 'Fire & Emergency Services Department',
      wallet_address: fireDeptWallet.address,
      api_key_hash: await bcrypt.hash('fire_api_key_123', 10),
      api_secret_hash: await bcrypt.hash('fire_secret_456', 10),
      is_active: true,
      description: 'Responsible for fire safety inspections and certifications',
      contact_email: 'fire@goa.gov.in',
      contact_phone: '+91-832-2222222',
    },
    {
      id: tourismDeptId,
      code: 'TOURISM_DEPT',
      name: 'Department of Tourism',
      wallet_address: tourismDeptWallet.address,
      api_key_hash: await bcrypt.hash('tourism_api_key_123', 10),
      api_secret_hash: await bcrypt.hash('tourism_secret_456', 10),
      is_active: true,
      description: 'Manages tourism licenses and hospitality registrations',
      contact_email: 'tourism@goa.gov.in',
      contact_phone: '+91-832-3333333',
    },
    {
      id: municipalityId,
      code: 'MUNICIPALITY',
      name: 'Municipal Corporation of Panaji',
      wallet_address: municipalityWallet.address,
      api_key_hash: await bcrypt.hash('municipality_api_key_123', 10),
      api_secret_hash: await bcrypt.hash('municipality_secret_456', 10),
      is_active: true,
      description: 'Local governance and building permits',
      contact_email: 'municipality@goa.gov.in',
      contact_phone: '+91-832-4444444',
    },
    {
      id: healthDeptId,
      code: 'HEALTH_DEPT',
      name: 'Directorate of Health Services',
      wallet_address: healthDeptWallet.address,
      api_key_hash: await bcrypt.hash('health_api_key_123', 10),
      api_secret_hash: await bcrypt.hash('health_secret_456', 10),
      is_active: true,
      description: 'Health and sanitation inspections',
      contact_email: 'health@goa.gov.in',
      contact_phone: '+91-832-5555555',
    },
  ];

  await knex('departments').insert(departments);

  // Store department wallets
  const departmentWallets = [
    { ...fireDeptWallet, id: uuidv4(), owner_type: 'DEPARTMENT', owner_id: fireDeptId, is_active: true },
    { ...tourismDeptWallet, id: uuidv4(), owner_type: 'DEPARTMENT', owner_id: tourismDeptId, is_active: true },
    { ...municipalityWallet, id: uuidv4(), owner_type: 'DEPARTMENT', owner_id: municipalityId, is_active: true },
    { ...healthDeptWallet, id: uuidv4(), owner_type: 'DEPARTMENT', owner_id: healthDeptId, is_active: true },
  ].map(w => ({
    id: w.id,
    address: w.address,
    encrypted_private_key: w.encryptedPrivateKey,
    owner_type: w.owner_type,
    owner_id: w.owner_id,
    is_active: w.is_active,
  }));

  await knex('wallets').insert(departmentWallets);

  // Generate wallets for demo users
  const adminWallet = generateWallet();
  const fireUserWallet = generateWallet();
  const tourismUserWallet = generateWallet();
  const municipalityUserWallet = generateWallet();
  const citizenWallet = generateWallet();
  const secondCitizenWallet = generateWallet();

  // Create demo users with specified credentials
  const adminUserId = uuidv4();
  const fireUserId = uuidv4();
  const tourismUserId = uuidv4();
  const municipalityUserId = uuidv4();
  const citizenUserId = uuidv4();
  const secondCitizenUserId = uuidv4();

  const users = [
    {
      id: adminUserId,
      email: 'admin@goa.gov.in',
      password_hash: await bcrypt.hash('Admin@123', 10),
      name: 'System Administrator',
      role: 'ADMIN',
      department_id: null,
      wallet_address: adminWallet.address,
      wallet_encrypted_key: adminWallet.encryptedPrivateKey,
      phone: '+91-9876543210',
      is_active: true,
    },
    {
      id: fireUserId,
      email: 'fire@goa.gov.in',
      password_hash: await bcrypt.hash('Fire@123', 10),
      name: 'Fire Department Officer',
      role: 'DEPARTMENT',
      department_id: fireDeptId,
      wallet_address: fireUserWallet.address,
      wallet_encrypted_key: fireUserWallet.encryptedPrivateKey,
      phone: '+91-9876543211',
      is_active: true,
    },
    {
      id: tourismUserId,
      email: 'tourism@goa.gov.in',
      password_hash: await bcrypt.hash('Tourism@123', 10),
      name: 'Tourism Department Officer',
      role: 'DEPARTMENT',
      department_id: tourismDeptId,
      wallet_address: tourismUserWallet.address,
      wallet_encrypted_key: tourismUserWallet.encryptedPrivateKey,
      phone: '+91-9876543212',
      is_active: true,
    },
    {
      id: municipalityUserId,
      email: 'municipality@goa.gov.in',
      password_hash: await bcrypt.hash('Municipality@123', 10),
      name: 'Municipality Officer',
      role: 'DEPARTMENT',
      department_id: municipalityId,
      wallet_address: municipalityUserWallet.address,
      wallet_encrypted_key: municipalityUserWallet.encryptedPrivateKey,
      phone: '+91-9876543213',
      is_active: true,
    },
    {
      id: citizenUserId,
      email: 'citizen@example.com',
      password_hash: await bcrypt.hash('Citizen@123', 10),
      name: 'Demo Citizen',
      role: 'CITIZEN',
      department_id: null,
      wallet_address: citizenWallet.address,
      wallet_encrypted_key: citizenWallet.encryptedPrivateKey,
      phone: '+91-9876543214',
      is_active: true,
    },
    {
      id: secondCitizenUserId,
      email: 'citizen2@example.com',
      password_hash: await bcrypt.hash('Citizen@123', 10),
      name: 'Second Citizen',
      role: 'CITIZEN',
      department_id: null,
      wallet_address: secondCitizenWallet.address,
      wallet_encrypted_key: secondCitizenWallet.encryptedPrivateKey,
      phone: '+91-9876543215',
      is_active: true,
    },
  ];

  await knex('users').insert(users);

  // Store user wallets
  const userWallets = [
    { ...adminWallet, id: uuidv4(), owner_type: 'USER', owner_id: adminUserId, is_active: true },
    { ...fireUserWallet, id: uuidv4(), owner_type: 'USER', owner_id: fireUserId, is_active: true },
    { ...tourismUserWallet, id: uuidv4(), owner_type: 'USER', owner_id: tourismUserId, is_active: true },
    { ...municipalityUserWallet, id: uuidv4(), owner_type: 'USER', owner_id: municipalityUserId, is_active: true },
    { ...citizenWallet, id: uuidv4(), owner_type: 'USER', owner_id: citizenUserId, is_active: true },
    { ...secondCitizenWallet, id: uuidv4(), owner_type: 'USER', owner_id: secondCitizenUserId, is_active: true },
  ].map(w => ({
    id: w.id,
    address: w.address,
    encrypted_private_key: w.encryptedPrivateKey,
    owner_type: w.owner_type,
    owner_id: w.owner_id,
    is_active: w.is_active,
  }));

  await knex('wallets').insert(userWallets);

  // Create sample workflow for Resort License
  const workflowId = uuidv4();
  await knex('workflows').insert({
    id: workflowId,
    workflow_type: 'RESORT_LICENSE',
    name: 'Resort License Approval Workflow',
    description: 'Multi-department approval workflow for resort licenses in Goa',
    version: 1,
    definition: JSON.stringify({
      isActive: true,
      stages: [
        {
          stageId: 'stage_1_fire',
          stageName: 'Fire Safety Review',
          stageOrder: 1,
          executionType: 'SEQUENTIAL',
          requiredApprovals: [
            {
              departmentCode: 'FIRE_DEPT',
              departmentName: 'Fire & Emergency Services Department',
              requiredDocuments: ['FIRE_SAFETY_CERTIFICATE', 'BUILDING_PLAN'],
              isMandatory: true,
            },
          ],
          completionCriteria: 'ALL',
          timeoutDays: 7,
          onTimeout: 'NOTIFY',
          onRejection: 'FAIL_REQUEST',
        },
        {
          stageId: 'stage_2_parallel',
          stageName: 'Tourism & Municipality Review',
          stageOrder: 2,
          executionType: 'PARALLEL',
          requiredApprovals: [
            {
              departmentCode: 'TOURISM_DEPT',
              departmentName: 'Department of Tourism',
              requiredDocuments: ['PROPERTY_OWNERSHIP', 'BUILDING_PLAN'],
              isMandatory: true,
            },
            {
              departmentCode: 'MUNICIPALITY',
              departmentName: 'Municipal Corporation of Panaji',
              requiredDocuments: ['PROPERTY_OWNERSHIP', 'TAX_CLEARANCE'],
              isMandatory: true,
            },
          ],
          completionCriteria: 'ALL',
          timeoutDays: 14,
          onTimeout: 'ESCALATE',
          onRejection: 'FAIL_REQUEST',
        },
        {
          stageId: 'stage_3_health',
          stageName: 'Health & Sanitation Review',
          stageOrder: 3,
          executionType: 'SEQUENTIAL',
          requiredApprovals: [
            {
              departmentCode: 'HEALTH_DEPT',
              departmentName: 'Directorate of Health Services',
              requiredDocuments: ['HEALTH_CERTIFICATE'],
              isMandatory: true,
            },
          ],
          completionCriteria: 'ALL',
          timeoutDays: 7,
          onTimeout: 'NOTIFY',
          onRejection: 'FAIL_REQUEST',
        },
      ],
    }),
    is_active: true,
  });

  // Create FIRE_SAFETY_CERT workflow for tests
  const fireSafetyCertWorkflowId = uuidv4();
  await knex('workflows').insert({
    id: fireSafetyCertWorkflowId,
    workflow_type: 'FIRE_SAFETY_CERT',
    name: 'Fire Safety Certificate Workflow',
    description: 'Simplified fire safety certificate approval workflow',
    version: 1,
    definition: JSON.stringify({
      isActive: true,
      stages: [
        {
          stageId: 'stage_1_fire',
          stageName: 'Fire Safety Review',
          stageOrder: 1,
          executionType: 'SEQUENTIAL',
          requiredApprovals: [
            {
              departmentCode: 'FIRE_DEPT',
              departmentName: 'Fire & Emergency Services Department',
              requiredDocuments: ['FIRE_SAFETY_CERTIFICATE', 'BUILDING_PLAN'],
              isMandatory: true,
            },
          ],
          completionCriteria: 'ALL',
          timeoutDays: 7,
          onTimeout: 'NOTIFY',
          onRejection: 'FAIL_REQUEST',
        },
        {
          stageId: 'stage_2_health',
          stageName: 'Health & Safety Review',
          stageOrder: 2,
          executionType: 'SEQUENTIAL',
          requiredApprovals: [
            {
              departmentCode: 'HEALTH_DEPT',
              departmentName: 'Directorate of Health Services',
              requiredDocuments: ['HEALTH_CERTIFICATE'],
              isMandatory: true,
            },
          ],
          completionCriteria: 'ALL',
          timeoutDays: 7,
          onTimeout: 'NOTIFY',
          onRejection: 'FAIL_REQUEST',
        },
      ],
    }),
    is_active: true,
  });

  // Create sample applicants (linked to citizen users)
  await knex('applicants').insert([
    {
      id: citizenUserId, // Use same ID for linking
      digilocker_id: 'DL-GOA-CITIZEN-001',
      name: 'Demo Citizen',
      email: 'citizen@example.com',
      phone: '+91-9876543214',
      wallet_address: citizenWallet.address,
      is_active: true,
    },
    {
      id: secondCitizenUserId, // Use same ID for linking
      digilocker_id: 'DL-GOA-CITIZEN-002',
      name: 'Second Citizen',
      email: 'citizen2@example.com',
      phone: '+91-9876543215',
      wallet_address: secondCitizenWallet.address,
      is_active: true,
    },
  ]);

  console.log('Seed data inserted successfully!');
  console.log('');
  console.log('Demo Accounts Created:');
  console.log('─────────────────────────────────────────');
  console.log('Admin:        admin@goa.gov.in / Admin@123');
  console.log('Fire Dept:    fire@goa.gov.in / Fire@123');
  console.log('Tourism:      tourism@goa.gov.in / Tourism@123');
  console.log('Municipality: municipality@goa.gov.in / Municipality@123');
  console.log('Citizen 1:    citizen@example.com / Citizen@123');
  console.log('Citizen 2:    citizen2@example.com / Citizen@123');
  console.log('─────────────────────────────────────────');
  console.log('Departments:', departments.length);
  console.log('Users:', users.length);
  console.log('Wallets:', departmentWallets.length + userWallets.length);
  console.log('Workflow created: RESORT_LICENSE');
}
