import { z } from "zod"

import { makeImageVaultImage } from "@/utils/imageVault"

const metaData = z.object({
  DefinitionType: z.number().nullable().optional(),
  Description: z.string().nullable(),
  LanguageId: z.number().nullable(),
  MetadataDefinitionId: z.number(),
  Name: z.string(),
  Value: z.string().nullable(),
})

export const focalPointSchema = z.object({
  x: z.number(),
  y: z.number(),
})

/**
 * Defines a media asset, original or conversion
 */
const mediaConversion = z.object({
  /**
   * Aspect ratio of the conversion
   */
  AspectRatio: z.number(),
  /**
   * Content type of the conversion
   */
  ContentType: z.string(),
  /**
   * Aspect ratio of the selected/requested format
   */
  FormatAspectRatio: z.number(),
  /**
   * Height of the selected/requested format
   */
  FormatHeight: z.number(),
  /**
   * Width of the selected/requested format
   */
  FormatWidth: z.number(),
  /**
   * Height, in pixels, of the conversion
   */
  Height: z.number(),
  /**
   * Html representing the conversion
   */
  Html: z.string(),
  /**
   * Id of the selected media format
   */
  MediaFormatId: z.number(),
  /**
   * Name of the media format
   */
  MediaFormatName: z.string(),
  /**
   * Name of the conversion
   */
  Name: z.string(),
  /**
   * The url to the conversion
   */
  Url: z.string(),
  /**
   * Width, in pixels, of the conversion
   */
  Width: z.number(),
})

/**
 * The response from ImageVault when inserting an asset
 */
export const imageVaultAssetSchema = z.object({
  /**
   * The media item id of the asset
   */
  Id: z.number(),
  /**
   * The id of the vault where the asset resides
   */
  VaultId: z.number(),
  /**
   * The name of the asset
   */
  Name: z.string(),
  /**
   * The conversion selected by the user. Is an array but will only contain one object
   */
  MediaConversions: z.array(mediaConversion),
  Metadata: z.array(metaData),
  /**
   * Date when the asset was added to ImageVault
   */
  DateAdded: z.string(),
  /**
   * Name of the user that added the asset to ImageVault
   */
  AddedBy: z.string(),
  FocalPoint: focalPointSchema.optional(),
})

export const imageVaultAssetTransformedSchema = imageVaultAssetSchema.transform(
  (rawData) => {
    const alt = rawData.Metadata?.find((meta) =>
      meta.Name.includes("AltText_")
    )?.Value

    const caption = rawData.Metadata?.find((meta) =>
      meta.Name.includes("Title_")
    )?.Value
    const mediaConversion = rawData.MediaConversions[0]
    const aspectRatio =
      mediaConversion.FormatAspectRatio ||
      mediaConversion.AspectRatio ||
      mediaConversion.Width / mediaConversion.Height

    return {
      url: mediaConversion.Url,
      id: rawData.Id,
      meta: {
        alt,
        caption,
      },
      title: rawData.Name,
      dimensions: {
        width: mediaConversion.Width,
        height: mediaConversion.Height,
        aspectRatio,
      },
      focalPoint: rawData.FocalPoint || { x: 50, y: 50 },
    }
  }
)

export const tempImageVaultAssetSchema = imageVaultAssetSchema
  .optional()
  .or(
    // Temp since there is a bug in Contentstack
    // sending empty objects when there has been an
    // image selected previously but has since been
    // deleted
    z.object({})
  )
  .transform((data) => {
    if (data) {
      if ("Name" in data) {
        return makeImageVaultImage(data)
      }
    }
    return undefined
  })
