import { getUserFromRequest } from '../../../lib/permission-middleware';
import { embedCardImage, EmbedApiError } from '../../../lib/card-embed.js';
import { matchVisualInCatalog, catalogHasEmbeddings } from '../../../lib/card-visual-match.js';
import { logScanAttempt } from '../../../lib/card-catalog-match.js';

function formatCardResponse(card) {
  return {
    id: card.id,
    name: card.name,
    set_name: card.set_name,
    set_code: card.set_code,
    card_number: card.card_number,
    game: card.game,
    card_type: card.card_type,
    rarity: card.rarity,
    hp: card.power,
    mana_cost: card.mana_cost,
    image_url: card.image_url,
    visual: {
      similarity: card.sim,
    },
  };
}

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  const startedAt = Date.now();

  try {
    const user = await getUserFromRequest(req);
    if (!user) {
      return res.status(401).json({ error: 'Authentication required' });
    }

    const { imageData, game } = req.body || {};

    if (!imageData || typeof imageData !== 'string') {
      return res.status(400).json({ error: 'imageData is required' });
    }

    if (imageData.length > 6_000_000) {
      return res.status(400).json({ error: 'Image payload too large' });
    }

    if (!(await catalogHasEmbeddings())) {
      const latencyMs = Date.now() - startedAt;
      await logScanAttempt({
        userId: user.userId,
        ocrText: null,
        ocrConfidence: null,
        layer: 0,
        resultKind: 'escalate',
        latencyMs,
      });
      return res.status(200).json({
        layer: 0,
        escalate: true,
        reason: 'Catalog visual index is empty — run npm run backfill-embeddings',
      });
    }

    const embedding = await embedCardImage(imageData);
    const matchResult = await matchVisualInCatalog({ embedding, game: game || null });
    const latencyMs = Date.now() - startedAt;

    if (matchResult.type === 'escalate') {
      await logScanAttempt({
        userId: user.userId,
        ocrText: null,
        ocrConfidence: null,
        layer: 0,
        resultKind: 'escalate',
        latencyMs,
      });
      return res.status(200).json({
        layer: 0,
        escalate: true,
        reason: matchResult.reason,
      });
    }

    if (matchResult.type === 'matched') {
      await logScanAttempt({
        userId: user.userId,
        ocrText: null,
        ocrConfidence: Math.round((matchResult.similarity || 0) * 100),
        layer: 0,
        matchedCardId: matchResult.card.id,
        resultKind: 'matched',
        latencyMs,
      });
      return res.status(200).json({
        layer: 0,
        escalate: false,
        isCard: true,
        card: formatCardResponse(matchResult.card),
        isExisting: true,
        message: matchResult.message,
        visual: { similarity: matchResult.similarity },
      });
    }

    await logScanAttempt({
      userId: user.userId,
      ocrText: null,
      ocrConfidence: Math.round((matchResult.similarity || 0) * 100),
      layer: 0,
      resultKind: 'disambiguation',
      latencyMs,
    });

    return res.status(200).json({
      layer: 0,
      escalate: false,
      isCard: true,
      card: null,
      matches: matchResult.matches,
      needsUserSelection: true,
      message: matchResult.message,
      visual: { similarity: matchResult.similarity },
    });
  } catch (error) {
    console.error('[POST /api/scan/identify-by-image]', error);

    if (error instanceof EmbedApiError) {
      if (error.message.includes('AI_GATEWAY_API_KEY')) {
        return res.status(503).json({
          error: 'Visual matching is not configured on this server (missing AI_GATEWAY_API_KEY).',
        });
      }
      if (error.status === 429) {
        return res.status(502).json({
          error: 'Embedding service quota exceeded. Try again later.',
        });
      }
    }

    if (String(error.message).includes('vector') || String(error.message).includes('pgvector')) {
      return res.status(503).json({
        error: 'Visual matching unavailable — run npm run migrate up (pgvector extension).',
      });
    }

    return res.status(500).json({ error: 'Internal server error' });
  }
}
