import type { ArtifactResultCardProps, FieldConfidenceListProps } from "../types";
import type { ParsedArtifactCandidate, ParsedField } from "../../../../lib/artifactOcrParser";
import type { ReviewSampleRecord } from "../../../../types/global";

export interface FieldConfidenceRowModel {
  label: string;
  field: ParsedField;
  confidenceClassName: string;
}

export interface ScanResultCardModel {
  levelField: ParsedField;
  quality: {
    label: string;
    className: string;
  };
  fieldRows: FieldConfidenceRowModel[];
  levelText: string;
  equippedText: string;
  substats: string[];
  noSubstatsText: string;
}

export interface ReviewSampleCardModel {
  artifactTitle: string;
  reasonText: string;
  sourceText: string;
  captureTargetText: string | null;
  resolutionText: string;
  gridText: string;
  ocrCountText: string;
  parsedSlotText: string;
  parsedMainText: string;
  parsedSetText: string;
  parsedEquippedText: string;
  savedAtText: string;
  showParsed: boolean;
  ocrRows: Array<{ id: string; label: string; text: string }>;
}

export function useFieldConfidenceRowsModel({ parsedArtifact }: FieldConfidenceListProps): FieldConfidenceRowModel[] {
  const rows: Array<[string, ParsedField]> = [
    ["Name", parsedArtifact.fields.name],
    ["Slot", parsedArtifact.fields.slot],
    ["Level", getLevelField(parsedArtifact)],
    ["Main", mergeField(parsedArtifact.fields.mainStat, parsedArtifact.fields.mainValue)],
    ["Set", parsedArtifact.fields.setName],
    ["Equipped", parsedArtifact.fields.equipped],
    ["Substats", parsedArtifact.fields.substats],
  ];

  return rows.map(([label, field]) => ({
    label,
    field,
    confidenceClassName: resolveFieldConfidenceClass(field),
  }));
}

export function useScanResultCardModel({
  parsed,
}: Pick<ArtifactResultCardProps, "parsed">): ScanResultCardModel {
  const substats = parsed.substats;

  return {
    levelField: getLevelField(parsed),
    quality: resolveQuality(parsed.confidence),
    fieldRows: [
      ["Name", parsed.fields.name],
      ["Slot", parsed.fields.slot],
      ["Level", getLevelField(parsed)],
      ["Main", mergeField(parsed.fields.mainStat, parsed.fields.mainValue)],
      ["Set", parsed.fields.setName],
      ["Equipped", parsed.fields.equipped],
      ["Substats", parsed.fields.substats],
    ].map(([label, field]) => ({
      label,
      field,
      confidenceClassName: resolveFieldConfidenceClass(field),
    })),
    levelText: resolveLevelText(parsed),
    equippedText: resolveEquippedText(parsed.equipped),
    substats,
    noSubstatsText: "Keine Substats gelesen",
  };
}

export function useReviewSampleCardModel({ entry }: { entry: ReviewSampleRecord }): ReviewSampleCardModel {
  const parsed = entry.sample?.parsed as Partial<ParsedArtifactCandidate> | undefined;
  const capture = entry.sample?.capture;
  const ocr = capture?.ocr ?? [];
  const grid = capture?.inventoryGrid;

  const date = new Date(entry.savedAt);
  const savedAtText = Number.isNaN(date.getTime()) ? "Unbekannter Zeitpunkt" : date.toLocaleString();

  return {
    artifactTitle: parsed?.name || "Unparsed capture",
    reasonText: entry.sample?.reason || "manual",
    sourceText: capture?.name || "Unknown source",
    captureTargetText: capture?.captureTarget || null,
    resolutionText: `${capture?.width ?? "?"}x${capture?.height ?? "?"}`,
    gridText: grid ? `${grid.cols}x${grid.rows} grid ${grid.confidence}%` : "no grid",
    ocrCountText: `${ocr.length} OCR fields`,
    parsedSlotText: parsed?.slot || "Unknown slot",
    parsedMainText: `${parsed?.mainStat || "Unknown main"} ${parsed?.mainValue || ""}`,
    parsedSetText: parsed?.setName || "Unknown set",
    parsedEquippedText: parsed?.equipped || "Not detected",
    savedAtText,
    showParsed: Boolean(parsed),
    ocrRows: ocr.slice(0, 4).map((item) => ({
      id: item.id,
      label: item.label,
      text: `${item.label}: ${item.confidence}%`,
    })),
  };
}

function getLevelField(parsedArtifact: ParsedArtifactCandidate): ParsedField {
  const fieldLevel = parsedArtifact.fields.level;
  if (fieldLevel?.value) {
    return fieldLevel;
  }

  const derivedLevel = parsedArtifact.level;
  return {
    value: `${derivedLevel}`,
    confidence: derivedLevel > 0 ? 80 : 0,
    source: derivedLevel > 0 ? "derived" : "missing",
  };
}

function resolveQuality(confidence: number): { label: string; className: string } {
  return confidence >= 85
    ? { label: "Sauber gelesen", className: "good" }
    : confidence >= 70
      ? { label: "Etwas unsicher", className: "mid" }
      : { label: "Unsicher - bitte prüfen", className: "low" };
}

function mergeField(primary: ParsedField, secondary: ParsedField): ParsedField {
  const confidence = primary.value && secondary.value
    ? Math.round((primary.confidence + secondary.confidence) / 2)
    : Math.min(primary.confidence, secondary.confidence);
  const source = primary.source === secondary.source
    ? primary.source
    : primary.source === "missing"
      ? secondary.source
      : primary.source;
  return {
    value: `${primary.value} ${secondary.value}`.trim(),
    confidence,
    source,
  };
}

function resolveFieldConfidenceClass(field: ParsedField): string {
  return field.confidence < 70 ? "low" : field.confidence < 86 ? "medium" : "high";
}

function resolveLevelText(parsed: ParsedArtifactCandidate): string {
  return parsed.level > 0 ? `Level +${parsed.level}` : "Level nicht erkannt";
}

function resolveEquippedText(equipped: string | null | undefined): string {
  return equipped && equipped !== "Not detected" ? `Ausgerüstet: ${equipped}` : "Nicht Ausgerüstet / nicht erkannt";
}
