import { useContext, useLayoutEffect, useRef } from 'react'

import { PktButton } from '../../button/Button'
import { PktIcon } from '../../icon/Icon'
import { PktTextarea } from '../../textarea/Textarea'
import { FileItem, PktFileUploadContext, TQueueItemOperation, TQueueOperationContext } from '../types'

const COMMENTS_ATTRIBUTE = 'comments'

export interface IComment {
  text: string
  timestamp: string
}

const formatTimestamp = (iso: string): string => {
  const date = new Date(iso)
  if (Number.isNaN(date.getTime())) return iso
  const day = String(date.getDate()).padStart(2, '0')
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const year = date.getFullYear()
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  return `${day}.${month}.${year} kl. ${hours}:${minutes}`
}

const AddComment = ({
  fileItem,
  disabled,
  closeOperationUi,
  onAddComment,
  existingComment,
}: {
  fileItem: FileItem
  disabled: boolean
  closeOperationUi: () => void
  onAddComment: (comment: IComment) => void
  existingComment?: IComment
}) => {
  const inputRef = useRef<HTMLTextAreaElement>(null)
  const isEditing = !!existingComment

  const handleAddComment = () => {
    const text = inputRef.current?.value?.trim()
    if (text) {
      onAddComment({ text, timestamp: new Date().toISOString() })
    }
    closeOperationUi()
  }

  useLayoutEffect(() => {
    const t = setTimeout(() => inputRef.current?.focus({ preventScroll: true }), 0)
    return () => clearTimeout(t)
  }, [fileItem.fileId])

  return (
    <>
      <PktTextarea
        autoFocus
        label={isEditing ? 'Rediger kommentar' : 'Legg til kommentar'}
        name={`comment-${fileItem.fileId}`}
        className="pkt-fileupload__queue-display__item__comment-input"
        placeholder="Skriv inn kommentar"
        rows={2}
        id={`comment-${fileItem.fileId}`}
        ref={inputRef}
        disabled={disabled}
        defaultValue={existingComment?.text}
      />

      <PktButton skin="secondary" size="small" disabled={disabled} onClick={handleAddComment}>
        {isEditing ? 'Lagre kommentar' : 'Legg til kommentar'}
      </PktButton>
      <PktButton skin="tertiary" size="small" disabled={disabled} onClick={closeOperationUi}>
        Avbryt
      </PktButton>
    </>
  )
}

const ShowComment = ({
  comment,
  disabled,
  onDeleteComment,
  onEditComment,
}: {
  comment: IComment
  disabled: boolean
  onDeleteComment: () => void
  onEditComment: () => void
}) => (
  <div className="pkt-fileupload__queue-display__item__comments">
    <div className="pkt-fileupload__queue-display__item__comment">
      <div className="pkt-fileupload__queue-display__item__comment__content">
        <span className="pkt-fileupload__queue-display__item__comment__text" aria-label="Kommentar tekst">
          {comment.text}
        </span>
        <time className="pkt-fileupload__queue-display__item__comment__time">
          {formatTimestamp(comment.timestamp)}
        </time>
      </div>
      <div className="pkt-fileupload__queue-display__item__comment__actions">
        <button
          type="button"
          className="pkt-fileupload__queue-display__item__comment__action"
          onClick={onEditComment}
          disabled={disabled}
          aria-label="Rediger kommentar"
        >
          <PktIcon name="edit" />
        </button>
        <button
          type="button"
          className="pkt-fileupload__queue-display__item__comment__action"
          onClick={onDeleteComment}
          disabled={disabled}
          aria-label="Slett kommentar"
        >
          <PktIcon name="trash-can" />
        </button>
      </div>
    </div>
  </div>
)

const CommentHiddenInput = ({ comments }: { comments: IComment[] | undefined }) => {
  const context = useContext(PktFileUploadContext)
  return (
    <input
      type="hidden"
      name={`${context.name}-comments`}
      value={comments ? JSON.stringify(comments) : ''}
    />
  )
}

const getComments = (context: TQueueOperationContext): IComment[] =>
  context.getAttribute<IComment[]>(COMMENTS_ATTRIBUTE) ?? []

export const addCommentOperation: TQueueItemOperation = {
  id: 'comment',
  title: (fileItem) => {
    const comments = (fileItem.attributes?.[COMMENTS_ATTRIBUTE] as IComment[] | undefined) ?? []
    return comments.length > 0 ? '' : 'Legg til kommentar'
  },
  ariaLabel: 'Legg til kommentar',
  renderExtendedUI: (context) => {
    const existingComment = getComments(context)[0]
    return (
      <AddComment
        fileItem={context.file}
        disabled={context.disabled}
        closeOperationUi={context.close}
        onAddComment={(comment) => {
          context.setAttribute(COMMENTS_ATTRIBUTE, [comment])
        }}
        existingComment={existingComment}
      />
    )
  },
  renderContent: (context) => {
    if (context.isActive) return null
    const comment = getComments(context)[0]
    if (!comment) return null
    return (
      <ShowComment
        comment={comment}
        disabled={context.disabled}
        onEditComment={context.activate}
        onDeleteComment={() => context.setAttribute(COMMENTS_ATTRIBUTE, undefined)}
      />
    )
  },
  renderHidden: (context) => (
    <CommentHiddenInput key={`comments${context.file.fileId}`} comments={context.getAttribute<IComment[]>(COMMENTS_ATTRIBUTE)} />
  ),
}
