/**
 * Real ReviewRemovalPrescoringAgent - Gemini 2.0 Flash text implementation.
 *
 * Pre-scores vendor review-removal requests and provides a recommendation to
 * the human admin. The agent does NOT make final decisions - it surfaces
 * high-confidence cases for faster admin triage.
 *
 * On any Gemini error the agent fails safe:
 *   shouldRemove: false, confidence: 0 - defer everything to human review.
 */

import { requireConfiguredLlmModel } from '../model-config.js';
import { withSentry } from '@/server/observability/with-sentry';
import { captureCaught } from '@/server/observability/capture.server';
import type { LlmProvider } from '../providers/types.js';
import type { AiCredentials } from '../credentials.js';
import type {
  ReviewRemovalPrescoringAgent,
  ReviewRemovalPrescoringInput,
  ReviewRemovalPrescoringResult,
} from '../types.js';

export class GeminiReviewRemovalPrescoringAgent implements ReviewRemovalPrescoringAgent {
  private readonly provider: LlmProvider;
  private readonly creds: AiCredentials;
  private readonly model: string;

  constructor(provider: LlmProvider, creds: AiCredentials, model: string) {
    this.provider = provider;
    this.creds = creds;
    this.model = requireConfiguredLlmModel(model, 'review removal');
    this.score = withSentry(this.score.bind(this), {
      name: 'ai.review-removal-prescoring.score',
      kind: 'ai-agent',
    });
  }

  score: (input: ReviewRemovalPrescoringInput) => Promise<ReviewRemovalPrescoringResult> = async (
    input,
  ) => {
    const { reviewBody, reviewRating, vendorReply, removalReason } = input;

    const ratingLine =
      reviewRating !== null && reviewRating !== undefined
        ? `Review rating: ${reviewRating}/5`
        : 'Review rating: not provided';

    const vendorReplySection = vendorReply
      ? `\nVendor reply to this review:\n"${vendorReply}"`
      : '\n(No vendor reply)';

    const prompt = `You are a trust and safety specialist for Multideal, a Hebrew-first marketplace where local Israeli businesses offer discounted deals to customers.

A vendor has requested removal of the following customer review.

${ratingLine}
Review text:
"${reviewBody}"
${vendorReplySection}

Vendor's stated removal reason:
"${removalReason}"

Evaluate whether this review should be removed from the platform.

APPROVE_REMOVAL if the review clearly violates marketplace policy:
- Spam or promotional content unrelated to an actual purchase
- Hate speech, slurs, or personal attacks on individuals (not just criticism of service)
- Personal identifying information (phone numbers, full names of staff, addresses)
- Content that is entirely unrelated to the deal or business
- Fabricated review with no legitimate purchase (bot/competitor attack)

REJECT_REMOVAL if the review is legitimate customer feedback that should remain:
- Honest negative criticism of product quality, service, or value
- Complaints about wait times, staff attitude, cleanliness, or deal conditions
- Low star ratings with factual descriptions of the customer's experience
- Unflattering but truthful accounts - even very harsh ones

DEFER if the situation is genuinely ambiguous and a human admin should decide.

Respond with exactly this format (three lines):
DECISION: APPROVE_REMOVAL or REJECT_REMOVAL or DEFER
CONFIDENCE: a number between 0.0 and 1.0
EXPLANATION: one or two sentences explaining your recommendation`;

    try {
      const { text: raw } = await this.provider.generateText(this.creds, {
        model: this.model,
        prompt,
      });

      const upper = raw.toUpperCase();

      let shouldRemove: boolean;
      let confidence: number;

      if (upper.includes('DECISION: APPROVE_REMOVAL')) {
        shouldRemove = true;
        confidence = parseConfidence(raw);
      } else if (upper.includes('DECISION: REJECT_REMOVAL')) {
        shouldRemove = false;
        confidence = parseConfidence(raw);
      } else {
        // DEFER or unexpected response - send to human with low confidence
        shouldRemove = false;
        confidence = 0;
      }

      const explanationMatch = raw.match(/EXPLANATION:\s*(.+(?:\n.+)*)/i);
      const explanation = explanationMatch?.[1]?.trim() ?? raw;

      return { shouldRemove, confidence, explanation };
    } catch (err) {
      captureCaught(err, {
        scope: 'server.ai.agents.review-removal-prescoring',
        severity: 'warning',
      });
      // Fail safe: never auto-remove on error
      return {
        shouldRemove: false,
        confidence: 0,
        explanation: 'AI prescoring unavailable - deferred to human admin',
      };
    }
  };
}

/** Parse a numeric confidence value (0-1) from a Gemini text response. */
function parseConfidence(raw: string): number {
  const match = raw.match(/CONFIDENCE[:\s]+([0-9.]+)/i);
  if (match?.[1]) {
    const val = parseFloat(match[1]);
    if (!isNaN(val)) return Math.min(1, Math.max(0, val));
  }
  return 0.5;
}
