/**
 * Providers API Routes
 *
 * 模型提供商管理相关的 REST API
 */

import { Hono } from 'hono';
import { getConfig } from './config.js';

// Types from core - dynamically import to avoid build dependency
interface ProviderListItem {
  id: string;
  name: string;
  description?: string;
  builtin: boolean;
  enabled: boolean;
  hasApiKey: boolean;
  modelCount: number;
}

interface ModelInfo {
  id: string;
  name: string;
  capabilities?: {
    vision?: boolean;
    functionCalling?: boolean;
    streaming?: boolean;
  };
  contextWindow?: number;
  maxOutput?: number;
}

interface ProviderDetail {
  id: string;
  name: string;
  description?: string;
  builtin: boolean;
  baseUrl?: string;
  apiKeyEnvVar?: string;
  models: ModelInfo[];
  allowCustomModels: boolean;
  config: {
    enabled: boolean;
    hasApiKey: boolean;
    baseUrl?: string;
    customModels: ModelInfo[];
  };
}

interface CustomProviderDefinition {
  id: string;
  name: string;
  description?: string;
  baseUrl: string;
  apiKeyEnvVar?: string;
  models?: ModelInfo[];
  allowCustomModels?: boolean;
}

interface ProviderConfig {
  id?: string;
  apiKey?: string;
  apiKeyEnvVar?: string;
  baseUrl?: string;
  enabled?: boolean;
  customModels?: ModelInfo[];
}

interface ConnectionTestResult {
  success: boolean;
  latency?: number;
  error?: string;
}

export const providersRouter = new Hono();

// Core module reference
let coreModule: any = null;

/**
 * Load core module dynamically
 */
async function getCoreModule() {
  if (!coreModule) {
    try {
      const corePath = '@ai-assistant/core';
      coreModule = await import(corePath);
    } catch {
      return null;
    }
  }
  return coreModule;
}

/**
 * GET /providers - List all providers
 */
providersRouter.get('/', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  try {
    const registry = core.getProviderRegistry();
    const providers: ProviderListItem[] = registry.listForApi();

    return c.json({
      success: true,
      data: providers,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to list providers',
      },
      500
    );
  }
});

/**
 * GET /providers/:id - Get provider detail
 */
providersRouter.get('/:id', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const id = c.req.param('id');

  try {
    const registry = core.getProviderRegistry();
    const detail: ProviderDetail | undefined = registry.getDetail(id);

    if (!detail) {
      return c.json({ success: false, error: `Provider not found: ${id}` }, 404);
    }

    return c.json({
      success: true,
      data: detail,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to get provider',
      },
      500
    );
  }
});

/**
 * GET /providers/:id/models - Get provider's model list
 */
providersRouter.get('/:id/models', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const id = c.req.param('id');

  try {
    const registry = core.getProviderRegistry();

    if (!registry.has(id)) {
      return c.json({ success: false, error: `Provider not found: ${id}` }, 404);
    }

    const models: ModelInfo[] = registry.getModels(id);

    return c.json({
      success: true,
      data: models,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to get models',
      },
      500
    );
  }
});

/**
 * POST /providers/:id/test - Test provider connection
 */
providersRouter.post('/:id/test', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const id = c.req.param('id');

  try {
    const body = await c.req.json().catch(() => ({}));
    const apiKey = body.apiKey as string | undefined;

    const registry = core.getProviderRegistry();
    const result: ConnectionTestResult = await registry.testConnection(id, apiKey);

    return c.json({
      success: true,
      data: result,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Connection test failed',
      },
      500
    );
  }
});

/**
 * POST /providers - Register custom provider
 */
providersRouter.post('/', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  try {
    const body: CustomProviderDefinition = await c.req.json();

    // Validate required fields
    if (!body.id || !body.name || !body.baseUrl) {
      return c.json(
        {
          success: false,
          error: 'Missing required fields: id, name, baseUrl',
        },
        400
      );
    }

    const registry = core.getProviderRegistry();
    registry.registerCustom(body);
    await registry.saveConfig();

    return c.json({
      success: true,
      message: `Provider ${body.id} registered`,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to register provider',
      },
      400
    );
  }
});

/**
 * PUT /providers/:id - Update provider config
 */
providersRouter.put('/:id', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const id = c.req.param('id');

  try {
    const body: ProviderConfig = await c.req.json();

    const registry = core.getProviderRegistry();

    if (!registry.has(id)) {
      return c.json({ success: false, error: `Provider not found: ${id}` }, 404);
    }

    registry.setConfig(id, { ...body, id });
    await registry.saveConfig();

    return c.json({
      success: true,
      message: `Provider ${id} config updated`,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to update provider config',
      },
      400
    );
  }
});

/**
 * DELETE /providers/:id - Delete custom provider
 */
providersRouter.delete('/:id', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const id = c.req.param('id');

  try {
    const registry = core.getProviderRegistry();
    const removed = registry.removeCustom(id);

    if (!removed) {
      return c.json({ success: false, error: `Provider not found: ${id}` }, 404);
    }

    await registry.saveConfig();

    return c.json({
      success: true,
      message: `Provider ${id} removed`,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to remove provider',
      },
      400
    );
  }
});

/**
 * POST /providers/:id/models - Add custom model
 */
providersRouter.post('/:id/models', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const providerId = c.req.param('id');

  try {
    const body: ModelInfo = await c.req.json();

    // Validate required fields
    if (!body.id || !body.name) {
      return c.json(
        {
          success: false,
          error: 'Missing required fields: id, name',
        },
        400
      );
    }

    const registry = core.getProviderRegistry();
    registry.addCustomModel(providerId, body);
    await registry.saveConfig();

    return c.json({
      success: true,
      message: `Model ${body.id} added to ${providerId}`,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to add model',
      },
      400
    );
  }
});

/**
 * DELETE /providers/:id/models/:modelId - Delete custom model
 */
providersRouter.delete('/:id/models/:modelId', async (c) => {
  const core = await getCoreModule();
  if (!core) {
    return c.json({ success: false, error: 'Core module not available' }, 503);
  }

  const providerId = c.req.param('id');
  const modelId = c.req.param('modelId');

  try {
    const registry = core.getProviderRegistry();
    const removed = registry.removeCustomModel(providerId, modelId);

    if (!removed) {
      return c.json(
        {
          success: false,
          error: `Model ${modelId} not found in ${providerId}`,
        },
        404
      );
    }

    await registry.saveConfig();

    return c.json({
      success: true,
      message: `Model ${modelId} removed from ${providerId}`,
    });
  } catch (error) {
    return c.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to remove model',
      },
      400
    );
  }
});
