// DeFi Pool Service
// Liquidity pool management

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


export interface PoolCreationRequest {
  moduleId: string;
  poolName: string;
  assetTypes: string[];
  governanceModel?: string; // dbis_governed, scb_oversight
}

export interface PoolDepositRequest {
  poolId: string;
  assetType: string;
  amount: string;
}

export class DeFiPoolService {
  /**
   * Create liquidity pool
   */
  async createPool(
    request: PoolCreationRequest
  ): Promise<{ poolId: string }> {
    const poolId = `POOL-${uuidv4()}`;

    const pool = await prisma.deFiLiquidityPool.create({
      data: {
        poolId,
        moduleId: request.moduleId,
        poolName: request.poolName,
        assetTypes: request.assetTypes,
        totalLiquidity: new Decimal(0),
        governanceModel: request.governanceModel || 'dbis_governed',
        status: 'active',
      },
    });

    return {
      poolId: pool.poolId,
    };
  }

  /**
   * Deposit to pool
   */
  async depositToPool(
    request: PoolDepositRequest
  ): Promise<void> {
    const pool = await prisma.deFiLiquidityPool.findUnique({
      where: { poolId: request.poolId },
    });

    if (!pool) {
      throw new Error(`Pool not found: ${request.poolId}`);
    }

    if (pool.status !== 'active') {
      throw new Error(`Pool is not active: ${pool.status}`);
    }

    const amount = new Decimal(request.amount);

    await prisma.deFiLiquidityPool.update({
      where: { poolId: request.poolId },
      data: {
        totalLiquidity: pool.totalLiquidity.plus(amount),
      },
    });
  }

  /**
   * Withdraw from pool
   */
  async withdrawFromPool(
    poolId: string,
    amount: string
  ): Promise<void> {
    const pool = await prisma.deFiLiquidityPool.findUnique({
      where: { poolId },
    });

    if (!pool) {
      throw new Error(`Pool not found: ${poolId}`);
    }

    const withdrawAmount = new Decimal(amount);

    if (pool.totalLiquidity.lessThan(withdrawAmount)) {
      throw new Error('Insufficient liquidity in pool');
    }

    await prisma.deFiLiquidityPool.update({
      where: { poolId },
      data: {
        totalLiquidity: pool.totalLiquidity.minus(withdrawAmount),
      },
    });
  }

  /**
   * Get pool details
   */
  async getPool(poolId: string): Promise<any | null> {
    const pool = await prisma.deFiLiquidityPool.findUnique({
      where: { poolId },
      include: {
        swaps: true,
      },
    });

    return pool;
  }

  /**
   * Pause pool
   */
  async pausePool(poolId: string): Promise<void> {
    await prisma.deFiLiquidityPool.update({
      where: { poolId },
      data: { status: 'paused' },
    });
  }
}

export const defiPoolService = new DeFiPoolService();

