import type { ActionDefinition, JsonSchema } from "../../core/types.ts";

import { s } from "../../core/json-schema.ts";
import { defineProviderAction } from "../../core/provider-definition.ts";

const service = "winston_ai";

const textOrUrlProperties: Record<string, JsonSchema> = {
  text: s.string("The text to scan. Winston AI documents a minimum length for reliable results."),
  fileUrl: s.url("A publicly accessible PDF, DOC, or DOCX URL for Winston AI to scan."),
  websiteUrl: s.url("A publicly accessible website URL for Winston AI to scan."),
  language: s.string("A two-letter language code supported by the endpoint, or auto to let Winston AI detect it."),
};
const statusSchema = s.integer("The HTTP status code reported by Winston AI.");
const creditsUsedSchema = s.integer("The number of Winston AI credits used by the request.");
const creditsRemainingSchema = s.integer("The number of Winston AI credits remaining after the request.");
const inputTypeSchema = s.string("The input type scanned by Winston AI, such as text, file, or website.");
const attackDetectedSchema = s.looseObject(
  "Signals for zero-width space or homoglyph attacks detected in scanned text.",
  {
    zero_width_space: s.boolean("Whether zero-width spaces were detected."),
    homoglyph_attack: s.boolean("Whether homoglyph attacks were detected."),
  },
);
const scanInformationSchema = s.looseObject("Basic metadata about a Winston AI plagiarism scan.", {
  service: s.string("The Winston AI service name used for the request."),
  scanTime: s.string("The timestamp when the scan was conducted."),
  inputType: inputTypeSchema,
  language: s.string("The language detected for the scanned text."),
});
const plagiarismSequenceSchema = s.looseObject("A plagiarized text sequence location.", {
  startIndex: s.number("The starting index of the plagiarized sequence."),
  endIndex: s.number("The ending index of the plagiarized sequence."),
  sequence: s.nullable(s.string("The plagiarized text sequence.")),
});

export const winstonAiActions: ActionDefinition[] = [
  defineProviderAction(service, {
    name: "detect_ai_text",
    description:
      "Detect whether text, a public document URL, or a public website URL was likely generated by AI with Winston AI.",
    inputSchema: s.actionInput(
      {
        ...textOrUrlProperties,
        version: s.string("The Winston AI model version to use, such as 4.14 or latest."),
        sentences: s.boolean("Whether Winston AI should include sentence-level scores."),
      },
      [],
      "Input for detecting whether content was likely generated by AI with Winston AI. Provide one of text, fileUrl, or websiteUrl.",
    ),
    outputSchema: s.looseObject("The Winston AI AI text detection response.", {
      status: statusSchema,
      score: s.integer(
        "Human score from 0 to 100. Lower values indicate AI-like text and higher values indicate human-like text.",
      ),
      sentences: s.unknown("Sentence-level score details returned by Winston AI."),
      input: inputTypeSchema,
      attack_detected: attackDetectedSchema,
      readability_score: s.integer("Readability score from 0 to 100."),
      credits_used: creditsUsedSchema,
      credits_remaining: creditsRemainingSchema,
      version: s.string("The Winston AI model version used for the prediction."),
      language: s.string("The detected or specified language code."),
    }),
  }),
  defineProviderAction(service, {
    name: "check_plagiarism",
    description: "Check text, a public document URL, or a public website URL for plagiarism with Winston AI.",
    inputSchema: s.actionInput(
      {
        ...textOrUrlProperties,
        excluded_sources: s.array(
          "Domains or URLs to exclude from the plagiarism score.",
          s.string("A domain or URL to exclude from the plagiarism score."),
        ),
        country: s.string("The country code of the country where the text was written."),
      },
      [],
      "Input for checking content plagiarism with Winston AI. Provide one of text, fileUrl, or websiteUrl.",
    ),
    outputSchema: s.looseObject("The Winston AI plagiarism response.", {
      status: s.number("The HTTP status code reported by Winston AI."),
      scanInformation: scanInformationSchema,
      result: s.looseObject("Summary scores from a Winston AI plagiarism scan.", {
        score: s.number("The percentage of plagiarized content in the scanned text."),
        sourceCounts: s.number("The number of sources containing matching content."),
        textWordCounts: s.number("The total number of words in the scanned text."),
        totalPlagiarismWords: s.number("The total number of words identified as plagiarized."),
      }),
      sources: s.array("Sources matched during the plagiarism scan.", s.unknownObject("A matched source.")),
      attackDetected: attackDetectedSchema,
      text: s.string("The input text used for the plagiarism scan."),
      similarWords: s.array("Similar words found in the input text.", s.unknownObject("A similar word match.")),
      citations: s.array("Sources cited in the provided text.", s.string("A cited source URL.")),
      indexes: s.array("Plagiarism sequences found in the input text.", plagiarismSequenceSchema),
      credits_used: creditsUsedSchema,
      credits_remaining: creditsRemainingSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "fact_check",
    description: "Verify claims in text, a public document URL, or a public website URL with Winston AI.",
    inputSchema: s.actionInput(
      textOrUrlProperties,
      [],
      "Input for fact-checking content with Winston AI. Provide one of text, fileUrl, or websiteUrl.",
    ),
    outputSchema: s.looseObject("The Winston AI fact-check response.", {
      status: statusSchema,
      claims: s.array(
        "Claims detected in the text with fact-checking results.",
        s.looseObject("A fact-check result for a claim in the input text.", {
          id: s.integer("The unique identifier of the input sentence."),
          sentence: s.string("The exact input sentence from which the claim was extracted."),
          claim: s.string("The distinct claim checked by Winston AI."),
          verdict: s.string("The fact-checking verdict for the claim."),
          score: s.integer("The confidence score from 0 to 100 for the verdict."),
          explanation: s.string("The explanation for the verdict."),
          links: s.array("Sources supporting the claim result.", s.unknownObject("A supporting reference.")),
        }),
      ),
      score: s.integer("Overall confidence score from 0 to 100 that the provided text is accurate."),
      claimsCount: s.integer("The number of claims extracted from the text."),
      text: s.string("The full original text that was analyzed."),
      sentences: s.array("Sentences from the analyzed text.", s.unknownObject("An extracted sentence.")),
      input: inputTypeSchema,
      language: s.string("The detected or specified input language."),
      creditsUsed: s.integer("The number of credits used to process the request."),
      creditsRemaining: s.integer("The number of credits remaining for the account."),
      wordCount: s.integer("The word count of the input text."),
    }),
  }),
  defineProviderAction(service, {
    name: "compare_texts",
    description: "Compare two texts and return similarity signals from Winston AI.",
    inputSchema: s.actionInput(
      {
        first_text: s.string("The first text to compare.", { maxLength: 120_000 }),
        second_text: s.string("The second text to compare against the first text.", { maxLength: 120_000 }),
      },
      ["first_text", "second_text"],
      "Input for comparing two texts with Winston AI.",
    ),
    outputSchema: s.looseObject("The Winston AI text comparison response.", {
      status: statusSchema,
      similarity_score: s.number("Overall similarity score from 0 to 100 between the two texts."),
      first_text: s.unknownObject("Similarity details for the first compared text."),
      second_text: s.unknownObject("Similarity details for the second compared text."),
      credits_used: creditsUsedSchema,
      credits_remaining: creditsRemainingSchema,
    }),
  }),
];

export type WinstonAiActionName = "detect_ai_text" | "check_plagiarism" | "fact_check" | "compare_texts";
