import querystring from 'node:querystring'

const getUsername = (data) => {
  return data.user.emailAddress
}

export const isGsuiteFile = (mimeType) => {
  return mimeType?.startsWith('application/vnd.google')
}

const isSharedDrive = (item) => {
  return item.kind === 'drive#drive'
}

const isFolder = (item) => {
  return (
    item.mimeType === 'application/vnd.google-apps.folder' ||
    isSharedDrive(item)
  )
}

export const isShortcut = (mimeType) => {
  return mimeType === 'application/vnd.google-apps.shortcut'
}

const getItemSize = (item) => {
  return parseInt(item.size, 10)
}

const getItemIcon = (item) => {
  if (isSharedDrive(item)) {
    const size = '=w16-h16-n'
    const sizeParamRegex = /=[-whncsp0-9]*$/
    return item.backgroundImageLink.match(sizeParamRegex)
      ? item.backgroundImageLink.replace(sizeParamRegex, size)
      : `${item.backgroundImageLink}${size}`
  }

  if (
    item.thumbnailLink &&
    !item.mimeType.startsWith('application/vnd.google')
  ) {
    const smallerThumbnailLink = item.thumbnailLink.replace('s220', 's40')
    return smallerThumbnailLink
  }

  return item.iconLink
}

const getItemSubList = (item) => {
  const allowedGSuiteTypes = [
    'application/vnd.google-apps.document',
    'application/vnd.google-apps.drawing',
    'application/vnd.google-apps.script',
    'application/vnd.google-apps.spreadsheet',
    'application/vnd.google-apps.presentation',
    'application/vnd.google-apps.shortcut',
  ]

  return item.files.filter((i) => {
    return (
      isFolder(i) ||
      !isGsuiteFile(i.mimeType) ||
      allowedGSuiteTypes.includes(i.mimeType)
    )
  })
}

const getItemName = (item) => {
  const extensionMaps = {
    'application/vnd.google-apps.document': '.docx',
    'application/vnd.google-apps.drawing': '.png',
    'application/vnd.google-apps.script': '.json',
    'application/vnd.google-apps.spreadsheet': '.xlsx',
    'application/vnd.google-apps.presentation': '.ppt',
  }

  const extension = extensionMaps[item.mimeType]
  if (extension && item.name && !item.name.endsWith(extension)) {
    return item.name + extension
  }

  return item.name ? item.name : '/'
}

export const getGsuiteExportType = (mimeType) => {
  const typeMaps = {
    'application/vnd.google-apps.document':
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.google-apps.drawing': 'image/png',
    'application/vnd.google-apps.script':
      'application/vnd.google-apps.script+json',
    'application/vnd.google-apps.spreadsheet':
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.google-apps.presentation':
      'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  }

  return typeMaps[mimeType] || 'application/pdf'
}

function getMimeType2(mimeType) {
  if (isGsuiteFile(mimeType)) {
    return getGsuiteExportType(mimeType)
  }
  return mimeType
}

const getMimeType = (item) => {
  if (isShortcut(item.mimeType)) {
    return getMimeType2(item.shortcutDetails.targetMimeType)
  }
  return getMimeType2(item.mimeType)
}

const getItemId = (item) => {
  return item.id
}

const getItemRequestPath = (item) => {
  return item.id
}

const getItemModifiedDate = (item) => {
  return item.modifiedTime
}

const getItemThumbnailUrl = (item) => {
  return item.thumbnailLink
}

const getNextPagePath = (data, currentQuery, currentPath) => {
  if (!data.nextPageToken) {
    return null
  }
  const query = { ...currentQuery, cursor: data.nextPageToken }
  return `${currentPath}?${querystring.stringify(query)}`
}

const getImageHeight = (item) => item.imageMediaMetadata?.height

const getImageWidth = (item) => item.imageMediaMetadata?.width

const getImageRotation = (item) => item.imageMediaMetadata?.rotation

const getImageDate = (item) => item.imageMediaMetadata?.date

const getVideoHeight = (item) => item.videoMediaMetadata?.height

const getVideoWidth = (item) => item.videoMediaMetadata?.width

const getVideoDurationMillis = (item) => item.videoMediaMetadata?.durationMillis

// Hopefully this name will not be used by Google
export const VIRTUAL_SHARED_DIR = 'shared-with-me'

export const adaptData = (
  listFilesResp,
  sharedDrivesResp,
  directory,
  query,
  showSharedWithMe,
  about,
) => {
  const adaptItem = (item) => ({
    isFolder: isFolder(item),
    icon: getItemIcon(item),
    name: getItemName(item),
    mimeType: getMimeType(item),
    id: getItemId(item),
    thumbnail: getItemThumbnailUrl(item),
    requestPath: getItemRequestPath(item),
    modifiedDate: getItemModifiedDate(item),
    size: getItemSize(item),
    custom: {
      isSharedDrive: isSharedDrive(item),
      imageHeight: getImageHeight(item),
      imageWidth: getImageWidth(item),
      imageRotation: getImageRotation(item),
      imageDateTime: getImageDate(item),
      videoHeight: getVideoHeight(item),
      videoWidth: getVideoWidth(item),
      videoDurationMillis: getVideoDurationMillis(item),
    },
  })

  const items = getItemSubList(listFilesResp)
  const sharedDrives = sharedDrivesResp ? sharedDrivesResp.drives || [] : []

  // “Shared with me” is a list of shared documents,
  // not the same as sharedDrives
  const virtualItem = showSharedWithMe && {
    isFolder: true,
    icon: 'folder',
    name: 'Shared with me',
    mimeType: 'application/vnd.google-apps.folder',
    id: VIRTUAL_SHARED_DIR,
    requestPath: VIRTUAL_SHARED_DIR,
  }

  const adaptedItems = [
    ...(virtualItem ? [virtualItem] : []), // shared folder first
    ...[...sharedDrives, ...items].map(adaptItem),
  ]

  return {
    username: getUsername(about),
    items: adaptedItems,
    nextPagePath: getNextPagePath(listFilesResp, query, directory),
  }
}
