// UMMC Sovereign Mapping Service
// Cross-reality sovereign identity mapping

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';


export interface CreateMappingRequest {
  sovereignBankId: string;
  realityLayer: string;
  identityAnchor: string;
  ledgerAnchor?: string;
  settlementAnchor?: string;
  divergenceBand?: string;
  pillarId?: string;
}

export interface MappingResult {
  mappingId: string;
  sovereignBankId: string;
  realityLayer: string;
  identityAnchor: string;
  divergenceBand?: string;
  status: string;
}

export class UmmcSovereignMappingService {
  /**
   * Create a sovereign mapping
   */
  async createMapping(request: CreateMappingRequest): Promise<MappingResult> {
    // Verify sovereign bank exists
    const bank = await prisma.sovereignBank.findUnique({
      where: { id: request.sovereignBankId },
    });

    if (!bank) {
      throw new Error(`Sovereign bank not found: ${request.sovereignBankId}`);
    }

    const mappingId = `UMMC-MAP-${uuidv4()}`;

    const mapping = await prisma.ummcSovereignMapping.create({
      data: {
        mappingId,
        sovereignBankId: request.sovereignBankId,
        realityLayer: request.realityLayer,
        identityAnchor: request.identityAnchor,
        ledgerAnchor: request.ledgerAnchor || null,
        settlementAnchor: request.settlementAnchor || null,
        divergenceBand: request.divergenceBand
          ? new Decimal(request.divergenceBand)
          : null,
        pillarId: request.pillarId || null,
        status: 'active',
      },
    });

    return {
      mappingId: mapping.mappingId,
      sovereignBankId: mapping.sovereignBankId,
      realityLayer: mapping.realityLayer,
      identityAnchor: mapping.identityAnchor,
      divergenceBand: mapping.divergenceBand?.toString(),
      status: mapping.status,
    };
  }

  /**
   * Get all mappings for a sovereign bank
   */
  async getMappingsBySovereign(
    sovereignBankId: string
  ): Promise<MappingResult[]> {
    const mappings = await prisma.ummcSovereignMapping.findMany({
      where: {
        sovereignBankId,
        status: 'active',
      },
      include: {
        pillar: true,
      },
      orderBy: { realityLayer: 'asc' },
    });

    return mappings.map((mapping) => ({
      mappingId: mapping.mappingId,
      sovereignBankId: mapping.sovereignBankId,
      realityLayer: mapping.realityLayer,
      identityAnchor: mapping.identityAnchor,
      divergenceBand: mapping.divergenceBand?.toString(),
      status: mapping.status,
    }));
  }

  /**
   * Get mapping by reality layer
   */
  async getMappingByReality(
    sovereignBankId: string,
    realityLayer: string
  ): Promise<MappingResult | null> {
    const mapping = await prisma.ummcSovereignMapping.findFirst({
      where: {
        sovereignBankId,
        realityLayer,
        status: 'active',
      },
      include: {
        pillar: true,
      },
    });

    if (!mapping) {
      return null;
    }

    return {
      mappingId: mapping.mappingId,
      sovereignBankId: mapping.sovereignBankId,
      realityLayer: mapping.realityLayer,
      identityAnchor: mapping.identityAnchor,
      divergenceBand: mapping.divergenceBand?.toString(),
      status: mapping.status,
    };
  }

  /**
   * Check divergence compliance
   */
  async checkDivergence(
    sovereignBankId: string,
    realityLayer: string,
    currentDivergence: string
  ): Promise<{
    compliant: boolean;
    allowedDivergence?: string;
    currentDivergence: string;
  }> {
    const mapping = await prisma.ummcSovereignMapping.findFirst({
      where: {
        sovereignBankId,
        realityLayer,
        status: 'active',
      },
    });

    if (!mapping || !mapping.divergenceBand) {
      return {
        compliant: true,
        currentDivergence,
      };
    }

    const divergence = new Decimal(currentDivergence);
    const band = mapping.divergenceBand;

    return {
      compliant: divergence.lessThanOrEqualTo(band),
      allowedDivergence: band.toString(),
      currentDivergence,
    };
  }

  /**
   * Update mapping
   */
  async updateMapping(
    mappingId: string,
    updates: Partial<CreateMappingRequest>
  ): Promise<MappingResult> {
    const updateData: any = {};

    if (updates.identityAnchor) {
      updateData.identityAnchor = updates.identityAnchor;
    }
    if (updates.ledgerAnchor !== undefined) {
      updateData.ledgerAnchor = updates.ledgerAnchor || null;
    }
    if (updates.settlementAnchor !== undefined) {
      updateData.settlementAnchor = updates.settlementAnchor || null;
    }
    if (updates.divergenceBand !== undefined) {
      updateData.divergenceBand = updates.divergenceBand
        ? new Decimal(updates.divergenceBand)
        : null;
    }
    if (updates.pillarId !== undefined) {
      updateData.pillarId = updates.pillarId || null;
    }

    const mapping = await prisma.ummcSovereignMapping.update({
      where: { mappingId },
      data: updateData,
    });

    return {
      mappingId: mapping.mappingId,
      sovereignBankId: mapping.sovereignBankId,
      realityLayer: mapping.realityLayer,
      identityAnchor: mapping.identityAnchor,
      divergenceBand: mapping.divergenceBand?.toString(),
      status: mapping.status,
    };
  }

  /**
   * Suspend mapping
   */
  async suspendMapping(mappingId: string): Promise<void> {
    await prisma.ummcSovereignMapping.update({
      where: { mappingId },
      data: { status: 'suspended' },
    });
  }
}

