import {FastifyPluginAsyncTypebox, Type} from '@fastify/type-provider-typebox'
import {handleError} from '../utils/errorHandler.js'
import {getClientForAddress} from '../plugins/custom/gmx.js'
import {getPrivyClient} from '../plugins/custom/privy.js'

const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
  fastify.get(
    '/',
    {
      schema: {
        tags: ['Home'],
        description: 'Welcome endpoint that confirms the API is running',
        response: {
          200: Type.Object({
            message: Type.String()
          }),
          500: Type.Object({
            success: Type.Boolean(),
            error: Type.String()
          })
        }
      }
    },
    async function (request, reply) {
      try {
        return { message: 'Welcome to the official Web3 Proxy API!' }
      } catch (error) {
        return handleError(request, reply, error, 'home-root');
      }
    }
  )
  // Enhanced health check endpoint
  fastify.get('/health', {
    schema: {
      tags: ['Health'],
      description: 'Enhanced health check endpoint that verifies API, Privy, and GMX connectivity',
      response: {
        200: Type.Object({
          status: Type.String(),
          timestamp: Type.String(),
          version: Type.String(),
          checks: Type.Object({
            privy: Type.Object({
              status: Type.String(),
              message: Type.String()
            }),
            gmx: Type.Object({
              status: Type.String(),
              message: Type.String(),
              data: Type.Optional(Type.Any())
            })
          })
        }),
        500: Type.Object({
          success: Type.Boolean(),
          error: Type.String()
        })
      }
    }
  }, async function (request, reply) {
    try {
      const checks = {
        privy: await checkPrivy(fastify),
        gmx: await checkGmx()
      }

      // If any check failed, set status to degraded
      const overallStatus = Object.values(checks).some(check => check.status !== 'healthy') 
        ? 'degraded' 
        : 'healthy';

      return { 
        status: overallStatus,
        timestamp: new Date().toISOString(),
        version: process.env.npm_package_version || '1.0.0',
        checks
      }
    } catch (error) {
      return handleError(request, reply, error, 'health');
    }
  })

  // Helper function to check Privy connectivity and configuration
  async function checkPrivy(fastify) {
    try {
      // Try to initialize the Privy client - this will validate env vars and connectivity
      const privy = getPrivyClient(fastify);
      
      // Check if the necessary configuration is available
      const hasPrivyAppId = !!process.env.PRIVY_APP_ID;
      const hasPrivySecret = !!process.env.PRIVY_APP_SECRET;
      const hasPrivyAuthKey = !!process.env.PRIVY_AUTHORIZATION_KEY;
      
      // Get the client status
      const allConfigPresent = hasPrivyAppId && hasPrivySecret && hasPrivyAuthKey;
      
      if (!allConfigPresent) {
        return {
          status: 'degraded',
          message: 'Privy configuration incomplete: ' + 
            (!hasPrivyAppId ? 'PRIVY_APP_ID ' : '') + 
            (!hasPrivySecret ? 'PRIVY_APP_SECRET ' : '') +
            (!hasPrivyAuthKey ? 'PRIVY_AUTHORIZATION_KEY ' : '')
        };
      }
      
      // If we got this far, the Privy client was successfully initialized
      return {
        status: 'healthy',
        message: 'Privy client successfully initialized'
      };
    } catch (error) {
      return {
        status: 'unhealthy',
        message: `Privy client initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`
      };
    }
  }

  // Helper function to check GMX connectivity using the GMX SDK
  async function checkGmx() {
    try {
      // Use a dummy zero address for the health check
      const account = "0x0000000000000000000000000000000000000000";
      
      // Use the existing getClientForAddress function to get a proper GMX SDK instance
      const sdk = await getClientForAddress(account);
      
      // Get the uiFeeFactor - this is a lightweight call
      const startTime = Date.now();
      const uiFeeFactor = await sdk.utils.getUiFeeFactor();
      const responseTime = Date.now() - startTime;
      
      return {
        status: 'healthy',
        message: 'GMX SDK successfully initialized',
        data: { 
          responseTimeMs: responseTime,
          uiFeeFactor: uiFeeFactor.toString()
        }
      };
    } catch (error) {
      return {
        status: 'unhealthy',
        message: `GMX SDK check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
        data: {
          errorType: error instanceof Error ? error.constructor.name : 'Unknown'
        }
      };
    }
  }
}

export default plugin
