import {
  Button,
  ButtonGroup,
  Field,
  FieldLabel,
  ModalBody,
  ModalFooter,
  ModalHeader,
  Select,
  TextInput,
} from "@contentstack/venus-components"
import React, { ChangeEvent, useEffect, useState } from "react"
import { Path } from "slate"

import type {
  IRteElementType,
  IRteParam,
} from "@contentstack/app-sdk/dist/src/RTE/types"
import FocalPointPicker from "~/shared-components/FocalPointPicker"

import type { FocalPoint, InsertResponse } from "~/types/imagevault"

enum DropdownValues {
  center = "center",
  left = "left",
  right = "right",
  none = "none",
}

type DropDownItem = {
  label: string
  value: DropdownValues
  type: string
}

const dropdownList: DropDownItem[] = [
  {
    label: "None",
    value: DropdownValues.none,
    type: "select",
  },
  {
    label: "Center",
    value: DropdownValues.center,
    type: "select",
  },
  {
    label: "Left",
    value: DropdownValues.left,
    type: "select",
  },
  {
    label: "Right",
    value: DropdownValues.right,
    type: "select",
  },
]

type ImageEditModalProps = {
  element: IRteElementType & {
    attrs: InsertResponse
  }
  rte: IRteParam
  closeModal: () => void
  path: Path
}

export default function ImageEditModal({
  element,
  closeModal,
  path,
  rte,
}: ImageEditModalProps) {
  const [alignment, setAlignment] = useState<DropDownItem>({
    label: "None",
    value: DropdownValues.none,
    type: "select",
  })
  const [altText, setAltText] = useState("")
  const [caption, setCaption] = useState("")
  const [focalPoint, setFocalPoint] = useState<FocalPoint>({ x: 50, y: 50 })

  const assetUrl = element.attrs.MediaConversions[0].Url

  useEffect(() => {
    if (element.attrs.Metadata && element.attrs.Metadata.length) {
      const altText = element.attrs.Metadata.find((meta) =>
        meta.Name.includes("AltText_")
      )?.Value

      const caption = element.attrs.Metadata.find((meta) =>
        meta.Name.includes("Title_")
      )?.Value

      setAltText(altText ?? "")
      setCaption(caption ?? "")
    }
  }, [element.attrs.Metadata])

  useEffect(() => {
    if (element.attrs.FocalPoint) {
      setFocalPoint(element.attrs.FocalPoint)
    }
  }, [element.attrs.FocalPoint])

  function handleSave() {
    let newStyle

    switch (alignment.value) {
      case DropdownValues.center:
      case DropdownValues.left:
      case DropdownValues.right:
        newStyle = {
          textAlign: alignment.value,
          maxWidth: element.attrs.width
            ? `${element.attrs.width}px`
            : undefined,
        }
        break
      case DropdownValues.none:
      default:
        newStyle = {}
        break
    }

    const metaData = element.attrs.Metadata ?? []

    const newMetadata = metaData.map((meta) => {
      if (meta.Name.includes("AltText_")) {
        return { ...meta, Value: altText }
      }
      if (meta.Name.includes("Title_")) {
        return { ...meta, Value: caption }
      }
      return meta
    })

    rte._adv.Transforms?.setNodes<IRteElementType>(
      rte._adv.editor,
      {
        attrs: {
          ...element.attrs,
          Metadata: newMetadata,
          position: alignment.value,
          style: { ...element.attrs.style, ...newStyle },
          FocalPoint: focalPoint,
        },
      },
      { at: path }
    )

    closeModal()
  }

  function changeFocalPoint(focalPoint: FocalPoint) {
    setFocalPoint(focalPoint)
  }

  return (
    <>
      <ModalHeader title="Update image" closeModal={closeModal} />
      <ModalBody
        style={{
          display: "grid",
          gridTemplateColumns: "1fr minmax(max-content, 250px)",
          gap: "1rem",
          alignItems: "center",
          width: "auto",
          maxHeight: "calc(90dvh - 124px)", // 124px is the height of the header and footer
          maxWidth: "90dvw",
          overflow: "auto",
        }}
      >
        <FocalPointPicker
          imageSrc={assetUrl}
          focalPoint={focalPoint}
          onChange={changeFocalPoint}
        />
        <div>
          <Field>
            {/* @ts-expect-error: Type incompatibility with Venus components */}
            <Select
              selectLabel="Alignment"
              value={alignment}
              onChange={(e: DropDownItem) => {
                setAlignment(e)
              }}
              options={dropdownList}
            />
          </Field>
          <Field>
            <FieldLabel htmlFor="alt">Alt text</FieldLabel>
            <TextInput
              value={altText}
              placeholder="Alt text for image"
              name="alt"
              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                setAltText(e.target.value)
              }
            />
          </Field>

          <Field>
            <FieldLabel htmlFor="caption">Caption</FieldLabel>
            <TextInput
              value={caption}
              placeholder="Caption for image..."
              name="caption"
              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                setCaption(e.target.value)
              }
            />
          </Field>

          <Field>
            <FieldLabel htmlFor="focalPoint">Focal Point</FieldLabel>
            <TextInput
              value={`X: ${focalPoint.x}, Y: ${focalPoint.y}`}
              name="focalPoint"
              disabled
            />
          </Field>
        </div>
      </ModalBody>
      <ModalFooter>
        <ButtonGroup>
          <Button onClick={closeModal} buttonType="light">
            Cancel
          </Button>
          <Button onClick={handleSave} icon="SaveWhite">
            Save
          </Button>
        </ButtonGroup>
      </ModalFooter>
    </>
  )
}
