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

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

const service = "pdfmonkey";

const jsonValueSchema = s.anyOf("A JSON object, JSON string, or null value.", [
  s.looseObject("A JSON object value."),
  s.string("A JSON string value."),
  { type: "null" },
]);

const documentStatusSchema = s.stringEnum("The current PDFMonkey document status.", [
  "draft",
  "pending",
  "generating",
  "success",
  "failure",
]);

const documentCreateStatusSchema = s.stringEnum(
  "The PDFMonkey creation status. Use pending to queue generation immediately.",
  ["draft", "pending"],
);

const currentUserSchema = s.object("Normalized PDFMonkey current user details.", {
  id: s.nonEmptyString("The PDFMonkey current_user identifier."),
  availableDocuments: s.nullableInteger("The number of available documents remaining for the account."),
  createdAt: s.nonEmptyString("The ISO 8601 timestamp when the account was created."),
  currentPlan: s.nullableString("The current billing plan name."),
  currentPlanInterval: s.nullableString("The current billing interval name."),
  desiredName: s.nullableString("The display name configured for the account."),
  email: s.nullableString("The account email address."),
  lang: s.nullableString("The account language code."),
  payingCustomer: s.nullableBoolean("Whether the current account is a paying customer."),
  trialEndsOn: s.nullableString("The account trial end date when present."),
  updatedAt: s.nonEmptyString("The ISO 8601 timestamp when the account was last updated."),
  blockResources: s.nullableBoolean("Whether resource blocking is enabled for generated documents."),
  shareLinks: s.nullableBoolean("Whether public share links are enabled for the account."),
});

const generationLogSchema = s.object("A PDFMonkey generation log entry.", {
  type: s.nonEmptyString("The log entry type returned by PDFMonkey."),
  message: s.nonEmptyString("The log entry message."),
  timestamp: s.nonEmptyString("The timestamp recorded for this generation log entry."),
});

const documentCardSchema = s.object("A normalized PDFMonkey document card.", {
  id: s.nonEmptyString("The document identifier."),
  appId: s.nonEmptyString("The workspace identifier that owns the document."),
  createdAt: s.nonEmptyString("The ISO 8601 timestamp when the document was created."),
  documentTemplateId: s.nonEmptyString("The template identifier used by the document."),
  documentTemplateIdentifier: s.nullableString("The human-readable template identifier when present."),
  downloadUrl: s.nullableString("The signed download URL for the generated file."),
  failureCause: s.nullableString("The upstream failure message when generation failed."),
  filename: s.nullableString("The generated filename when available."),
  meta: jsonValueSchema,
  outputType: s.nonEmptyString("The generated output type such as pdf or image."),
  previewUrl: s.nullableString("The preview URL for the generated document when available."),
  publicShareLink: s.nullableString("The public share URL when sharing is enabled."),
  status: documentStatusSchema,
  updatedAt: s.nonEmptyString("The ISO 8601 timestamp when the document was last updated."),
});

const documentSchema = s.object("A normalized full PDFMonkey document.", {
  ...(documentCardSchema.properties as Record<string, object>),
  checksum: s.nullableString("The checksum reported for the document payload."),
  generationLogs: s.array("The generation log entries returned by PDFMonkey.", generationLogSchema),
  payload: jsonValueSchema,
});

const paginationSchema = s.object("Pagination metadata returned by PDFMonkey list endpoints.", {
  currentPage: s.integer("The current page number."),
  nextPage: s.nullableInteger("The next page number when another page exists."),
  prevPage: s.nullableInteger("The previous page number when a previous page exists."),
  totalPages: s.integer("The total number of pages available."),
});

const documentTemplateCardSchema = s.object("A normalized PDFMonkey document template card.", {
  id: s.nonEmptyString("The template identifier."),
  appId: s.nonEmptyString("The workspace identifier that owns the template."),
  identifier: s.nonEmptyString("The human-readable template identifier."),
  editionMode: s.nonEmptyString("The template edition mode."),
  outputType: s.nonEmptyString("The output type used by documents generated from this template."),
  templateFolderId: s.nullableString("The folder identifier used to group the template."),
  ttl: s.number("The time-to-live in seconds for documents generated by this template."),
  createdAt: s.nonEmptyString("The ISO 8601 timestamp when the template was created."),
  updatedAt: s.nonEmptyString("The ISO 8601 timestamp when the template was last updated."),
  previewUrl: s.nullableString("The preview URL for the template when available."),
});

const documentTemplateSchema = s.object("A normalized full PDFMonkey document template.", {
  ...(documentTemplateCardSchema.properties as Record<string, object>),
  body: s.string("The published HTML and Liquid body."),
  bodyDraft: s.string("The draft HTML and Liquid body."),
  scssStyle: s.string("The published CSS or SCSS styles."),
  scssStyleDraft: s.string("The draft CSS or SCSS styles."),
  sampleData: s.string("The published sample data string."),
  sampleDataDraft: s.string("The draft sample data string."),
  settings: s.looseObject("The published PDFMonkey template settings object."),
  settingsDraft: s.looseObject("The draft PDFMonkey template settings object."),
  pdfEngineId: s.nullableString("The published PDF engine identifier."),
  pdfEngineDraftId: s.nullableString("The draft PDF engine identifier."),
  checksum: s.nullableString("The checksum returned for this template."),
});

export type PdfmonkeyActionName =
  | "get_current_user"
  | "create_document"
  | "get_document_card"
  | "list_document_cards"
  | "get_document"
  | "list_document_template_cards"
  | "get_document_template";

export const pdfmonkeyActions: ActionDefinition[] = [
  defineProviderAction(service, {
    name: "get_current_user",
    description: "Get the current PDFMonkey account resolved by the provided API key.",
    requiredScopes: [],
    inputSchema: s.object("No input parameters are required for this action.", {}),
    outputSchema: s.object("The normalized output payload for the get_current_user action.", {
      currentUser: currentUserSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "create_document",
    description:
      "Create a PDFMonkey document and optionally queue generation immediately by setting status to pending.",
    requiredScopes: [],
    inputSchema: s.object(
      "Input parameters for creating a PDFMonkey document.",
      {
        documentTemplateId: s.nonEmptyString("The template UUID used for generation."),
        payload: s.anyOf("The JSON object or JSON string passed to PDFMonkey as the document payload.", [
          s.looseObject("A JSON object value."),
          s.string("A JSON string value."),
        ]),
        meta: s.anyOf("The JSON object or JSON string passed to PDFMonkey as document metadata.", [
          s.looseObject("A JSON object value."),
          s.string("A JSON string value."),
        ]),
        status: documentCreateStatusSchema,
      },
      { optional: ["payload", "meta", "status"] },
    ),
    outputSchema: s.object("The normalized output payload for the create_document action.", {
      document: documentSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "get_document_card",
    description: "Get one PDFMonkey document card for lightweight status polling without the full payload.",
    requiredScopes: [],
    inputSchema: s.object("Input parameters for retrieving one PDFMonkey document card.", {
      documentId: s.nonEmptyString("The document UUID to fetch as a document card."),
    }),
    outputSchema: s.object("The normalized output payload for the get_document_card action.", {
      documentCard: documentCardSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "list_document_cards",
    description:
      "List PDFMonkey document cards with optional filters for template, status, workspace, update time, and search text.",
    requiredScopes: [],
    inputSchema: s.object(
      "Input parameters for listing PDFMonkey document cards.",
      {
        pageNumber: s.positiveInteger("The 1-based page number to request."),
        documentTemplateId: s.nonEmptyString(
          "Filter documents by one template UUID or comma-separated template UUIDs.",
        ),
        status: documentStatusSchema,
        workspaceId: s.nonEmptyString("Filter documents by workspace UUID."),
        updatedSince: s.nonEmptyString("Only return documents updated after this Unix timestamp or ISO 8601 string."),
        search: s.nonEmptyString("Search by document UUID or filename."),
      },
      { optional: ["pageNumber", "documentTemplateId", "status", "workspaceId", "updatedSince", "search"] },
    ),
    outputSchema: s.object("The normalized output payload for the list_document_cards action.", {
      documentCards: s.array("The PDFMonkey document cards returned for the request.", documentCardSchema),
      pagination: paginationSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "get_document",
    description: "Get one full PDFMonkey document including its payload and generation logs.",
    requiredScopes: [],
    inputSchema: s.object("Input parameters for retrieving one full PDFMonkey document.", {
      documentId: s.nonEmptyString("The document UUID to retrieve."),
    }),
    outputSchema: s.object("The normalized output payload for the get_document action.", {
      document: documentSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "list_document_template_cards",
    description:
      "List PDFMonkey document template cards for one workspace with optional folder, page, and sort filters.",
    requiredScopes: [],
    inputSchema: s.object(
      "Input parameters for listing PDFMonkey document template cards.",
      {
        workspaceId: s.nonEmptyString("The workspace UUID to list templates from."),
        folders: s.nonEmptyString("An optional comma-separated folder list, none, or all."),
        page: s.positiveInteger("The 1-based page number to request."),
        sort: s.nonEmptyString("The template sort expression accepted by PDFMonkey."),
      },
      { optional: ["folders", "page", "sort"] },
    ),
    outputSchema: s.object("The normalized output payload for the list_document_template_cards action.", {
      documentTemplateCards: s.array(
        "The PDFMonkey document template cards returned for the request.",
        documentTemplateCardSchema,
      ),
      pagination: paginationSchema,
    }),
  }),
  defineProviderAction(service, {
    name: "get_document_template",
    description: "Get one full PDFMonkey document template including draft and published fields.",
    requiredScopes: [],
    inputSchema: s.object("Input parameters for retrieving one full PDFMonkey document template.", {
      templateId: s.nonEmptyString("The template UUID to retrieve."),
    }),
    outputSchema: s.object("The normalized output payload for the get_document_template action.", {
      documentTemplate: documentTemplateSchema,
    }),
  }),
];
