import { ArrowBigLeft, ArrowBigLeftDash, ArrowBigRight, ArrowBigRightDash } from "lucide-react";
import Button from "../../../components/Button";

export type MessagePreviewAttachment = {
  filename?: string | null;
  label?: string | null;
  detail?: string | null;
  contentType?: string | null;
  sizeBytes?: number | null;
  archiveGroup?: string | null;
  archiveLabel?: string | null;
};

export type MessagePreviewMetaItem = {
  label: string;
  value: React.ReactNode;
};

export type MessagePreviewNavigation = {
  index: number;
  total: number;
  onFirst: () => void;
  onPrevious: () => void;
  onNext: () => void;
  onLast: () => void;
};

export type MessagePreviewOverlayProps = {
  title?: string;
  subject?: string | null;
  bodyMode?: "text" | "html";
  text?: string | null;
  html?: string | null;
  recipientLabel?: React.ReactNode;
  recipientNote?: React.ReactNode;
  metaItems?: MessagePreviewMetaItem[];
  attachments?: MessagePreviewAttachment[];
  raw?: string | null;
  rawLabel?: string;
  navigation?: MessagePreviewNavigation;
  closeLabel?: string;
  onClose: () => void;
};

export default function MessagePreviewOverlay({
  title = "Message preview",
  subject,
  bodyMode = "text",
  text,
  html,
  recipientLabel,
  recipientNote,
  metaItems = [],
  attachments = [],
  raw,
  rawLabel = "Raw MIME",
  navigation,
  closeLabel = "Close",
  onClose
}: MessagePreviewOverlayProps) {
  const shownSubject = subject?.trim() || "No subject";
  const shownText = text?.trim() || "No plain-text body to preview.";
  const shownHtml = html?.trim() || "<p>No HTML body to preview.</p>";

  return (
    <div className="overlay-backdrop" role="dialog" aria-modal="true" aria-labelledby="message-preview-title">
      <div className="modal-panel template-preview-modal message-preview-modal">
        <header className="modal-header">
          <h2 id="message-preview-title">{title}</h2>
          <button className="modal-close" onClick={onClose}>×</button>
        </header>
        <div className="modal-body">
          {(recipientLabel || recipientNote || navigation) && (
            <div className="template-preview-toolbar">
              <div>
                {recipientLabel && <strong>{recipientLabel}</strong>}
                {recipientNote && <p className="muted small-note">{recipientNote}</p>}
              </div>
              {navigation && (
                <div className="button-row compact-actions template-preview-nav" aria-label="Preview message navigation">
                  <button type="button" className="version-arrow" onClick={navigation.onFirst} disabled={navigation.index <= 0} title="First message" aria-label="First message"><ArrowBigLeftDash aria-hidden="true" /></button>
                  <button type="button" className="version-arrow" onClick={navigation.onPrevious} disabled={navigation.index <= 0} title="Previous message" aria-label="Previous message"><ArrowBigLeft aria-hidden="true" /></button>
                  <span className="template-preview-count">{navigation.index + 1} / {navigation.total}</span>
                  <button type="button" className="version-arrow" onClick={navigation.onNext} disabled={navigation.index >= navigation.total - 1} title="Next message" aria-label="Next message"><ArrowBigRight aria-hidden="true" /></button>
                  <button type="button" className="version-arrow" onClick={navigation.onLast} disabled={navigation.index >= navigation.total - 1} title="Last message" aria-label="Last message"><ArrowBigRightDash aria-hidden="true" /></button>
                </div>
              )}
            </div>
          )}

          {metaItems.length > 0 && (
            <div className="detail-grid message-preview-meta">
              {metaItems.map((item) => (
                <div key={item.label}><span className="muted small-note">{item.label}</span><strong>{item.value || "—"}</strong></div>
              ))}
            </div>
          )}

          <div className="template-preview-box">
            <h3>{shownSubject}</h3>
            {bodyMode === "html" ? (
              <iframe className="template-preview-frame" title="Rendered HTML body preview" sandbox="" srcDoc={shownHtml} />
            ) : (
              <pre>{shownText}</pre>
            )}
          </div>

          <MessagePreviewAttachmentBoxes attachments={attachments} />

          {raw && (
            <details className="message-preview-raw">
              <summary>{rawLabel}</summary>
              <pre className="mock-message-raw">{raw}</pre>
            </details>
          )}
        </div>
        <footer className="modal-footer"><Button variant="primary" onClick={onClose}>{closeLabel}</Button></footer>
      </div>
    </div>
  );
}

function MessagePreviewAttachmentBoxes({ attachments }: { attachments: MessagePreviewAttachment[] }) {
  const direct = attachments.filter((attachment) => !attachment.archiveGroup);
  const archiveGroups = new Map<string, MessagePreviewAttachment[]>();
  for (const attachment of attachments) {
    if (!attachment.archiveGroup) continue;
    const group = archiveGroups.get(attachment.archiveGroup) ?? [];
    group.push(attachment);
    archiveGroups.set(attachment.archiveGroup, group);
  }

  function attachmentChip(attachment: MessagePreviewAttachment, index: number) {
    const filename = attachment.filename?.trim() || attachment.label?.trim() || "Unnamed attachment";
    const details = [attachment.detail, attachment.contentType, attachment.sizeBytes ? `${attachment.sizeBytes} bytes` : ""].filter(Boolean).join(" · ");
    return (
      <div className="attachment-file-chip" key={`${filename}:${index}`}>
        <strong>{filename}</strong>
        {details && <span>{details}</span>}
      </div>
    );
  }

  return (
    <div className="template-preview-attachments message-preview-attachments">
      <h3>Attachments</h3>
      {attachments.length === 0 ? (
        <p className="muted small-note">No attachments are effective for this message.</p>
      ) : (
        <div className="message-preview-attachment-layout">
          {direct.length > 0 && <div className="attachment-chip-grid">{direct.map(attachmentChip)}</div>}
          {[...archiveGroups.entries()].map(([groupName, items]) => (
            <section className="attachment-zip-group" key={groupName}>
              <header>
                <strong>{items[0]?.archiveLabel || groupName}</strong>
                <span>{items.length} file{items.length === 1 ? "" : "s"} inside ZIP</span>
              </header>
              <div className="attachment-chip-grid">{items.map(attachmentChip)}</div>
            </section>
          ))}
        </div>
      )}
    </div>
  );
}
