import { TextractIcon } from '@/components/icons'
import {
  AuthMode,
  type BlockConfig,
  type BlockMeta,
  IntegrationType,
  type SubBlockType,
} from '@/blocks/types'
import { createVersionedToolSelector, normalizeFileInput } from '@/blocks/utils'
import type { TextractParserOutput } from '@/tools/textract/types'

export const TextractBlock: BlockConfig<TextractParserOutput> = {
  type: 'textract',
  name: 'AWS Textract',
  description: 'Extract text, tables, and forms from documents',
  hideFromToolbar: true,
  authMode: AuthMode.ApiKey,
  longDescription: `Integrate AWS Textract into your workflow to extract text, tables, forms, and key-value pairs from documents. Single-page mode supports JPEG, PNG, and single-page PDF. Multi-page mode supports multi-page PDF and TIFF.`,
  docsLink: 'https://docs.sim.ai/integrations/textract',
  category: 'tools',
  integrationType: IntegrationType.AI,
  bgColor: 'linear-gradient(135deg, #055F4E 0%, #56C0A7 100%)',
  iconColor: '#56C0A7',
  icon: TextractIcon,
  subBlocks: [
    {
      id: 'processingMode',
      title: 'Processing Mode',
      type: 'dropdown' as SubBlockType,
      options: [
        { id: 'sync', label: 'Single Page (JPEG, PNG, 1-page PDF)' },
        { id: 'async', label: 'Multi-Page (PDF, TIFF via S3)' },
      ],
      tooltip:
        'Single Page uses synchronous API for JPEG, PNG, or single-page PDF. Multi-Page uses async API for multi-page PDF/TIFF stored in S3.',
    },
    {
      id: 'fileUpload',
      title: 'Document',
      type: 'file-upload' as SubBlockType,
      canonicalParamId: 'document',
      acceptedTypes: 'image/jpeg,image/png,application/pdf',
      placeholder: 'Upload JPEG, PNG, or single-page PDF (max 10MB)',
      condition: {
        field: 'processingMode',
        value: 'async',
        not: true,
      },
      mode: 'basic',
      maxSize: 10,
    },
    {
      id: 'filePath',
      title: 'Document',
      type: 'short-input' as SubBlockType,
      canonicalParamId: 'document',
      placeholder: 'URL to JPEG, PNG, or single-page PDF',
      condition: {
        field: 'processingMode',
        value: 'async',
        not: true,
      },
      mode: 'advanced',
    },
    {
      id: 's3Uri',
      title: 'S3 URI',
      type: 'short-input' as SubBlockType,
      placeholder: 's3://bucket-name/path/to/document.pdf',
      condition: {
        field: 'processingMode',
        value: 'async',
      },
    },
    {
      id: 'region',
      title: 'AWS Region',
      type: 'short-input' as SubBlockType,
      placeholder: 'e.g., us-east-1',
      required: true,
    },
    {
      id: 'accessKeyId',
      title: 'AWS Access Key ID',
      type: 'short-input' as SubBlockType,
      placeholder: 'Enter your AWS Access Key ID',
      password: true,
      required: true,
    },
    {
      id: 'secretAccessKey',
      title: 'AWS Secret Access Key',
      type: 'short-input' as SubBlockType,
      placeholder: 'Enter your AWS Secret Access Key',
      password: true,
      required: true,
    },
    {
      id: 'extractTables',
      title: 'Extract Tables',
      type: 'switch' as SubBlockType,
    },
    {
      id: 'extractForms',
      title: 'Extract Forms (Key-Value Pairs)',
      type: 'switch' as SubBlockType,
    },
    {
      id: 'detectSignatures',
      title: 'Detect Signatures',
      type: 'switch' as SubBlockType,
    },
    {
      id: 'analyzeLayout',
      title: 'Analyze Document Layout',
      type: 'switch' as SubBlockType,
    },
  ],
  tools: {
    access: ['textract_parser'],
    config: {
      tool: () => 'textract_parser',
      params: (params) => {
        if (!params.accessKeyId || params.accessKeyId.trim() === '') {
          throw new Error('AWS Access Key ID is required')
        }
        if (!params.secretAccessKey || params.secretAccessKey.trim() === '') {
          throw new Error('AWS Secret Access Key is required')
        }
        if (!params.region || params.region.trim() === '') {
          throw new Error('AWS Region is required')
        }

        const processingMode = params.processingMode || 'sync'
        const parameters: Record<string, unknown> = {
          accessKeyId: params.accessKeyId.trim(),
          secretAccessKey: params.secretAccessKey.trim(),
          region: params.region.trim(),
          processingMode,
        }

        if (processingMode === 'async') {
          if (!params.s3Uri || params.s3Uri.trim() === '') {
            throw new Error('S3 URI is required for multi-page processing')
          }
          parameters.s3Uri = params.s3Uri.trim()
        } else {
          // document is the canonical param for both basic (fileUpload) and advanced (filePath) modes
          const documentInput = params.document
          if (!documentInput) {
            throw new Error('Document is required')
          }
          if (typeof documentInput === 'object') {
            parameters.file = documentInput
          } else if (typeof documentInput === 'string') {
            parameters.filePath = documentInput.trim()
          }
        }

        const featureTypes: string[] = []
        if (params.extractTables) featureTypes.push('TABLES')
        if (params.extractForms) featureTypes.push('FORMS')
        if (params.detectSignatures) featureTypes.push('SIGNATURES')
        if (params.analyzeLayout) featureTypes.push('LAYOUT')

        if (featureTypes.length > 0) {
          parameters.featureTypes = featureTypes
        }

        return parameters
      },
    },
  },
  inputs: {
    processingMode: { type: 'string', description: 'Document type: single-page or multi-page' },
    document: { type: 'json', description: 'Document input (file upload or URL reference)' },
    s3Uri: { type: 'string', description: 'S3 URI for multi-page processing (s3://bucket/key)' },
    extractTables: { type: 'boolean', description: 'Extract tables from document' },
    extractForms: { type: 'boolean', description: 'Extract form key-value pairs' },
    detectSignatures: { type: 'boolean', description: 'Detect signatures' },
    analyzeLayout: { type: 'boolean', description: 'Analyze document layout' },
    region: { type: 'string', description: 'AWS region' },
    accessKeyId: { type: 'string', description: 'AWS Access Key ID' },
    secretAccessKey: { type: 'string', description: 'AWS Secret Access Key' },
  },
  outputs: {
    blocks: {
      type: 'json',
      description: 'Array of detected blocks (PAGE, LINE, WORD, TABLE, CELL, KEY_VALUE_SET, etc.)',
    },
    documentMetadata: {
      type: 'json',
      description: 'Document metadata containing pages count',
    },
    modelVersion: {
      type: 'string',
      description: 'Version of the Textract model used for processing',
    },
  },
}

const textractV2Inputs = TextractBlock.inputs ? { ...TextractBlock.inputs } : {}
const textractV2SubBlocks = (TextractBlock.subBlocks || []).flatMap((subBlock) => {
  if (subBlock.id === 'filePath') {
    return [] // Remove the old filePath subblock
  }
  if (subBlock.id === 'fileUpload') {
    // Insert fileReference right after fileUpload
    return [
      subBlock,
      {
        id: 'fileReference',
        title: 'Document',
        type: 'short-input' as SubBlockType,
        canonicalParamId: 'document',
        placeholder: 'File reference',
        condition: {
          field: 'processingMode',
          value: 'async',
          not: true,
        },
        mode: 'advanced' as const,
      },
    ]
  }
  return [subBlock]
})

export const TextractV2Block: BlockConfig<TextractParserOutput> = {
  ...TextractBlock,
  type: 'textract_v2',
  name: 'AWS Textract',
  hideFromToolbar: false,
  subBlocks: textractV2SubBlocks,
  tools: {
    access: ['textract_parser_v2'],
    config: {
      tool: createVersionedToolSelector({
        baseToolSelector: () => 'textract_parser',
        suffix: '_v2',
        fallbackToolId: 'textract_parser_v2',
      }),
      params: (params) => {
        if (!params.accessKeyId || params.accessKeyId.trim() === '') {
          throw new Error('AWS Access Key ID is required')
        }
        if (!params.secretAccessKey || params.secretAccessKey.trim() === '') {
          throw new Error('AWS Secret Access Key is required')
        }
        if (!params.region || params.region.trim() === '') {
          throw new Error('AWS Region is required')
        }

        const processingMode = params.processingMode || 'sync'
        const parameters: Record<string, unknown> = {
          accessKeyId: params.accessKeyId.trim(),
          secretAccessKey: params.secretAccessKey.trim(),
          region: params.region.trim(),
          processingMode,
        }

        if (processingMode === 'async') {
          if (!params.s3Uri || params.s3Uri.trim() === '') {
            throw new Error('S3 URI is required for multi-page processing')
          }
          parameters.s3Uri = params.s3Uri.trim()
        } else {
          // document is the canonical param for both basic (fileUpload) and advanced (fileReference) modes
          const file = normalizeFileInput(params.document, { single: true })
          if (!file) {
            throw new Error('Document file is required')
          }
          parameters.file = file
        }

        const featureTypes: string[] = []
        if (params.extractTables) featureTypes.push('TABLES')
        if (params.extractForms) featureTypes.push('FORMS')
        if (params.detectSignatures) featureTypes.push('SIGNATURES')
        if (params.analyzeLayout) featureTypes.push('LAYOUT')

        if (featureTypes.length > 0) {
          parameters.featureTypes = featureTypes
        }

        return parameters
      },
    },
  },
  inputs: textractV2Inputs,
}

export const TextractBlockMeta = {
  tags: ['document-processing', 'ocr', 'cloud'],
  url: 'https://aws.amazon.com/textract',
  templates: [
    {
      icon: TextractIcon,
      title: 'Textract invoice extractor',
      prompt:
        'Create a scheduled workflow that polls an S3 folder for new PDFs, runs AWS Textract to extract line items and totals, writes the structured fields to a table, and flags invoices that fail validation.',
      modules: ['scheduled', 'tables', 'files', 'agent', 'workflows'],
      category: 'operations',
      tags: ['finance', 'automation'],
      alsoIntegrations: ['s3'],
    },
    {
      icon: TextractIcon,
      title: 'Receipt OCR for expense reports',
      prompt:
        'Build a workflow that processes Gmail attachments with AWS Textract, extracts vendor, date, total, and category, logs each receipt to an expense table, and tags reimbursable items.',
      modules: ['tables', 'files', 'agent', 'workflows'],
      category: 'operations',
      tags: ['finance', 'automation'],
      alsoIntegrations: ['gmail'],
    },
    {
      icon: TextractIcon,
      title: 'Textract ID verification',
      prompt:
        'Build a workflow that runs uploaded ID documents through AWS Textract analyze-id, extracts name, DOB, and ID number, validates against a customer record, and flags mismatches for review.',
      modules: ['tables', 'files', 'agent', 'workflows'],
      category: 'operations',
      tags: ['legal', 'automation'],
    },
    {
      icon: TextractIcon,
      title: 'Textract form-to-table',
      prompt:
        'Build a workflow that pushes scanned forms from Google Drive through AWS Textract analyze-document, extracts key-value pairs and tables, and writes structured rows to a Sim table for downstream automations.',
      modules: ['tables', 'files', 'agent', 'workflows'],
      category: 'operations',
      tags: ['automation', 'enterprise'],
      alsoIntegrations: ['google_drive'],
    },
    {
      icon: TextractIcon,
      title: 'Textract + Reducto cross-format extractor',
      prompt:
        'Create a workflow that ingests mixed PDF and image files, routes images through AWS Textract and dense PDFs through Reducto, normalizes fields, and writes rows to a table.',
      modules: ['files', 'tables', 'agent', 'workflows'],
      category: 'operations',
      tags: ['automation', 'analysis'],
      alsoIntegrations: ['reducto'],
    },
    {
      icon: TextractIcon,
      title: 'Textract + Extend pipeline composer',
      prompt:
        'Build a workflow that uses AWS Textract for layout-aware OCR and Extend for structured field extraction, fusing outputs into clean records for downstream automations.',
      modules: ['files', 'tables', 'agent', 'workflows'],
      category: 'operations',
      tags: ['finance', 'automation'],
      alsoIntegrations: ['extend'],
    },
    {
      icon: TextractIcon,
      title: 'Textract handwritten-note digitizer',
      prompt:
        'Build a workflow that runs scanned handwritten intake notes through AWS Textract, converts the recognized text into clean Markdown, indexes it into a knowledge base, and posts a confidence summary to Slack so low-confidence pages get a human review.',
      modules: ['files', 'knowledge-base', 'agent', 'workflows'],
      category: 'operations',
      tags: ['ocr', 'automation', 'enterprise'],
      alsoIntegrations: ['slack'],
    },
  ],
  skills: [
    {
      name: 'extract-invoice-fields',
      description:
        'Run an invoice or receipt through AWS Textract and return clean structured fields (vendor, date, totals, line items). Use when you need to digitize finance documents.',
      content:
        '# Extract Invoice Fields\n\nUse AWS Textract to pull structured data from an invoice or receipt image/PDF.\n\n## Steps\n1. Choose the processing mode: Single Page for JPEG, PNG, or one-page PDF; Multi-Page for multi-page PDF/TIFF staged in S3.\n2. Provide the document (upload, file reference, or S3 URI) and enable Extract Forms and Extract Tables so key-value pairs and line items are captured.\n3. Run the extraction and read the returned blocks (KEY_VALUE_SET, TABLE, CELL, LINE).\n4. Map key-value pairs to fields: vendor, invoice number, invoice date, due date, subtotal, tax, and total.\n5. Reconstruct line items from the TABLE/CELL blocks into rows with description, quantity, unit price, and amount.\n\n## Output\nReturn a clean JSON record with the header fields and a line-items array. Flag any field where Textract confidence is low or the totals do not reconcile so a human can review.',
    },
    {
      name: 'extract-form-key-values',
      description:
        'Turn a scanned form into structured key-value pairs and tables using AWS Textract. Use for intake forms, applications, and contracts.',
      content:
        '# Extract Form Key-Values\n\nDigitize a scanned form into structured data.\n\n## Steps\n1. Select Single Page mode for an image or one-page PDF, or Multi-Page mode with an S3 URI for longer documents.\n2. Enable Extract Forms (key-value pairs) and, if the form has tables, Extract Tables. Enable Analyze Document Layout for complex multi-column forms.\n3. Run the extraction and parse the KEY_VALUE_SET blocks into field-name to field-value pairs.\n4. Normalize field names (trim labels, lowercase keys) and coerce values like dates and numbers.\n\n## Output\nReturn a flat object of normalized field names to values, plus any extracted tables as arrays of rows. Note pages or fields with low confidence for review.',
    },
    {
      name: 'ocr-document-to-text',
      description:
        'Convert a scanned document or image into plain readable text with AWS Textract OCR. Use to digitize handwritten notes, faxes, or image-only PDFs for indexing or search.',
      content:
        '# OCR Document To Text\n\nExtract readable text from a scanned or image-only document.\n\n## Steps\n1. Pick the processing mode that matches the file: Single Page for an image or one-page PDF, Multi-Page (S3) for multi-page documents.\n2. Provide the document and run the extraction. Plain OCR does not require the Forms or Tables features.\n3. Read the LINE and WORD blocks and join LINE blocks in reading order to reconstruct the text.\n4. Preserve paragraph and page breaks using the PAGE blocks.\n\n## Output\nReturn the full extracted text as clean Markdown, grouped by page. Include the page count from document metadata and surface any low-confidence lines so they can be reviewed before indexing.',
    },
  ],
} as const satisfies BlockMeta
