// DBIS Omni-Sovereign Settlement Matrix - Coordination Service
// Multi-reality settlement coordination

import prisma from '@/shared/database/prisma';
import { ossmMatrixService } from './ossm-matrix.service';
import { ossmSettlementService } from './ossm-settlement.service';
import { ossmMergeService } from './ossm-merge.service';


export class OssmCoordinationService {
  /**
   * Coordinate settlement across all realities
   */
  async coordinateSettlement(matrixId: string) {
    const matrix = await ossmMatrixService.getMatrix(matrixId);
    if (!matrix) {
      throw new Error(`Matrix not found: ${matrixId}`);
    }

    const coordinates = await ossmSettlementService.getCoordinatesByMatrix(matrixId);
    const layerStates = await ossmMergeService.getMergedStates(matrixId);

    // Synchronize all coordinates
    const syncResults = await Promise.all(
      coordinates.map((coord) =>
        ossmSettlementService.synchronizeCoordinate(coord.coordinateId).catch((err) => ({
          coordinateId: coord.coordinateId,
          error: err.message,
        }))
      )
    );

    // Check for conflicts
    const conflicts = coordinates.filter((c) => c.settlementStatus === 'conflicted');
    const conflictedStates = layerStates.filter((s) => s.syncStatus === 'conflicted');

    return {
      matrixId,
      totalCoordinates: coordinates.length,
      synchronized: syncResults.filter((r) => !('error' in r)).length,
      failed: syncResults.filter((r) => 'error' in r).length,
      conflicts: {
        coordinates: conflicts.length,
        states: conflictedStates.length,
      },
      layerStates: layerStates.length,
    };
  }

  /**
   * Get coordination status
   */
  async getCoordinationStatus(matrixId: string) {
    const matrix = await ossmMatrixService.getMatrix(matrixId);
    if (!matrix) {
      throw new Error(`Matrix not found: ${matrixId}`);
    }

    const coordinates = await ossmSettlementService.getCoordinatesByMatrix(matrixId);
    const layerStates = await ossmMergeService.getMergedStates(matrixId);

    const statusCounts = {
      pending: coordinates.filter((c) => c.settlementStatus === 'pending').length,
      synchronized: coordinates.filter((c) => c.settlementStatus === 'synchronized').length,
      conflicted: coordinates.filter((c) => c.settlementStatus === 'conflicted').length,
    };

    const layerStatusCounts = {
      synced: layerStates.filter((s) => s.syncStatus === 'synced').length,
      conflicted: layerStates.filter((s) => s.syncStatus === 'conflicted').length,
      pending: layerStates.filter((s) => s.syncStatus === 'pending').length,
    };

    return {
      matrixId,
      matrixName: matrix.matrixName,
      dimensions: matrix.dimensions.length,
      coordinates: {
        total: coordinates.length,
        byStatus: statusCounts,
      },
      layerStates: {
        total: layerStates.length,
        byStatus: layerStatusCounts,
        realities: layerStates.map((s) => s.realityLayer),
      },
    };
  }

  /**
   * Resolve all conflicts
   */
  async resolveAllConflicts(matrixId: string) {
    const matrix = await ossmMatrixService.getMatrix(matrixId);
    if (!matrix) {
      throw new Error(`Matrix not found: ${matrixId}`);
    }

    const conflictedCoordinates = await prisma.settlementCoordinate.findMany({
      where: {
        matrixId,
        settlementStatus: 'conflicted',
      },
    });

    const conflictedStates = await prisma.realityLayerState.findMany({
      where: {
        matrixId,
        syncStatus: 'conflicted',
      },
    });

    // In production, this would use conflict resolution logic
    // For now, mark as resolved manually
    const resolvedCoordinates = await Promise.all(
      conflictedCoordinates.map((coord) =>
        ossmSettlementService.synchronizeCoordinate(coord.coordinateId)
      )
    );

    return {
      resolvedCoordinates: resolvedCoordinates.length,
      conflictedStates: conflictedStates.length,
      message: 'Conflicts resolved (manual resolution required in production)',
    };
  }
}

export const ossmCoordinationService = new OssmCoordinationService();

