import { IS_WORDPRESS, PLUGIN_REST_ENDPOINTS, getRestNonce } from '../constants';

export type ChatAttachmentSource = 'user_upload' | 'site_media' | 'rendered_screenshot';
export type ChatAttachmentDetail = 'auto' | 'low' | 'high';

export interface ChatAttachmentInput {
  kind: 'image';
  source: ChatAttachmentSource;
  attachment_id?: number;
  name: string;
  mime: string;
  url?: string;
  width?: number;
  height?: number;
  detail: ChatAttachmentDetail;
  data_url: string;
}

export interface UploadedImageAttachment {
  attachmentId?: number;
  name: string;
  mime: string;
  url?: string;
  width?: number;
  height?: number;
  dataUrl: string;
}

const SUPPORTED_IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/webp', 'image/gif']);

export function isSupportedImageFile(file: File): boolean {
  return SUPPORTED_IMAGE_MIME_TYPES.has(file.type);
}

function readFileAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      if (typeof reader.result === 'string') resolve(reader.result);
      else reject(new Error('FileReader did not return a data URL'));
    };
    reader.onerror = () => reject(reader.error ?? new Error('Failed to read image file'));
    reader.readAsDataURL(file);
  });
}

async function uploadToWordPressMediaLibrary(file: File): Promise<Omit<UploadedImageAttachment, 'dataUrl'>> {
  const body = new FormData();
  body.append('file', file);

  const response = await fetch(PLUGIN_REST_ENDPOINTS.attachments, {
    method: 'POST',
    credentials: 'include',
    headers: { 'X-WP-Nonce': getRestNonce() },
    body,
  });
  if (!response.ok) {
    throw new Error('Failed to upload image attachment');
  }
  const payload = await response.json();
  return {
    attachmentId: typeof payload.attachment_id === 'number' ? payload.attachment_id : undefined,
    name: typeof payload.name === 'string' && payload.name.trim() ? payload.name : file.name,
    mime: typeof payload.mime === 'string' && payload.mime ? payload.mime : file.type,
    url: typeof payload.url === 'string' ? payload.url : undefined,
    width: typeof payload.width === 'number' ? payload.width : undefined,
    height: typeof payload.height === 'number' ? payload.height : undefined,
  };
}

export async function uploadImageAttachment(file: File): Promise<UploadedImageAttachment> {
  if (!isSupportedImageFile(file)) {
    throw new Error('Unsupported image type');
  }

  const dataUrl = await readFileAsDataUrl(file);
  if (!IS_WORDPRESS) {
    return {
      name: file.name,
      mime: file.type,
      dataUrl,
    };
  }

  const media = await uploadToWordPressMediaLibrary(file);
  return { ...media, dataUrl };
}

export function composerAttachmentToChatInput(attachment: {
  attachmentId?: number;
  name: string;
  mime: string;
  url?: string;
  width?: number;
  height?: number;
  dataUrl?: string;
}): ChatAttachmentInput | null {
  if (!attachment.dataUrl) return null;
  return {
    kind: 'image',
    source: 'user_upload',
    attachment_id: attachment.attachmentId,
    name: attachment.name,
    mime: attachment.mime,
    url: attachment.url,
    width: attachment.width,
    height: attachment.height,
    detail: 'auto',
    data_url: attachment.dataUrl,
  };
}
