// Enhanced Asset Tokenization Service
// Supports all token classes: Virtual Land, Avatar Assets, Business Licenses, Event Rights, Data Ownership, AI Companion
// Supplement B: MetaverseDubai Integration Framework

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';
import { tokenClassManagerService } from './token-class-manager.service';


export interface TokenizeAssetRequest {
  metaverseNodeId: string;
  assetName: string;
  assetType: string;
  tokenClass:
    | 'virtual_land'
    | 'avatar_asset'
    | 'business_license'
    | 'event_rights'
    | 'data_ownership'
    | 'ai_companion';
  ownerAvatarId?: string;
  value?: string;
  currencyCode?: string;
  businessLicenseId?: string;
  eventRights?: Record<string, unknown>;
  dataOwnershipTokenId?: string;
  aiCompanionId?: string;
  metadata?: Record<string, unknown>;
}

export interface TokenizeAssetResult {
  assetId: string;
  tokenId?: string;
  tokenClass: string;
  status: string;
}

export class AssetTokenizationService {
  /**
   * Tokenize asset with enhanced token class support
   */
  async tokenizeAsset(
    request: TokenizeAssetRequest
  ): Promise<TokenizeAssetResult> {
    logger.info('Asset Tokenization: Tokenizing asset', { request });

    // Step 1: Verify token class exists
    const tokenClass = await tokenClassManagerService.getTokenClass(
      request.tokenClass
    );

    if (!tokenClass || tokenClass.status !== 'active') {
      throw new Error(`Token class not found or inactive: ${request.tokenClass}`);
    }

    // Step 2: Generate asset ID and token ID
    const assetId = `ASSET-${uuidv4()}`;
    const tokenId = request.tokenClass === 'virtual_land' 
      ? `LAND-${uuidv4()}` 
      : `TOKEN-${uuidv4()}`;

    // Step 3: Create asset record
    const asset = await prisma.metaverse_assets.create({
      data: {
        assetId,
        metaverseNodeId: request.metaverseNodeId,
        assetType: request.assetType,
        assetName: request.assetName,
        tokenId,
        ownerAvatarId: request.ownerAvatarId || null,
        value: request.value ? new Decimal(request.value) : null,
        currencyCode: request.currencyCode || null,
        tokenClass: request.tokenClass,
        businessLicenseId: request.businessLicenseId || null,
        eventRights: request.eventRights || null,
        dataOwnershipTokenId: request.dataOwnershipTokenId || null,
        aiCompanionId: request.aiCompanionId || null,
        status: 'active',
      },
    });

    logger.info('Asset Tokenization: Asset tokenized', {
      assetId,
      tokenId,
      tokenClass: request.tokenClass,
    });

    return {
      assetId: asset.assetId,
      tokenId: asset.tokenId || undefined,
      tokenClass: asset.tokenClass || request.tokenClass,
      status: asset.status,
    };
  }

  /**
   * Get tokenized asset by ID
   */
  async getTokenizedAsset(assetId: string) {
    return await prisma.metaverse_assets.findUnique({
      where: { assetId },
      include: {
        node: true,
      },
    });
  }

  /**
   * Get tokenized assets by token class
   */
  async getTokenizedAssetsByClass(
    metaverseNodeId: string,
    tokenClass: string
  ) {
    return await prisma.metaverse_assets.findMany({
      where: {
        metaverseNodeId,
        tokenClass,
        status: 'active',
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Transfer tokenized asset
   */
  async transferTokenizedAsset(
    assetId: string,
    newOwnerAvatarId: string
  ): Promise<void> {
    await prisma.metaverse_assets.update({
      where: { assetId },
      data: {
        ownerAvatarId: newOwnerAvatarId,
      },
    });

    logger.info('Asset Tokenization: Asset transferred', {
      assetId,
      newOwnerAvatarId,
    });
  }
}

export const assetTokenizationService = new AssetTokenizationService();

