// Metaverse & Holographic Bonds Service
// ALB and holographic certificates

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


export interface IssueAvatarLinkedBondRequest {
  bondName: string;
  principalAmount: string;
  avatarId: string;
  metaverseNodeId?: string;
  digitalIdentityId: string;
  metaverseAssetPortfolio?: Record<string, any>;
  maturityYears: number;
  couponRate: string;
}

export interface IssueHolographicBondRequest {
  bondName: string;
  principalAmount: string;
  holographicEconomyId: string;
  simulatedEconomyId?: string;
  certificateHash: string;
  holographicData?: Record<string, any>;
  maturityYears: number;
  couponRate: string;
}

export class MetaverseBondsService {
  /**
   * Issue avatar-linked bond
   */
  async issueAvatarLinkedBond(request: IssueAvatarLinkedBondRequest): Promise<string> {
    logger.info('GRU: Issuing avatar-linked bond', { request });

    const bondId = `ALB-${uuidv4()}`;
    const maturityDate = new Date();
    maturityDate.setFullYear(maturityDate.getFullYear() + request.maturityYears);

    const bond = await prisma.avatarLinkedBond.create({
      data: {
        bondId,
        bondName: request.bondName,
        principalAmount: new Decimal(request.principalAmount),
        avatarId: request.avatarId,
        metaverseNodeId: request.metaverseNodeId,
        digitalIdentityId: request.digitalIdentityId,
        metaverseAssetPortfolio: request.metaverseAssetPortfolio
          ? JSON.stringify(request.metaverseAssetPortfolio)
          : null,
        maturityDate,
        couponRate: new Decimal(request.couponRate),
        status: 'active',
        issuedAt: new Date(),
      },
    });

    logger.info('GRU: Avatar-linked bond issued', { bondId });

    return bondId;
  }

  /**
   * Issue holographic bond
   */
  async issueHolographicBond(request: IssueHolographicBondRequest): Promise<string> {
    logger.info('GRU: Issuing holographic bond', { request });

    const bondId = `HOLO-${uuidv4()}`;
    const maturityDate = new Date();
    maturityDate.setFullYear(maturityDate.getFullYear() + request.maturityYears);

    const bond = await prisma.holographicBond.create({
      data: {
        bondId,
        bondName: request.bondName,
        principalAmount: new Decimal(request.principalAmount),
        holographicEconomyId: request.holographicEconomyId,
        simulatedEconomyId: request.simulatedEconomyId,
        certificateHash: request.certificateHash,
        holographicData: request.holographicData ? JSON.stringify(request.holographicData) : null,
        maturityDate,
        couponRate: new Decimal(request.couponRate),
        status: 'active',
        issuedAt: new Date(),
      },
    });

    logger.info('GRU: Holographic bond issued', { bondId });

    return bondId;
  }

  /**
   * Pay avatar bond coupon
   */
  async payAvatarBondCoupon(bondId: string): Promise<string> {
    const bond = await prisma.avatarLinkedBond.findUnique({
      where: { bondId },
    });

    if (!bond || bond.status !== 'active') {
      throw new Error(`Bond not found or not active: ${bondId}`);
    }

    const couponAmount = bond.principalAmount.times(bond.couponRate);
    const couponId = `COUPON-${uuidv4()}`;

    await prisma.avatarBondCoupon.create({
      data: {
        couponId,
        bondId,
        couponAmount,
        paymentDate: new Date(),
        status: 'paid',
        paidAt: new Date(),
      },
    });

    logger.info('GRU: Avatar bond coupon paid', { bondId });

    return couponId;
  }

  /**
   * Pay holographic bond coupon
   */
  async payHolographicBondCoupon(bondId: string): Promise<string> {
    const bond = await prisma.holographicBond.findUnique({
      where: { bondId },
    });

    if (!bond || bond.status !== 'active') {
      throw new Error(`Bond not found or not active: ${bondId}`);
    }

    const couponAmount = bond.principalAmount.times(bond.couponRate);
    const couponId = `COUPON-${uuidv4()}`;

    await prisma.holographicBondCoupon.create({
      data: {
        couponId,
        bondId,
        couponAmount,
        paymentDate: new Date(),
        status: 'paid',
        paidAt: new Date(),
      },
    });

    logger.info('GRU: Holographic bond coupon paid', { bondId });

    return couponId;
  }

  /**
   * Get avatar-linked bond
   */
  async getAvatarLinkedBond(bondId: string) {
    return await prisma.avatarLinkedBond.findUnique({
      where: { bondId },
      include: {
        coupons: {
          orderBy: { paymentDate: 'desc' },
        },
      },
    });
  }

  /**
   * Get holographic bond
   */
  async getHolographicBond(bondId: string) {
    return await prisma.holographicBond.findUnique({
      where: { bondId },
      include: {
        coupons: {
          orderBy: { paymentDate: 'desc' },
        },
      },
    });
  }

  /**
   * Get avatar-linked bonds by avatar
   */
  async getBondsByAvatar(avatarId: string) {
    return await prisma.avatarLinkedBond.findMany({
      where: { avatarId },
      orderBy: { issuedAt: 'desc' },
      include: {
        coupons: true,
      },
    });
  }

  /**
   * Get holographic bonds by economy
   */
  async getBondsByEconomy(holographicEconomyId: string) {
    return await prisma.holographicBond.findMany({
      where: { holographicEconomyId },
      orderBy: { issuedAt: 'desc' },
      include: {
        coupons: true,
      },
    });
  }
}

export const metaverseBondsService = new MetaverseBondsService();

