/**
 * Liquidity Engine Service
 * Main entry point for the liquidity engine service
 */

import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import { LiquidityEngine } from '../liquidity-engine.service';
import { QuoteAggregator } from '../quote-aggregator.service';
import { ethers } from 'ethers';

dotenv.config();

const app = express();
app.use(cors());
app.use(express.json());

const PORT = process.env.PORT || 3000;
const RPC_URL = process.env.ETHEREUM_RPC_URL || process.env.ETHEREUM_MAINNET_RPC;
const ENHANCED_SWAP_ROUTER = process.env.ENHANCED_SWAP_ROUTER;

if (!RPC_URL) {
  throw new Error('ETHEREUM_RPC_URL or ETHEREUM_MAINNET_RPC must be set');
}

if (!ENHANCED_SWAP_ROUTER) {
  throw new Error('ENHANCED_SWAP_ROUTER must be set');
}

// Initialize services
const provider = new ethers.JsonRpcProvider(RPC_URL);
const liquidityEngine = new LiquidityEngine(provider, ENHANCED_SWAP_ROUTER);
const quoteAggregator = new QuoteAggregator(provider, ENHANCED_SWAP_ROUTER);

// Health check
app.get('/health', (req, res) => {
  res.json({ status: 'ok', service: 'liquidity-engine' });
});

// Get best route
app.post('/api/route', async (req, res) => {
  try {
    const { inputToken, outputToken, amount, maxSlippage } = req.body;
    
    if (!inputToken || !outputToken || !amount) {
      return res.status(400).json({ error: 'Missing required parameters' });
    }

    const decision = await liquidityEngine.findBestRoute(
      inputToken,
      outputToken,
      BigInt(amount),
      maxSlippage || 0.5
    );

    res.json(decision);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// Get quotes
app.get('/api/quotes', async (req, res) => {
  try {
    const { inputToken, outputToken, amount } = req.query;
    
    if (!inputToken || !outputToken || !amount) {
      return res.status(400).json({ error: 'Missing required parameters' });
    }

    const quotes = await quoteAggregator.aggregateQuotes(
      inputToken as string,
      outputToken as string,
      BigInt(amount as string)
    );

    res.json(quotes);
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// Get decision map
app.get('/api/decision-map', (req, res) => {
  const decisionMap = liquidityEngine.getDecisionMap();
  res.json(decisionMap);
});

// Update decision map
app.put('/api/decision-map', (req, res) => {
  try {
    liquidityEngine.updateDecisionMap(req.body);
    res.json({ success: true });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(PORT, () => {
  console.log(`Liquidity Engine Service running on port ${PORT}`);
});

