"use client"

import {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
  type CSSProperties,
} from "react"
import { Star, Reply, ReplyAll, Forward } from "lucide-react"
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip"
import { cn } from "@/lib/utils"
import {
  avatarColor,
  cleanSenderName,
  senderInitial,
} from "@/lib/sender-display"
import type { Email, EmailAttachment } from "@/lib/email-data"
import type { FolderTreeNode, LabelRowItem } from "@/lib/sidebar-nav-data"
import {
  useComposeActions,
  useComposeDrafts,
  useComposeWindows,
  DEFAULT_IDENTITIES,
  type ThreadComposeKind,
  type ComposeOpenPreset,
  savedThreadDraftToComposePreset,
} from "@/lib/compose-context"
import {
  buildThreadComposePreset,
  withTouchFullscreenComposePreset,
} from "@/lib/thread-compose-preset"
import { openConversationPrint } from "@/lib/print-conversation"
import { resolveParsedCalendarInvitation } from "@/lib/resolve-email-calendar-invitation"
import { ComposeWindow } from "@/components/gmail/compose-modal"
import { CalendarInvitationPreview } from "@/components/gmail/calendar-invitation-preview"
import { EmailViewSubjectHeader } from "./email-view/email-view-header"
import {
  MAIL_PREVIEW_SCROLL_CLASS,
  MAIL_REPLY_BAR_CLASS,
  MAIL_REPLY_BUTTON_CLASS,
} from "@/lib/mail-chrome-classes"
import {
  CollapsedMessage,
  ExpandedMessage,
  SpamWhyBanner,
} from "@/components/gmail/email-view/email-view-messages"

interface EmailViewProps {
  email: Email
  onToggleStar: (id: string) => void
  isStarred: boolean
  onNavigateToLabel?: (label: string) => void
  /** Message spam : bannière + pastille sujet ; bouton « non-spam » */
  onNotSpam?: () => void
  /** Si défini, les pastilles libellé dont la fonction retourne false sont masquées (préférences barre latérale). */
  showLabelChip?: (label: string) => boolean
  labelBgByText?: Map<string, string>
  emailLabelToSidebarFolderId?: Record<string, string>
  getNavItemPrefs?: (id: string) => { messages: string }
  folderTree?: FolderTreeNode[]
  labelRows?: readonly LabelRowItem[]
  /** Id dossier / libellé courant — masque la pastille du dossier actif (comme en liste). */
  currentFolderId?: string
  /** Fil complet (mode message isolé hors conversation). */
  threadRoot?: Email | null
  /** Affiche uniquement le message courant avec option d’ouvrir le fil. */
  isSingleMessageView?: boolean
}

/* ── Main EmailView component ── */

export function EmailView({
  email,
  onToggleStar,
  isStarred,
  onNavigateToLabel,
  onNotSpam,
  showLabelChip,
  labelBgByText,
  emailLabelToSidebarFolderId = {},
  getNavItemPrefs = () => ({ messages: "show" }),
  folderTree,
  labelRows,
  currentFolderId,
  threadRoot = null,
  isSingleMessageView = false,
}: EmailViewProps) {
  const [showFullThread, setShowFullThread] = useState(false)
  const threadForReplies = threadRoot ?? email
  const priorCount = Math.max(
    0,
    (threadForReplies.threadMessageIds?.length ?? 1) - 1
  )
  const showRepliesCta =
    isSingleMessageView && !showFullThread && priorCount > 0

  const conversation =
    isSingleMessageView && !showFullThread
      ? []
      : (showFullThread ? threadForReplies.conversation : email.conversation) ?? []
  const hasConversation = conversation.length > 0
  const isSpamMessage = email.spam === true

  // Track which conversation messages are expanded (by index).
  // By default all previous messages are collapsed, only the last (main) is expanded.
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())

  const toggleExpanded = (msgId: string) => {
    setExpandedIds((prev) => {
      const next = new Set(prev)
      if (next.has(msgId)) {
        next.delete(msgId)
      } else {
        next.add(msgId)
      }
      return next
    })
  }

  const mainSenderName = cleanSenderName(email.sender)
  const mainSenderAddr = email.senderEmail || `${mainSenderName.toLowerCase().replace(/\s+/g, ".")}@example.com`

  const { composeWindows } = useComposeWindows()
  const { savedThreadReplyDrafts } = useComposeDrafts()
  const { openComposeWithInitial } = useComposeActions()
  const inlineCompose = useMemo(
    () =>
      composeWindows.find(
        (c) => c.placement === "inline" && c.threadEmailId === email.id
      ),
    [composeWindows, email.id]
  )

  const mainMessageAttachments = useMemo((): EmailAttachment[] => {
    if (email.attachments && email.attachments.length > 0) return email.attachments
    if (email.hasAttachment) return [{ name: "Pièce jointe", kind: "other" }]
    return []
  }, [email.attachments, email.hasAttachment])

  const savedThreadDraft = savedThreadReplyDrafts[email.id]
  const hasInlineForThread = Boolean(inlineCompose)
  const showReplyForwardBar = !inlineCompose

  const previewScrollRef = useRef<HTMLDivElement>(null)
  const threadComposeAnchorRef = useRef<HTMLDivElement>(null)

  const scrollThreadComposeIntoView = useCallback(() => {
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        threadComposeAnchorRef.current?.scrollIntoView({
          behavior: "smooth",
          block: "end",
          inline: "nearest",
        })
      })
    })
  }, [])

  const openThreadCompose = useCallback(
    (preset: ComposeOpenPreset) => {
      const resolved = withTouchFullscreenComposePreset(preset)
      openComposeWithInitial(resolved)
      if (resolved.placement === "inline") {
        scrollThreadComposeIntoView()
      }
    },
    [openComposeWithInitial, scrollThreadComposeIntoView]
  )

  useEffect(() => {
    if (!savedThreadDraft || hasInlineForThread) return
    openThreadCompose(savedThreadDraftToComposePreset(savedThreadDraft))
  }, [
    email.id,
    savedThreadDraft,
    hasInlineForThread,
    openThreadCompose,
  ])

  const startThreadCompose = useCallback(
    (kind: ThreadComposeKind) => {
      openThreadCompose(buildThreadComposePreset(email, kind))
    },
    [email, openThreadCompose]
  )

  const selfIdentity = DEFAULT_IDENTITIES[0]
  const selfName = cleanSenderName(selfIdentity.name)

  const calendarInvitation = useMemo(
    () => resolveParsedCalendarInvitation(email),
    [email]
  )

  return (
    <TooltipProvider delayDuration={400}>
      <div className="flex min-h-0 min-w-0 flex-1 flex-col">
        <div ref={previewScrollRef} className={MAIL_PREVIEW_SCROLL_CLASS}>
        {/* Spacer for floating nav buttons on xs */}
        <div className="h-[52px] shrink-0 bg-mail-surface sm:hidden" aria-hidden />
        <EmailViewSubjectHeader
          email={email}
          isSpamMessage={isSpamMessage}
          onNotSpam={onNotSpam}
          onNavigateToLabel={onNavigateToLabel}
          showLabelChip={showLabelChip}
          labelBgByText={labelBgByText}
          emailLabelToSidebarFolderId={emailLabelToSidebarFolderId}
          getNavItemPrefs={getNavItemPrefs}
          folderTree={folderTree}
          labelRows={labelRows}
          currentFolderId={currentFolderId}
        />

        {calendarInvitation ? (
          <CalendarInvitationPreview invitation={calendarInvitation} />
        ) : null}

        {isSpamMessage && <SpamWhyBanner onNotSpam={onNotSpam} />}

        {showRepliesCta ? (
          <div className="border-b border-border px-6 py-3 max-sm:px-4">
            <button
              type="button"
              onClick={() => setShowFullThread(true)}
              className="text-sm font-medium text-primary hover:underline"
            >
              {priorCount === 1
                ? "Afficher la réponse"
                : `Afficher les ${priorCount} réponses`}
            </button>
          </div>
        ) : null}

        {/* Conversation messages */}
        {/* Previous messages in conversation */}
        {hasConversation && conversation.map((msg) => {
          const isExpanded = expandedIds.has(msg.id)

          if (isExpanded) {
            return (
              <div key={msg.id} className="border-b border-border">
                <ExpandedMessage
                  sender={msg.sender}
                  senderEmail={msg.senderEmail}
                  dateIso={msg.date}
                  body={msg.body}
                  isSpam={false}
                  isLast={false}
                  starred={false}
                  attachments={msg.attachments ?? []}
                  onCollapse={() => toggleExpanded(msg.id)}
                  onPrintConversation={() => openConversationPrint(email)}
                />
              </div>
            )
          }

          return (
            <div key={msg.id} className="border-b border-[#eceff1]">
              <CollapsedMessage
                message={msg}
                onClick={() => toggleExpanded(msg.id)}
              />
            </div>
          )
        })}

        {/* Last / main message — always expanded */}
        <ExpandedMessage
          sender={mainSenderName}
          senderEmail={mainSenderAddr}
          dateIso={email.date}
          body={email.body || `<p style="color:var(--muted-foreground);">${email.preview}</p>`}
          isSpam={email.spam === true}
          isLast={true}
          starred={isStarred}
          attachments={mainMessageAttachments}
          onToggleStar={() => onToggleStar(email.id)}
          onPrintConversation={() => openConversationPrint(email)}
        />

        {showReplyForwardBar ? (
            <div
              className={cn(
                "z-10 mt-4 hidden flex-wrap items-center gap-x-3 gap-y-2 px-4 pb-6 pl-[68px] sm:flex",
                "max-sm:static sm:sticky sm:bottom-0",
                MAIL_REPLY_BAR_CLASS
              )}
            >
              <button
                type="button"
                onClick={() => startThreadCompose("reply")}
                className={MAIL_REPLY_BUTTON_CLASS}
              >
                <Reply className="h-[18px] w-[18px] shrink-0 text-muted-foreground" strokeWidth={1.5} />
                Répondre
              </button>
              <button
                type="button"
                onClick={() => startThreadCompose("replyAll")}
                className={MAIL_REPLY_BUTTON_CLASS}
              >
                <ReplyAll className="h-[18px] w-[18px] shrink-0 text-muted-foreground" strokeWidth={1.5} />
                Répondre à tous
              </button>
              <button
                type="button"
                onClick={() => startThreadCompose("forward")}
                className={MAIL_REPLY_BUTTON_CLASS}
              >
                <Forward className="h-[18px] w-[18px] shrink-0 text-muted-foreground" strokeWidth={1.5} />
                Transférer
              </button>
            </div>
        ) : null}

        {inlineCompose ? (
          <div ref={threadComposeAnchorRef} className="mt-6 px-4 pb-6 pl-[68px] max-sm:pl-4">
              <div className="flex items-start gap-3">
                <div
                  className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-sm font-bold text-white"
                  style={{ backgroundColor: avatarColor(selfName) }}
                  aria-hidden
                >
                  {senderInitial(selfName)}
                </div>
                <div className="min-w-0 flex-1">
                  <ComposeWindow
                    key={inlineCompose.id}
                    compose={inlineCompose}
                    threadSourceEmail={email}
                  />
                </div>
              </div>
            </div>
        ) : null}

        </div>
      </div>
    </TooltipProvider>
  )
}
