/**
 * User Settings Routes
 *
 * Endpoints for managing user-specific settings, including AI configuration.
 * All routes require authentication and operate only on the authenticated user's data.
 */

import express, { Request, Response } from 'express';
import { body, param, validationResult } from 'express-validator';
import { authenticate } from '../middleware/auth';
import { getModels } from '../models';
import { invalidateAICache } from '../utils/aiProvider';

const router = express.Router();
router.use(authenticate);

// ============================================
// TYPES
// ============================================

type AIProvider = 'claude' | 'zhipu' | 'ollama' | 'openai' | 'flux' | 'midjourney' | 'ideogram' | 'nano';

interface APIKeyEntry {
  key: string;
  isActive: boolean;
  model?: string;
  url?: string;
  // ── Health metadata — managed automatically by the AI Key Health Check worker ──
  health?: 'active' | 'inactive';
  lastCheckedAt?: string;
  lastError?: string;
  lastLatencyMs?: number;
  consecutiveFailures?: number;
}

interface AIConfigSettings {
  aiProvider: string;
  aiTimeout: number;
  ollamaBaseUrl: string;
  claudeKeys: APIKeyEntry[];
  zhipuKeys: APIKeyEntry[];
  ollamaKeys: APIKeyEntry[];
  openaiKeys: APIKeyEntry[];
}

// ============================================
// HELPERS
// ============================================

function maskApiKey(key: string): { masked: string; hasKey: boolean } {
  if (!key || key.trim() === '') return { masked: '', hasKey: false };
  if (key.length <= 4) return { masked: '****', hasKey: true };
  return { masked: '*'.repeat(key.length - 4) + key.slice(-4), hasKey: true };
}

function isMaskedValue(value: string): boolean {
  if (!value) return false;
  return /^\*{4,}.{0,4}$/.test(value);
}

/**
 * Migrate legacy single-key format to new array format
 */
function migrateToKeysArray(aiConfig: any): any {
  if (!aiConfig) return { aiProvider: 'auto', aiTimeout: 120000 };

  // Check if already migrated (has keys arrays)
  if (aiConfig.claudeKeys || aiConfig.zhipuKeys || aiConfig.ollamaKeys || aiConfig.openaiKeys) {
    return aiConfig;
  }

  const migrated: any = {
    aiProvider: aiConfig.aiProvider || 'auto',
    aiTimeout: aiConfig.aiTimeout || 120000,
    ollamaBaseUrl: aiConfig.ollamaBaseUrl || '',
  };

  // Migrate Claude key
  if (aiConfig.claudeApiKey && aiConfig.claudeApiKey.trim()) {
    migrated.claudeKeys = [{ key: aiConfig.claudeApiKey.trim(), isActive: true }];
  } else {
    migrated.claudeKeys = [];
  }

  // Migrate Zhipu key
  if (aiConfig.zhipuApiKey && aiConfig.zhipuApiKey.trim()) {
    migrated.zhipuKeys = [{
      key: aiConfig.zhipuApiKey.trim(),
      isActive: true,
      model: aiConfig.zhipuModel || 'glm-4-plus',
      url: aiConfig.zhipuApiUrl || '',
    }];
  } else {
    migrated.zhipuKeys = [];
  }

  // Migrate Ollama key
  if (aiConfig.ollamaApiKey && aiConfig.ollamaApiKey.trim()) {
    migrated.ollamaKeys = [{
      key: aiConfig.ollamaApiKey.trim(),
      isActive: true,
      model: aiConfig.ollamaModel || '',
    }];
  } else {
    migrated.ollamaKeys = [];
  }

  // Migrate OpenAI key
  if (aiConfig.openaiApiKey && aiConfig.openaiApiKey.trim()) {
    migrated.openaiKeys = [{
      key: aiConfig.openaiApiKey.trim(),
      isActive: true,
      model: aiConfig.openaiModel || 'gpt-4o',
      url: aiConfig.openaiApiUrl || '',
    }];
  } else {
    migrated.openaiKeys = [];
  }

  return migrated;
}

function getKeysArrayName(provider: AIProvider): string {
  switch (provider) {
    case 'claude': return 'claudeKeys';
    case 'zhipu': return 'zhipuKeys';
    case 'ollama': return 'ollamaKeys';
    case 'openai': return 'openaiKeys';
    case 'flux': return 'fluxKeys';
    case 'midjourney': return 'midjourneyKeys';
    case 'ideogram': return 'ideogramKeys';
    case 'nano': return 'nanoKeys';
  }
}

type MaskedKeyEntry = {
  key: string;
  isActive: boolean;
  model?: string;
  url?: string;
  hasKey: boolean;
  // Health status maintained by the AI Key Health Check worker
  health?: 'active' | 'inactive';
  lastCheckedAt?: string;
  lastError?: string;
  lastLatencyMs?: number;
  consecutiveFailures?: number;
};

function maskKeyEntry(entry: APIKeyEntry): MaskedKeyEntry {
  const masked = maskApiKey(entry.key);
  return {
    key: masked.masked,
    isActive: entry.isActive,
    ...(entry.model ? { model: entry.model } : {}),
    ...(entry.url ? { url: entry.url } : {}),
    hasKey: masked.hasKey,
    ...(entry.health ? { health: entry.health } : {}),
    ...(entry.lastCheckedAt ? { lastCheckedAt: entry.lastCheckedAt } : {}),
    ...(entry.lastError ? { lastError: entry.lastError } : {}),
    ...(typeof entry.lastLatencyMs === 'number' ? { lastLatencyMs: entry.lastLatencyMs } : {}),
    ...(typeof entry.consecutiveFailures === 'number' ? { consecutiveFailures: entry.consecutiveFailures } : {}),
  };
}

function maskKeysArray(keys: APIKeyEntry[]): MaskedKeyEntry[] {
  if (!keys || !Array.isArray(keys)) return [];
  return keys.map(maskKeyEntry);
}

// ============================================
// GET /user-settings/ai-config — Get user's AI config
// ============================================

router.get('/ai-config', async (req: Request, res: Response) => {
  try {
    const { User } = getModels();
    const user = await User.findById(req.user!._id);

    if (!user) {
      res.status(404).json({ error: 'User not found' });
      return;
    }

    const userSettings = (user as any).userSettings || {};
    const useGlobalAIConfig = userSettings.useGlobalAIConfig !== false;

    // Get the AI config
    const rawAiConfig = userSettings.aiConfig || {};
    const migratedAi = migrateToKeysArray(rawAiConfig);

    const aiConfig: AIConfigSettings = {
      aiProvider: migratedAi.aiProvider || 'auto',
      aiTimeout: migratedAi.aiTimeout || 120000,
      ollamaBaseUrl: migratedAi.ollamaBaseUrl || '',
      claudeKeys: maskKeysArray(migratedAi.claudeKeys || []),
      zhipuKeys: maskKeysArray(migratedAi.zhipuKeys || []),
      ollamaKeys: maskKeysArray(migratedAi.ollamaKeys || []),
      openaiKeys: maskKeysArray(migratedAi.openaiKeys || []),
    };

    res.json({
      useGlobalAIConfig,
      aiConfig,
    });
  } catch (error: any) {
    console.error('[UserSettings] Get AI config error:', error.message);
    res.status(500).json({ error: 'Failed to fetch AI configuration' });
  }
});

// ============================================
// PUT /user-settings/ai-config — Update user's AI config
// ============================================

router.put(
  '/ai-config',
  [
    body('aiProvider').optional().isIn(['auto', 'ollama', 'zhipu', 'claude', 'openai']),
    body('ollamaBaseUrl').optional().trim(),
    body('aiTimeout').optional().isInt({ min: 10000, max: 600000 }),
    body('claudeKeys').optional().isArray(),
    body('zhipuKeys').optional().isArray(),
    body('ollamaKeys').optional().isArray(),
    body('openaiKeys').optional().isArray(),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById(req.user!._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const currentUserSettings = (user as any).userSettings || {};
      const currentAiConfig = migrateToKeysArray(currentUserSettings.aiConfig || {});
      const mergedAi: any = { ...currentAiConfig };

      // Non-key fields — always overwrite
      if (req.body.aiProvider !== undefined) mergedAi.aiProvider = req.body.aiProvider;
      if (req.body.ollamaBaseUrl !== undefined) mergedAi.ollamaBaseUrl = req.body.ollamaBaseUrl;
      if (req.body.aiTimeout !== undefined) mergedAi.aiTimeout = req.body.aiTimeout;

      // Process keys arrays
      const processKeysArray = (keys: any[], currentKeys: APIKeyEntry[], provider: AIProvider): APIKeyEntry[] => {
        return keys.map((k, i) => {
          const existing = currentKeys[i];
          const key = k.key;
          // If key is masked, use the existing key value
          const finalKey = isMaskedValue(key) ? (existing?.key || '') : key;
          return {
            key: finalKey,
            isActive: k.isActive ?? (i === 0),
            ...(k.model !== undefined ? { model: k.model } : {}),
            ...(k.url !== undefined ? { url: k.url } : {}),
          };
        });
      };

      if (Array.isArray(req.body.claudeKeys)) {
        mergedAi.claudeKeys = processKeysArray(req.body.claudeKeys, currentAiConfig.claudeKeys || [], 'claude');
      }
      if (Array.isArray(req.body.zhipuKeys)) {
        mergedAi.zhipuKeys = processKeysArray(req.body.zhipuKeys, currentAiConfig.zhipuKeys || [], 'zhipu');
      }
      if (Array.isArray(req.body.ollamaKeys)) {
        mergedAi.ollamaKeys = processKeysArray(req.body.ollamaKeys, currentAiConfig.ollamaKeys || [], 'ollama');
      }
      if (Array.isArray(req.body.openaiKeys)) {
        mergedAi.openaiKeys = processKeysArray(req.body.openaiKeys, currentAiConfig.openaiKeys || [], 'openai');
      }

      // Save updated settings
      (user as any).userSettings = {
        ...currentUserSettings,
        useGlobalAIConfig: currentUserSettings.useGlobalAIConfig !== false,
        aiConfig: mergedAi,
      };
      user.markModified('userSettings');
      await user.save();

      // Invalidate AI cache for this user only
      invalidateAICache(req.user!._id.toString());

      // Return masked config
      const savedConfig = {
        aiProvider: mergedAi.aiProvider,
        aiTimeout: mergedAi.aiTimeout,
        ollamaBaseUrl: mergedAi.ollamaBaseUrl || '',
        claudeKeys: maskKeysArray(mergedAi.claudeKeys || []),
        zhipuKeys: maskKeysArray(mergedAi.zhipuKeys || []),
        ollamaKeys: maskKeysArray(mergedAi.ollamaKeys || []),
        openaiKeys: maskKeysArray(mergedAi.openaiKeys || []),
      };

      res.json({
        useGlobalAIConfig: (user as any).userSettings.useGlobalAIConfig,
        aiConfig: savedConfig,
      });
    } catch (error: any) {
      console.error('[UserSettings] Update AI config error:', error.message);
      res.status(500).json({ error: 'Failed to update AI configuration' });
    }
  }
);

// ============================================
// POST /user-settings/ai-keys — Add new API key
// ============================================

router.post(
  '/ai-keys',
  [
    body('provider').isIn(['claude', 'zhipu', 'ollama', 'openai']),
    body('key').notEmpty().trim(),
    body('model').optional().trim(),
    body('url').optional().trim(),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById(req.user!._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const { provider, key, model, url } = req.body;
      const currentUserSettings = (user as any).userSettings || {};
      const currentAiConfig = migrateToKeysArray(currentUserSettings.aiConfig || {});

      // Get or initialize the keys array
      const keysArrayName = getKeysArrayName(provider as AIProvider);
      const keys: APIKeyEntry[] = currentAiConfig[keysArrayName] || [];

      // Create new key entry
      const newKey: APIKeyEntry = {
        key: key.trim(),
        isActive: keys.length === 0, // First key is automatically active
      };

      // Add provider-specific fields
      if (provider === 'zhipu') {
        newKey.model = model?.trim() || 'glm-4-plus';
        newKey.url = url?.trim() || '';
      } else if (provider === 'ollama') {
        newKey.model = model?.trim() || '';
      } else if (provider === 'openai') {
        newKey.model = model?.trim() || 'gpt-4o';
        newKey.url = url?.trim() || '';
      }

      keys.push(newKey);
      currentAiConfig[keysArrayName] = keys;

      // Save updated settings
      (user as any).userSettings = {
        ...currentUserSettings,
        useGlobalAIConfig: currentUserSettings.useGlobalAIConfig !== false,
        aiConfig: currentAiConfig,
      };
      user.markModified('userSettings');
      await user.save();

      // Invalidate AI cache for this user only
      invalidateAICache(req.user!._id.toString());

      // Return masked response
      const response: any = { provider, index: keys.length - 1 };
      response[keysArrayName] = maskKeysArray(keys);

      res.json(response);
    } catch (error: any) {
      console.error('[UserSettings] Add AI key error:', error.message);
      res.status(500).json({ error: 'Failed to add API key' });
    }
  }
);

// ============================================
// DELETE /user-settings/ai-keys/:provider/:index — Remove key
// ============================================

router.delete(
  '/ai-keys/:provider/:index',
  [
    param('provider').isIn(['claude', 'zhipu', 'ollama', 'openai']),
    param('index').isInt({ min: 0 }),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById(req.user!._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const { provider, index } = req.params;
      const indexNum = parseInt(index, 10);

      const currentUserSettings = (user as any).userSettings || {};
      const currentAiConfig = migrateToKeysArray(currentUserSettings.aiConfig || {});

      const keysArrayName = getKeysArrayName(provider as AIProvider);
      const keys: APIKeyEntry[] = currentAiConfig[keysArrayName] || [];

      if (indexNum < 0 || indexNum >= keys.length) {
        res.status(400).json({ error: 'Invalid key index' });
        return;
      }

      const wasActive = keys[indexNum].isActive;
      keys.splice(indexNum, 1);

      // If deleted key was active, make first remaining key active
      if (wasActive && keys.length > 0) {
        keys[0].isActive = true;
      }

      currentAiConfig[keysArrayName] = keys;
      (user as any).userSettings = {
        ...currentUserSettings,
        useGlobalAIConfig: currentUserSettings.useGlobalAIConfig !== false,
        aiConfig: currentAiConfig,
      };
      user.markModified('userSettings');
      await user.save();

      // Invalidate AI cache for this user only
      invalidateAICache(req.user!._id.toString());

      res.json({ provider, keys: maskKeysArray(keys) });
    } catch (error: any) {
      console.error('[UserSettings] Delete AI key error:', error.message);
      res.status(500).json({ error: 'Failed to delete API key' });
    }
  }
);

// ============================================
// PUT /user-settings/ai-keys/:provider/:index/activate — Set active key
// ============================================

router.put(
  '/ai-keys/:provider/:index/activate',
  [
    param('provider').isIn(['claude', 'zhipu', 'ollama', 'openai']),
    param('index').isInt({ min: 0 }),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById(req.user!._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const { provider, index } = req.params;
      const indexNum = parseInt(index, 10);

      const currentUserSettings = (user as any).userSettings || {};
      const currentAiConfig = migrateToKeysArray(currentUserSettings.aiConfig || {});

      const keysArrayName = getKeysArrayName(provider as AIProvider);
      const keys: APIKeyEntry[] = currentAiConfig[keysArrayName] || [];

      if (indexNum < 0 || indexNum >= keys.length) {
        res.status(400).json({ error: 'Invalid key index' });
        return;
      }

      // Set all keys to inactive, then activate the selected one
      keys.forEach((k, i) => {
        k.isActive = (i === indexNum);
      });

      currentAiConfig[keysArrayName] = keys;
      (user as any).userSettings = {
        ...currentUserSettings,
        useGlobalAIConfig: currentUserSettings.useGlobalAIConfig !== false,
        aiConfig: currentAiConfig,
      };
      user.markModified('userSettings');
      await user.save();

      // Invalidate AI cache for this user only
      invalidateAICache(req.user!._id.toString());

      res.json({ provider, keys: maskKeysArray(keys) });
    } catch (error: any) {
      console.error('[UserSettings] Activate AI key error:', error.message);
      res.status(500).json({ error: 'Failed to activate API key' });
    }
  }
);

// ============================================
// PATCH /user-settings/use-global — Toggle useGlobalAIConfig
// ============================================

router.patch(
  '/use-global',
  [
    body('useGlobal').isBoolean(),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById(req.user!._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const { useGlobal } = req.body;
      const currentUserSettings = (user as any).userSettings || {};

      (user as any).userSettings = {
        ...currentUserSettings,
        useGlobalAIConfig: useGlobal,
      };
      user.markModified('userSettings');
      await user.save();

      // Invalidate AI cache for this user only
      invalidateAICache(req.user!._id.toString());

      res.json({ useGlobalAIConfig: useGlobal });
    } catch (error: any) {
      console.error('[UserSettings] Toggle use global error:', error.message);
      res.status(500).json({ error: 'Failed to update setting' });
    }
  }
);

// ============================================
// GET /user-settings/ai-model-preference — Get user's saved AI model preference
// Returns per-type preferences (text, image, video, audio) and legacy fields for backward compatibility.
// ============================================

router.get('/ai-model-preference', async (req: Request, res: Response) => {
  try {
    const { User } = getModels();
    const user = await User.findById((req as any).user?._id);

    if (!user) {
      res.status(404).json({ error: 'User not found' });
      return;
    }

    const userSettings = (user as any).userSettings || {};
    const aiModelPreferences = userSettings.aiModelPreferences || {};

    // Migrate from legacy fields if per-type preferences don't exist yet
    const textPref = aiModelPreferences.text || {
      model: userSettings.preferredTextModel || null,
      remember: userSettings.rememberTextModelChoice === true,
    };

    res.json({
      // Per-type preferences (new format)
      preferences: {
        text: textPref,
        image: aiModelPreferences.image || { model: null, remember: false },
        video: aiModelPreferences.video || { model: null, remember: false },
        audio: aiModelPreferences.audio || { model: null, remember: false },
      },
      // Legacy fields for backward compatibility
      preferredTextModel: textPref.model,
      rememberTextModelChoice: textPref.remember,
    });
  } catch (error: any) {
    console.error('[UserSettings] Get AI model preference error:', error.message);
    res.status(500).json({ error: 'Failed to fetch AI model preference' });
  }
});

// ============================================
// PUT /user-settings/ai-model-preference — Save user's AI model preference
// Accepts both legacy format (preferredTextModel + rememberTextModelChoice) and
// new per-type format (generationType + model + remember).
// ============================================

router.put(
  '/ai-model-preference',
  [
    // Legacy fields
    body('preferredTextModel').optional().isString().trim(),
    body('rememberTextModelChoice').optional().isBoolean(),
    // New per-type fields
    body('generationType').optional().isString().trim(),
    body('model').optional().isString().trim(),
    body('remember').optional().isBoolean(),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    try {
      const { User } = getModels();
      const user = await User.findById((req as any).user?._id);

      if (!user) {
        res.status(404).json({ error: 'User not found' });
        return;
      }

      const currentUserSettings = (user as any).userSettings || {};
      const currentPrefs = currentUserSettings.aiModelPreferences || {
        text: { model: null, remember: false },
        image: { model: null, remember: false },
        video: { model: null, remember: false },
        audio: { model: null, remember: false },
      };

      let updatedSettings;

      if (req.body.generationType) {
        // New per-type format: { generationType: 'image', model: 'gpt_image_2', remember: true }
        const genType = req.body.generationType;
        const validTypes = ['text', 'image', 'video', 'audio'];
        if (!validTypes.includes(genType)) {
          res.status(400).json({ error: `Invalid generationType. Must be one of: ${validTypes.join(', ')}` });
          return;
        }

        const updatedPrefs = { ...currentPrefs };
        updatedPrefs[genType] = {
          model: req.body.model || null,
          remember: req.body.remember === true,
        };

        updatedSettings = {
          ...currentUserSettings,
          aiModelPreferences: updatedPrefs,
        };

        // Keep legacy fields in sync for backward compatibility
        if (genType === 'text') {
          updatedSettings.preferredTextModel = req.body.model || null;
          updatedSettings.rememberTextModelChoice = req.body.remember === true;
        }
      } else {
        // Legacy format: { preferredTextModel, rememberTextModelChoice }
        updatedSettings = {
          ...currentUserSettings,
          ...(req.body.preferredTextModel !== undefined && { preferredTextModel: req.body.preferredTextModel }),
          ...(req.body.rememberTextModelChoice !== undefined && { rememberTextModelChoice: req.body.rememberTextModelChoice }),
        };

        // Sync legacy fields into per-type preferences (text type)
        const updatedPrefs = { ...currentPrefs };
        updatedPrefs.text = {
          model: updatedSettings.preferredTextModel || null,
          remember: updatedSettings.rememberTextModelChoice === true,
        };
        updatedSettings.aiModelPreferences = updatedPrefs;
      }

      (user as any).userSettings = updatedSettings;
      await user.save();

      // Invalidate AI config cache so the new preference is picked up
      invalidateAICache((req as any).user?._id);

      const finalPrefs = updatedSettings.aiModelPreferences;

      res.json({
        // Per-type preferences (new format)
        preferences: {
          text: finalPrefs?.text || { model: null, remember: false },
          image: finalPrefs?.image || { model: null, remember: false },
          video: finalPrefs?.video || { model: null, remember: false },
          audio: finalPrefs?.audio || { model: null, remember: false },
        },
        // Legacy fields for backward compatibility
        preferredTextModel: finalPrefs?.text?.model || null,
        rememberTextModelChoice: finalPrefs?.text?.remember === true,
      });
    } catch (error: any) {
      console.error('[UserSettings] Save AI model preference error:', error.message);
      res.status(500).json({ error: 'Failed to save AI model preference' });
    }
  }
);

// ============================================
// GET /user-settings/available-ai-providers — Public: which text-generation providers have active keys
// ============================================

router.get('/available-ai-providers', async (req: Request, res: Response) => {
  try {
    const userId = (req as any).user?._id;
    const capability = (req.query.capability as string) || 'content-generation';
    const { getAIConfig, providerHasActiveKey, AI_MODEL_REGISTRY } = require('../utils/aiProvider');

    const config = await getAIConfig(userId);

    // Provider groups by capability — each group lists which providers
    // to check for active API keys.
    const PROVIDER_GROUPS: Record<string, string[]> = {
      'content-generation': ['claude', 'openai', 'zhipu', 'ollama'],
      'image-generation': ['openai', 'flux', 'midjourney', 'ideogram', 'nano', 'zhipu'],
      'video-generation': ['luma'],
      'audio-generation': ['suno'],
    };
    const providersToCheck = PROVIDER_GROUPS[capability] || PROVIDER_GROUPS['content-generation'];

    const availableProviders: string[] = [];
    for (const provider of providersToCheck) {
      if (providerHasActiveKey(provider, config)) {
        availableProviders.push(provider);
      }
    }

    // Get subscription-level model restrictions if available
    let accessibleModels: string[] | null = null;
    const companyId = (req as any).user?.companyId;
    if (companyId) {
      try {
        const { getModels: getDbModels } = require('../models');
        const { CompanySubscription } = getDbModels();
        const subscription = await CompanySubscription.findOne({ companyId }).lean();
        if (subscription && subscription.aiModels && subscription.aiModels.length > 0) {
          accessibleModels = subscription.aiModels;
        }
      } catch {
        // Subscription check is optional — if it fails, allow all models
      }
    }

    // Build model options based on available providers and subscription
    // Filter by the requested capability (default: content-generation)
    const models = AI_MODEL_REGISTRY
      ? AI_MODEL_REGISTRY
          .filter((m: any) => availableProviders.includes(m.provider))
          .filter((m: any) => !m.capability || m.capability === capability)
          .map((m: any) => ({
            value: m.slug,
            label: m.label || m.slug,
            provider: m.provider,
            capability: m.capability || capability,
            ...(m.description ? { description: m.description } : {}),
          }))
      : availableProviders.map((p) => ({
          value: p,
          label: p === 'claude' ? 'Claude Sonnet' :
                 p === 'openai' ? 'GPT-4o' :
                 p === 'zhipu' ? 'GLM-4 Plus' :
                 p === 'ollama' ? 'Ollama (Local)' : p,
          provider: p,
          capability: capability,
        }));

    // Filter by subscription if applicable
    const filteredModels = accessibleModels && accessibleModels.length > 0 && !accessibleModels.includes('*')
      ? models.filter((m: any) => accessibleModels.includes(m.value))
      : models;

    // Capability-based default model selection
    const DEFAULT_PROVIDERS: Record<string, string> = {
      'content-generation': 'ollama',
      'image-generation': 'openai',
      'video-generation': 'luma',
      'audio-generation': 'suno',
    };
    const defaultProvider = DEFAULT_PROVIDERS[capability] || DEFAULT_PROVIDERS['content-generation'];

    res.json({
      providers: availableProviders,
      models: filteredModels,
      defaultModel: filteredModels.length === 1
        ? filteredModels[0].value
        : (defaultProvider ? filteredModels.find((m: any) => m.provider === defaultProvider)?.value : null) || (filteredModels[0]?.value || null),
    });
  } catch (error: any) {
    console.error('[UserSettings] Available AI providers error:', error.message);
    res.status(500).json({ error: 'Failed to fetch available AI providers' });
  }
});

export default router;