// Agreement Generator Service
// Dynamic IRU agreement generation

import { templateEngine } from './template-engine.service';
import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { DbisError, ErrorCode } from '@/shared/types';
import fs from 'fs/promises';
import path from 'path';

export interface GenerateAgreementRequest {
  subscriptionId: string;
  templateId?: string;
  variables?: Record<string, any>;
}

export interface GeneratedAgreement {
  agreementId: string;
  subscriptionId: string;
  agreementContent: string;
  variables: Record<string, any>;
  status: string;
}

export class AgreementGenerator {
  /**
   * Generate IRU agreement
   */
  async generateAgreement(request: GenerateAgreementRequest): Promise<GeneratedAgreement> {
    const subscription = await prisma.iruSubscription.findUnique({
      where: { subscriptionId: request.subscriptionId },
      include: {
        offering: true,
        inquiry: true,
      },
    });

    if (!subscription) {
      throw new DbisError(ErrorCode.NOT_FOUND, `Subscription ${request.subscriptionId} not found`);
    }

    // Determine template based on capacity tier
    const templateId = request.templateId || `tier-${subscription.offering.capacityTier}`;

    // Prepare variables
    const variables = {
      ...request.variables,
      participantName: subscription.organizationName,
      capacityTier: subscription.capacityTier,
      institutionalType: subscription.offering.institutionalType,
      jurisdiction: subscription.inquiry?.jurisdiction || 'Not specified',
      subscriptionDate: subscription.subscriptionDate.toISOString(),
      iruGrantFee: subscription.iruGrantFee?.toString() || 'TBD',
      ...this.getDefaultVariables(subscription),
    };

    // Load and process template
    const template = await this.loadTemplate(templateId);
    const agreementContent = await templateEngine.process(template, variables);

    // Create agreement record
    const agreementId = `AGMT-${uuidv4().substring(0, 8).toUpperCase()}`;
    const agreement = await prisma.iruAgreement.create({
      data: {
        id: uuidv4(),
        agreementId,
        subscriptionId: subscription.id,
        agreementType: 'IRU_PARTICIPATION',
        agreementVersion: '1.0',
        templateUsed: templateId,
        agreementContent,
        variables: variables as any,
        status: 'draft',
      },
    });

    return {
      agreementId: agreement.agreementId,
      subscriptionId: subscription.subscriptionId,
      agreementContent,
      variables,
      status: agreement.status,
    };
  }

  /**
   * Load agreement template
   */
  private async loadTemplate(templateId: string): Promise<string> {
    try {
      // Try to load from templates directory
      const templatePath = path.join(
        process.cwd(),
        'templates',
        'iru-agreement',
        `${templateId}.md`
      );
      return await fs.readFile(templatePath, 'utf-8');
    } catch (error) {
      // Fallback to default template
      return this.getDefaultTemplate();
    }
  }

  /**
   * Get default template
   */
  private getDefaultTemplate(): string {
    return `# IRU Participation Agreement

This Agreement is entered into between the Digital Bank of International Settlements (DBIS) and {{participantName}}.

## Part I: Grant of IRU

DBIS hereby grants to {{participantName}} an Irrevocable Right of Use (IRU) for:

1. Infrastructure IRU
2. SaaS IRU

## Part II: Capacity Tier

Participant is classified as Capacity Tier {{capacityTier}} ({{institutionalType}}).

## Part III: Term

The IRU Term shall be determined in accordance with the Law of {{jurisdiction}}.

## Part IV: Fees

IRU Grant Fee: {{currency}} {{iruGrantFee}}

[Additional agreement content...]`;
  }

  /**
   * Get default variables
   */
  private getDefaultVariables(subscription: any): Record<string, any> {
    return {
      currency: 'USD',
      date: new Date().toISOString().split('T')[0],
      year: new Date().getFullYear(),
    };
  }
}

export const agreementGenerator = new AgreementGenerator();
