import type { FileWithHandle } from 'browser-fs-access';

import type { DConversationId } from '~/common/stores/chat/chat.conversation';
import type { DMessageAttachmentFragment, DMessageFragment } from '~/common/stores/chat/chat.fragments';
import type { DMessageId } from '~/common/stores/chat/chat.message';


// Attachment Draft

export type AttachmentDraft = {
  readonly id: AttachmentDraftId;
  readonly source: AttachmentDraftSource,
  label: string;  // what's written in the button, such as a web page `title`
  ref: string;    // will be used in ```ref\n...``` for instance the web page `url`

  inputLoading: boolean;
  inputError: string | null;
  input?: AttachmentDraftInput;

  // options to convert the input
  converters: AttachmentDraftConverter[]; // List of available converters for this attachment

  outputsConverting: boolean;
  outputsConversionProgress: number | null;
  outputFragments: DMessageAttachmentFragment[];

  // Warnings for poor conversions (e.g. scanned PDF with text extraction rather than OCR)
  outputWarnings?: string[];

  // Tracks what method was actually used (especially for Auto mode)
  outputsHeuristic?: {
    isAuto: boolean;
    actualConverterId: AttachmentDraftConverterType;
    explain?: string; // e.g., "42 chars/page detected"
  };

  // metadata: {
  //   creationDate?: Date; // Creation date of the file
  //   modifiedDate?: Date; // Last modified date of the file
  //   altText?: string; // Alternative text for images for screen readers
  // };
};

export type AttachmentDraftId = string;

export type AttachmentCreationOptions = {
  /** Also attach an image representation of the attachment. Requires Release.Features.ENABLE_TEXT_AND_IMAGES as well. */
  hintAddImages?: boolean;
}

export type AttachmentCloudProviderId = 'gdrive' | 'onedrive' | 'dropbox';


// 0. draft source (filled at the onset)

export type AttachmentDraftSource = {
  media: 'url';
  origin: AttachmentDraftSourceOriginUrl;
  url: string; // parsed valid url
  refUrl: string; // original url literal text (use this as text ref, otherwise use the url)
} | {
  media: 'file';
  origin: AttachmentDraftSourceOriginFile,
  fileWithHandle: FileWithHandle;
  refPath: string; // original file name, or path/to/file name
} | {
  media: 'text';
  method: 'clipboard-read' | AttachmentDraftSourceOriginDTO;
  textPlain?: string;
  textHtml?: string;
} | {
  media: 'cloud';
  origin: AttachmentDraftSourceOriginCloud;

  // auth for fetching
  accessToken: string;
  // tokenExpiresAt?: number; // optional for staleness detection, unix ts

  // recipe for fetching
  provider: AttachmentCloudProviderId;
  fileId: string;
  mimeType: string; // cloud-native MIME (e.g., 'application/vnd.google-apps.document')

  // decorative
  fileName: string;
  fileSize?: number;
  webViewLink?: string; // link to view in cloud provider's UI
} | {
  // special type for attachments thar are references to self (ego, application) objects
  media: 'ego';
  method: 'ego-fragments';
  label: string;
  egoFragmentsInputData: DraftEgoFragmentsInputData;
};

export type AttachmentDraftSourceOriginFile =
  | 'camera' | 'screencapture'
  | 'live-feed-camera' | 'live-feed-screen'
  | 'file-open'
  | 'clipboard-read'
  | AttachmentDraftSourceOriginDTO;

export type AttachmentDraftSourceOriginDTO = 'drop' | 'paste';

export type AttachmentDraftSourceOriginUrl = 'input-link' | 'clipboard-read' | AttachmentDraftSourceOriginDTO;

export type AttachmentDraftSourceOriginCloud = `picker-${AttachmentCloudProviderId}`;


// 1. draft input (loaded from the source)

export type AttachmentDraftInput = {
  mimeType: string; // Original MIME type of the file, or application specific type
  data: string | Blob | DraftWebInputData | DraftYouTubeInputData | DraftEgoFragmentsInputData; // The original data of the attachment
  dataSize?: number; // Size of the original data (for plain/simple 1:1 mime)
  altMimeType?: string; // Alternative MIME type for the input
  altData?: string; // Alternative data for the input
  // [media:URL] special for download inputs
  urlImage?: {
    imgDataUrl: string;
    mimeType: string;
    width: number;
    height: number;
    // to discriminate the source
    generator: 'web-capture' | 'youtube-thumbnail';
    timestamp: number; // Unix timestamp
  };
  // preview?: AttachmentPreview; // Preview of the input
};

export type DraftWebInputData = {
  pageText?: string;
  pageMarkdown?: string;
  pageCleanedHtml?: string;
  pageTitle?: string;
}

export type DraftYouTubeInputData = {
  videoId: string;
  videoTitle: string;
  videoDescription: string;
  videoThumbnailUrl: string;
  videoTranscript: string;
}

export type DraftEgoFragmentsInputData = {
  fragments: DMessageFragment[];
  conversationTitle: string;
  conversationId: DConversationId;
  messageId: DMessageId;
}


// 2. draft converters (UI options to convert the input)

export type AttachmentDraftConverter = {
  id: AttachmentDraftConverterType;
  name: string;
  disabled?: boolean;
  unsupported?: boolean;
  isCheckbox?: boolean; // renders as checkbox and is not exclusive with the others

  // runtime properties
  isActive?: boolean; // checked, for both radio (mutually exclusive) and checkbox (additional) converters

  // outputType: ComposerOutputPartType; // The type of the output after conversion
  // isAutonomous: boolean; // Whether the conversion does not require user input
  // isAsync: boolean; // Whether the conversion is asynchronous
  // progress: number; // Conversion progress percentage (0..1)
  // errorMessage?: string; // Error message if the conversion failed
}

export type AttachmentDraftConverterType =
  | 'text' | 'text-cleaner' | 'text-markdown'
  | 'rich-text' | 'rich-text-cleaner' | 'rich-text-markdown' | 'rich-text-table'
  | 'image-original' | 'image-resized-high' | 'image-resized-low' | 'image-ocr' | 'image-caption' | 'image-to-default'
  | 'pdf-auto' | 'pdf-text' | 'pdf-images' | 'pdf-images-ocr' | 'pdf-text-and-images'
  | 'docx-to-html'
  | 'url-page-text' | 'url-page-markdown' | 'url-page-html' | 'url-page-null' | 'url-page-image'
  | 'youtube-transcript' | 'youtube-transcript-simple'
  | 'ego-fragments-inlined'
  | 'unhandled';


// 3. Output - this is done via DMessageAttachmentFragment[], to be directly compatible with our data


// Actions on attachment drafts

export type AttachmentDraftsAction = 'inline-text' | 'copy-text';


/*export type AttachmentDraftPreview = {
  renderer: 'noPreview',
  title: string; // A title for the preview
} | {
  renderer: 'textPreview'
  fileName: string; // The name of the file
  snippet: string; // A text snippet for documents
  tooltip?: string; // A tooltip for the preview
} | {
  renderer: 'imagePreview'
  thumbnail: string; // A thumbnail preview for images, videos, etc.
  tooltip?: string; // A tooltip for the preview
};*/
