import { Router } from 'express';
import { getProjects, getSessions } from '../projects.js';
import { userDb, subscriptionDb, paymentDb, apiKeysDb, credentialsDb, relayTokensDb, webhookDb, workflowDb } from '../database/db.js';

const router = Router();

// AI provider credential types
const AI_PROVIDER_TYPES = ['anthropic_key', 'openai_key', 'openrouter_key', 'google_key'];
const PROVIDER_LABELS = {
  anthropic_key: 'Anthropic',
  openai_key: 'OpenAI',
  openrouter_key: 'OpenRouter',
  google_key: 'Google',
};

// Per-user stats cache (60s TTL)
const statsCache = new Map();
const CACHE_TTL = 60_000;

function getCachedStats(userId) {
  const entry = statsCache.get(userId);
  if (entry && Date.now() - entry.ts < CACHE_TTL) return entry.data;
  return null;
}
function setCachedStats(userId, data) {
  statsCache.set(userId, { data, ts: Date.now() });
}
function invalidateStatsCache(userId) {
  statsCache.delete(userId);
}

// Periodic expiry of overdue subs (every 5 min, not per-request)
let lastExpireRun = 0;
async function maybeExpireOverdue() {
  if (Date.now() - lastExpireRun < 300_000) return;
  lastExpireRun = Date.now();
  try { await subscriptionDb.expireOverdue(); } catch { /* non-critical */ }
}

/**
 * GET /api/dashboard/user-stats — Per-user dashboard data from Turso
 * Aggregates: account, subscription, payments, API keys, AI providers, relay tokens, webhooks, workflows
 */
router.get('/user-stats', async (req, res) => {
  try {
    const userId = req.user.id;

    // Return cached stats if fresh (< 60s)
    const cached = getCachedStats(userId);
    if (cached) return res.json(cached);

    // Run all DB queries in parallel
    const [
      fullUser,
      activeSub,
      allSubs,
      payments,
      apiKeys,
      credentials,
      relayTokens,
      webhooks,
      workflows,
    ] = await Promise.all([
      userDb.getUserById(userId),
      subscriptionDb.getActiveSub(userId).catch(() => null),
      subscriptionDb.getAllSubs(userId).catch(() => []),
      paymentDb.getUserPayments(userId).catch(() => []),
      apiKeysDb.getApiKeys(userId).catch(() => []),
      credentialsDb.getCredentials(userId).catch(() => []),
      relayTokensDb.getTokens(userId).catch(() => []),
      webhookDb.getAll(userId).catch(() => []),
      workflowDb.getAll(userId).catch(() => []),
    ]);

    // Expire overdue subs periodically (not per-request)
    maybeExpireOverdue();

    // Account
    const account = fullUser ? {
      username: fullUser.username,
      email: fullUser.email,
      phone: fullUser.phone,
      firstName: fullUser.first_name,
      lastName: fullUser.last_name,
      userCode: fullUser.user_code,
      createdAt: fullUser.created_at,
      lastLogin: fullUser.last_login,
      accessOverride: fullUser.access_override,
    } : null;

    // Subscription
    const subscription = {
      active: activeSub ? {
        id: activeSub.id,
        planId: activeSub.plan_id,
        status: activeSub.status,
        startsAt: activeSub.starts_at,
        expiresAt: activeSub.expires_at,
        amount: activeSub.amount,
        currency: activeSub.currency || 'INR',
      } : null,
      history: allSubs.map(s => ({
        id: s.id,
        planId: s.plan_id,
        status: s.status,
        startsAt: s.starts_at,
        expiresAt: s.expires_at,
        amount: s.amount,
        currency: s.currency || 'INR',
        createdAt: s.created_at,
      })),
    };

    // Payments
    const paidPayments = payments.filter(p => p.status === 'paid');
    const totalAmountPaise = paidPayments.reduce((sum, p) => sum + (Number(p.amount) || 0), 0);
    const paymentData = {
      total: payments.length,
      paid: paidPayments.length,
      totalAmountPaise,
      recent: payments.slice(0, 10).map(p => ({
        id: p.id,
        planId: p.plan_id,
        amount: p.amount,
        currency: p.currency || 'INR',
        status: p.status,
        createdAt: p.created_at,
      })),
    };

    // API Keys (include full list for dashboard display)
    const activeKeys = apiKeys.filter(k => k.is_active);
    const apiKeyData = {
      total: apiKeys.length,
      active: activeKeys.length,
      keys: apiKeys.map(k => ({
        id: k.id,
        keyName: k.key_name || 'default',
        keyPrefix: k.api_key ? k.api_key.slice(0, 12) : '',
        keySuffix: k.api_key ? k.api_key.slice(-6) : '',
        fullKey: k.api_key,
        isActive: !!k.is_active,
        createdAt: k.created_at,
        lastUsed: k.last_used,
      })),
    };

    // AI Providers (filter credentials by AI provider types)
    const aiCreds = credentials.filter(c => AI_PROVIDER_TYPES.includes(c.credential_type));
    const activeAiCreds = aiCreds.filter(c => c.is_active);
    const aiProviderData = {
      total: aiCreds.length,
      active: activeAiCreds.length,
      providers: activeAiCreds.map(c => PROVIDER_LABELS[c.credential_type] || c.credential_type),
    };

    // Relay Tokens
    const activeTokens = relayTokens.filter(t => t.is_active);
    const lastConnected = relayTokens
      .filter(t => t.last_connected)
      .sort((a, b) => new Date(b.last_connected) - new Date(a.last_connected))[0]?.last_connected || null;
    const relayData = {
      total: relayTokens.length,
      active: activeTokens.length,
      lastConnected,
    };

    // Webhooks
    const activeWebhooks = webhooks.filter(w => w.is_active);
    const webhookData = {
      total: webhooks.length,
      active: activeWebhooks.length,
    };

    // Workflows
    const activeWorkflows = workflows.filter(w => w.is_active);
    const workflowData = {
      total: workflows.length,
      active: activeWorkflows.length,
    };

    const result = {
      account,
      subscription,
      payments: paymentData,
      apiKeys: apiKeyData,
      aiProviders: aiProviderData,
      relayTokens: relayData,
      webhooks: webhookData,
      workflows: workflowData,
    };

    setCachedStats(userId, result);
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch user stats' });
  }
});

/**
 * GET /api/dashboard/stats — Dashboard usage analytics (local projects)
 * Returns session counts, provider breakdown, and today's activity.
 */
router.get('/stats', async (req, res) => {
  try {
    const userId = req.user?.id || req.user?.userId;
    const projects = await getProjects(null, userId);
    let totalSessions = 0;
    let todaySessions = 0;
    const providers = {};
    const today = new Date().toISOString().slice(0, 10);

    for (const project of projects) {
      // Count sessions per provider
      for (const provider of ['claude', 'cursor', 'codex']) {
        try {
          const sessions = await getSessions(project.name, provider);
          if (sessions && sessions.length) {
            totalSessions += sessions.length;
            providers[provider] = (providers[provider] || 0) + sessions.length;

            // Count today's sessions
            for (const s of sessions) {
              const created = s.created_at || s.createdAt || '';
              if (created.startsWith(today)) {
                todaySessions++;
              }
            }
          }
        } catch (e) {
          // Provider not available for this project
        }
      }
    }

    res.json({
      total: totalSessions,
      today: todaySessions,
      providers,
      projectCount: projects.length,
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch dashboard stats' });
  }
});

/**
 * POST /api/dashboard/api-keys — Create a new API key
 */
router.post('/api-keys', async (req, res) => {
  try {
    const userId = req.user.id;
    const keyName = req.body.keyName || 'default';
    const result = await apiKeysDb.createApiKey(userId, keyName);
    invalidateStatsCache(userId);
    res.json({ success: true, key: result });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create API key' });
  }
});

/**
 * DELETE /api/dashboard/api-keys/:id — Delete a specific API key
 */
router.delete('/api-keys/:id', async (req, res) => {
  try {
    const userId = req.user.id;
    const keyId = Number(req.params.id);
    const deleted = await apiKeysDb.deleteApiKey(userId, keyId);
    if (!deleted) return res.status(404).json({ error: 'API key not found' });
    invalidateStatsCache(userId);
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Failed to delete API key' });
  }
});

/**
 * PATCH /api/dashboard/api-keys/:id/toggle — Toggle API key active/inactive
 */
router.patch('/api-keys/:id/toggle', async (req, res) => {
  try {
    const userId = req.user.id;
    const keyId = Number(req.params.id);
    const isActive = !!req.body.isActive;
    const toggled = await apiKeysDb.toggleApiKey(userId, keyId, isActive);
    invalidateStatsCache(userId);
    if (!toggled) return res.status(404).json({ error: 'API key not found' });
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Failed to toggle API key' });
  }
});

export default router;
