// IRU Offering Service
// Management of IRU offerings in the marketplace

import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { DbisError, ErrorCode } from '@/shared/types';

export interface CreateOfferingRequest {
  name: string;
  description?: string;
  capacityTier: number;
  institutionalType: string;
  pricingModel: string;
  basePrice?: number;
  currency?: string;
  features?: any;
  technicalSpecs?: any;
  legalFramework?: any;
  regulatoryPosition?: any;
  documents?: any;
  displayOrder?: number;
}

export interface UpdateOfferingRequest {
  name?: string;
  description?: string;
  pricingModel?: string;
  basePrice?: number;
  features?: any;
  technicalSpecs?: any;
  legalFramework?: any;
  regulatoryPosition?: any;
  documents?: any;
  status?: string;
  displayOrder?: number;
}

export class OfferingService {
  /**
   * Create new IRU offering
   */
  async createOffering(request: CreateOfferingRequest): Promise<any> {
    const offeringId = `IRU-OFF-${uuidv4().substring(0, 8).toUpperCase()}`;

    const offering = await prisma.iruOffering.create({
      data: {
        id: uuidv4(),
        offeringId,
        name: request.name,
        description: request.description,
        capacityTier: request.capacityTier,
        institutionalType: request.institutionalType,
        pricingModel: request.pricingModel,
        basePrice: request.basePrice,
        currency: request.currency || 'USD',
        features: request.features,
        technicalSpecs: request.technicalSpecs,
        legalFramework: request.legalFramework,
        regulatoryPosition: request.regulatoryPosition,
        documents: request.documents,
        status: 'active',
        displayOrder: request.displayOrder || 0,
      },
    });

    return {
      id: offering.id,
      offeringId: offering.offeringId,
      name: offering.name,
      description: offering.description,
      capacityTier: offering.capacityTier,
      institutionalType: offering.institutionalType,
      pricingModel: offering.pricingModel,
      basePrice: offering.basePrice ? Number(offering.basePrice) : undefined,
      currency: offering.currency,
      features: offering.features,
      technicalSpecs: offering.technicalSpecs,
      legalFramework: offering.legalFramework,
      regulatoryPosition: offering.regulatoryPosition,
      documents: offering.documents,
      status: offering.status,
      displayOrder: offering.displayOrder,
    };
  }

  /**
   * Update IRU offering
   */
  async updateOffering(offeringId: string, request: UpdateOfferingRequest): Promise<any> {
    const offering = await prisma.iruOffering.findUnique({
      where: { offeringId },
    });

    if (!offering) {
      throw new DbisError(ErrorCode.NOT_FOUND, `Offering ${offeringId} not found`);
    }

    const updated = await prisma.iruOffering.update({
      where: { offeringId },
      data: {
        name: request.name,
        description: request.description,
        pricingModel: request.pricingModel,
        basePrice: request.basePrice,
        features: request.features,
        technicalSpecs: request.technicalSpecs,
        legalFramework: request.legalFramework,
        regulatoryPosition: request.regulatoryPosition,
        documents: request.documents,
        status: request.status,
        displayOrder: request.displayOrder,
        updatedAt: new Date(),
      },
    });

    return {
      id: updated.id,
      offeringId: updated.offeringId,
      name: updated.name,
      description: updated.description,
      capacityTier: updated.capacityTier,
      institutionalType: updated.institutionalType,
      pricingModel: updated.pricingModel,
      basePrice: updated.basePrice ? Number(updated.basePrice) : undefined,
      currency: updated.currency,
      features: updated.features,
      technicalSpecs: updated.technicalSpecs,
      legalFramework: updated.legalFramework,
      regulatoryPosition: updated.regulatoryPosition,
      documents: updated.documents,
      status: updated.status,
      displayOrder: updated.displayOrder,
    };
  }

  /**
   * Delete IRU offering (soft delete by setting status to inactive)
   */
  async deleteOffering(offeringId: string): Promise<void> {
    const offering = await prisma.iruOffering.findUnique({
      where: { offeringId },
    });

    if (!offering) {
      throw new DbisError(ErrorCode.NOT_FOUND, `Offering ${offeringId} not found`);
    }

    // Check for active subscriptions
    const activeSubscriptions = await prisma.iruSubscription.count({
      where: {
        offeringId: offering.id,
        subscriptionStatus: 'active',
      },
    });

    if (activeSubscriptions > 0) {
      throw new DbisError(
        ErrorCode.VALIDATION_ERROR,
        `Cannot delete offering with ${activeSubscriptions} active subscriptions`
      );
    }

    await prisma.iruOffering.update({
      where: { offeringId },
      data: {
        status: 'inactive',
        updatedAt: new Date(),
      },
    });
  }

  /**
   * Get offering statistics
   */
  async getOfferingStats(offeringId: string): Promise<any> {
    const offering = await prisma.iruOffering.findUnique({
      where: { offeringId },
      include: {
        _count: {
          select: {
            inquiries: true,
            subscriptions: true,
          },
        },
      },
    });

    if (!offering) {
      throw new DbisError(ErrorCode.NOT_FOUND, `Offering ${offeringId} not found`);
    }

    const activeSubscriptions = await prisma.iruSubscription.count({
      where: {
        offeringId: offering.id,
        subscriptionStatus: 'active',
      },
    });

    const pendingInquiries = await prisma.iruInquiry.count({
      where: {
        offeringId: offering.id,
        status: {
          in: ['submitted', 'acknowledged', 'in_review'],
        },
      },
    });

    return {
      offeringId: offering.offeringId,
      name: offering.name,
      totalInquiries: offering._count.inquiries,
      totalSubscriptions: offering._count.subscriptions,
      activeSubscriptions,
      pendingInquiries,
    };
  }
}

export const offeringService = new OfferingService();
