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

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

const COMMENT_SYMBOL = Symbol('comment')

export interface IComment {
  text: string
  timestamp: Date
}

const formatTimestamp = (date: Date): string => {
  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,
  closeOperationUi,
  onAddComment,
  existingComment,
}: {
  fileItem: FileItem
  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(),
      })
    }
    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}
        defaultValue={existingComment?.text}
      />

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

const ShowComments = ({
  comments,
  onDeleteComment,
  onEditComment,
}: {
  comments?: IComment[]
  onDeleteComment?: (index: number) => void
  onEditComment?: (index: number) => void
}) =>
  comments && comments.length > 0 ? (
    <div className="pkt-fileupload__queue-display__item__comments">
      {comments.map((comment, index) => (
        <div key={index} 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">
            {onDeleteComment && (
              <button
                type="button"
                className="pkt-fileupload__queue-display__item__comment__action"
                onClick={() => onDeleteComment(index)}
                aria-label="Slett kommentar"
              >
                <PktIcon name="trash-can" />
              </button>
            )}
            {onEditComment && (
              <button
                type="button"
                className="pkt-fileupload__queue-display__item__comment__action"
                onClick={() => onEditComment(index)}
                aria-label="Rediger kommentar"
              >
                <PktIcon name="edit" />
              </button>
            )}
          </div>
        </div>
      ))}
    </div>
  ) : null

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

export const addCommentOperation = (attributes: TFileAttributes): TQueueItemOperation => {
  const commentsAttribute = attributes<IComment[]>('comments')

  const addComment = (fileId: string, newComment: IComment) => {
    commentsAttribute.set(fileId, [newComment])
  }

  const deleteComment = (fileId: string, commentIndex: number) => {
    const existingComments = commentsAttribute.get(fileId) || []
    const newComments = existingComments.filter((_, i) => i !== commentIndex)
    commentsAttribute.set(fileId, newComments.length > 0 ? newComments : undefined)
  }

  return {
    // Only show button text when no comment exists yet
    title: (fileItem: FileItem) => {
      const comments = commentsAttribute.get(fileItem.fileId)
      // If comment exists, return empty string to hide the button (icons are shown in renderContent)
      if (comments && comments.length > 0) return ''
      return 'Legg til kommentar'
    },
    renderExtendedUI: (fileItem: FileItem, closeOperationUi: () => void) => {
      const existingComments = commentsAttribute.get(fileItem.fileId)
      const existingComment = existingComments?.[0]
      return (
        <AddComment
          fileItem={fileItem}
          closeOperationUi={closeOperationUi}
          onAddComment={(comment) => addComment(fileItem.fileId, comment)}
          existingComment={existingComment}
        />
      )
    },
    renderContent: (fileItem: FileItem, activateOperation?: () => void, isOperationActive?: boolean) => {
      // Hide comment preview when editing
      if (isOperationActive) return null

      const comments = commentsAttribute.get(fileItem.fileId)
      return (
        <ShowComments
          comments={comments}
          onDeleteComment={(index) => deleteComment(fileItem.fileId, index)}
          onEditComment={activateOperation ? () => activateOperation() : undefined}
        />
      )
    },
    renderHidden: (fileItem: FileItem) => (
      <CommentHiddenInput key={`comments${fileItem.fileId}`} comments={commentsAttribute.get(fileItem.fileId)} />
    ),
    symbol: COMMENT_SYMBOL,
  }
}
