import { useEffect, useMemo, useState } from 'react'
import { save } from '@tauri-apps/plugin-dialog'
import {
  CalendarCheck,
  CalendarClock,
  CalendarPlus,
  CalendarX,
  CheckSquare,
  Download,
  ListPlus,
  Mail,
  Paperclip,
} from 'lucide-react'
import type { AttachmentMeta, InviteInfo, InviteResponse, MessageFull } from '../types'
import { Avatar } from './Avatar'
import { api } from '../lib/api'
import { formatBytes, formatFullDate } from '../lib/format'
import { AttachmentPreviewModal, isPreviewable } from './AttachmentPreviewModal'

function isIcsAttachment(att: AttachmentMeta) {
  return att.mime_type.toLowerCase() === 'text/calendar' || att.filename.toLowerCase().endsWith('.ics')
}

function InviteBanner({
  info,
  onRespond,
}: {
  info: InviteInfo
  onRespond: (response: InviteResponse) => Promise<void>
}) {
  const [responding, setResponding] = useState<InviteResponse | null>(null)
  const [responded, setResponded] = useState<InviteResponse | null>(null)

  async function respond(r: InviteResponse) {
    setResponding(r)
    try {
      await onRespond(r)
      setResponded(r)
    } finally {
      setResponding(null)
    }
  }

  const dateLabel = `${new Date(info.start_ts * 1000).toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: 'short' })}${
    info.all_day ? '' : `, ${new Date(info.start_ts * 1000).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })} – ${new Date(info.end_ts * 1000).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })}`
  }`

  return (
    <div className="border-b border-indigo-100 bg-indigo-50/60 px-7 py-3.5 dark:border-indigo-950 dark:bg-indigo-950/30">
      <p className="text-[12.5px] font-medium text-indigo-800 dark:text-indigo-200">
        Termineinladung: {info.summary}
      </p>
      <p className="text-[11.5px] text-indigo-500 dark:text-indigo-400">
        {dateLabel}
        {info.organizer_email && ` · von ${info.organizer_name || info.organizer_email}`}
      </p>
      {responded ? (
        <p className="mt-2 text-[12px] font-medium text-indigo-700 dark:text-indigo-300">
          {responded === 'accepted' && 'Angenommen — Antwort wurde gesendet.'}
          {responded === 'declined' && 'Abgelehnt — Antwort wurde gesendet.'}
          {responded === 'tentative' && 'Mit Vorbehalt beantwortet — Antwort wurde gesendet.'}
        </p>
      ) : (
        <div className="mt-2 flex gap-2">
          <button
            onClick={() => respond('accepted')}
            disabled={responding !== null}
            className="flex items-center gap-1.5 rounded-full bg-green-600 px-3 py-1.5 text-[12px] font-medium text-white shadow-sm transition hover:bg-green-500 disabled:opacity-60"
          >
            <CalendarCheck size={13} /> {responding === 'accepted' ? 'Sende…' : 'Annehmen'}
          </button>
          <button
            onClick={() => respond('tentative')}
            disabled={responding !== null}
            className="flex items-center gap-1.5 rounded-full bg-amber-500 px-3 py-1.5 text-[12px] font-medium text-white shadow-sm transition hover:bg-amber-400 disabled:opacity-60"
          >
            <CalendarClock size={13} /> {responding === 'tentative' ? 'Sende…' : 'Vorbehalt'}
          </button>
          <button
            onClick={() => respond('declined')}
            disabled={responding !== null}
            className="flex items-center gap-1.5 rounded-full bg-zinc-500 px-3 py-1.5 text-[12px] font-medium text-white shadow-sm transition hover:bg-zinc-400 disabled:opacity-60"
          >
            <CalendarX size={13} /> {responding === 'declined' ? 'Sende…' : 'Ablehnen'}
          </button>
        </div>
      )}
    </div>
  )
}

function downloadAttachment(filename: string, mimeType: string, base64: string) {
  const byteChars = atob(base64)
  const bytes = new Uint8Array(byteChars.length)
  for (let i = 0; i < byteChars.length; i++) bytes[i] = byteChars.charCodeAt(i)
  const blob = new Blob([bytes], { type: mimeType || 'application/octet-stream' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  a.click()
  URL.revokeObjectURL(url)
}

export function ReadingPane({
  message,
  loading,
  selectionCount = 0,
  onImportIcsAttachment,
  onCreateTask,
  onReplyToInvite,
}: {
  message: MessageFull | null
  loading: boolean
  selectionCount?: number
  onImportIcsAttachment?: (base64: string) => Promise<void>
  onCreateTask?: (message: MessageFull) => void
  onReplyToInvite?: (accountId: string, icsBase64: string, response: InviteResponse) => Promise<void>
}) {
  const [importingIcs, setImportingIcs] = useState<number | null>(null)
  const [previewAttachment, setPreviewAttachment] = useState<AttachmentMeta | null>(null)
  const [invite, setInvite] = useState<{ base64: string; info: InviteInfo } | null>(null)

  useEffect(() => {
    setInvite(null)
    if (!message || !onReplyToInvite) return
    const icsAtt = message.attachments.find(isIcsAttachment)
    if (!icsAtt) return
    let cancelled = false
    api
      .previewInvite(icsAtt.content_base64)
      .then((info) => {
        if (!cancelled && info) setInvite({ base64: icsAtt.content_base64, info })
      })
      .catch(() => {})
    return () => {
      cancelled = true
    }
  }, [message, onReplyToInvite])
  const srcDoc = useMemo(() => {
    if (!message) return ''
    if (message.body_html) {
      return `<!doctype html><html><head><meta charset="utf-8"><base target="_blank"><style>
        body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:14px;line-height:1.55;color:#18181b;margin:0;padding:0;word-wrap:break-word;}
        img{max-width:100%;height:auto;}
        a{color:#4f46e5;}
        @media (prefers-color-scheme: dark){ body{color:#e4e4e7;} a{color:#a5b4fc;} }
      </style></head><body>${message.body_html}</body></html>`
    }
    const escaped = (message.body_text || '').replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c]!)
    return `<!doctype html><html><head><meta charset="utf-8"><style>
      body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:14px;line-height:1.55;color:#18181b;margin:0;white-space:pre-wrap;word-wrap:break-word;}
      @media (prefers-color-scheme: dark){ body{color:#e4e4e7;} }
    </style></head><body>${escaped}</body></html>`
  }, [message])

  async function handleExportEml(m: MessageFull) {
    const suggested = `${m.subject.replace(/[\\/:*?"<>|]/g, '_').slice(0, 60) || 'nachricht'}.eml`
    const path = await save({ defaultPath: suggested, filters: [{ name: 'E-Mail', extensions: ['eml'] }] })
    if (!path) return
    await api.exportMessageEml(m.account_id, m.folder, m.uid, path)
  }

  if (loading) {
    return (
      <div className="flex flex-1 items-center justify-center text-sm text-zinc-400">
        Lade Nachricht…
      </div>
    )
  }

  if (selectionCount > 1) {
    return (
      <div className="flex flex-1 flex-col items-center justify-center gap-3">
        <div className="flex h-16 w-16 items-center justify-center rounded-full bg-indigo-50 text-indigo-400 dark:bg-indigo-500/10 dark:text-indigo-300">
          <CheckSquare size={26} strokeWidth={1.4} />
        </div>
        <p className="text-sm text-zinc-400">{selectionCount} Nachrichten ausgewählt</p>
      </div>
    )
  }

  if (!message) {
    return (
      <div className="flex flex-1 flex-col items-center justify-center gap-3">
        <div className="flex h-16 w-16 items-center justify-center rounded-full bg-zinc-100 text-zinc-300 dark:bg-zinc-900 dark:text-zinc-700">
          <Mail size={26} strokeWidth={1.4} />
        </div>
        <p className="text-sm text-zinc-400">Wähle eine Nachricht aus</p>
      </div>
    )
  }

  return (
    <div className="flex min-w-0 flex-1 flex-col">
      <div className="flex items-start justify-between gap-4 border-b border-zinc-200/80 px-7 py-5 dark:border-zinc-800/80">
        <div className="min-w-0">
          <h1 className="truncate text-[18px] font-semibold tracking-tight text-zinc-900 dark:text-zinc-50">
            {message.subject || '(kein Betreff)'}
          </h1>
          <div className="mt-2.5 flex items-center gap-3">
            <Avatar name={message.from_name || message.from_addr} size={38} />
            <div className="min-w-0">
              <p className="truncate text-[13px] font-medium text-zinc-800 dark:text-zinc-200">
                {message.from_name || message.from_addr}
                <span className="ml-1.5 font-normal text-zinc-400">&lt;{message.from_addr}&gt;</span>
              </p>
              <p className="truncate text-[12px] text-zinc-400">
                an {message.to || 'mich'} · {formatFullDate(message.date)}
              </p>
            </div>
          </div>
        </div>
        <div className="flex shrink-0 items-center gap-1.5">
          {onCreateTask && (
            <button
              onClick={() => onCreateTask(message)}
              title="Als Aufgabe markieren"
              className="rounded-full border border-zinc-200 p-1.5 text-zinc-500 shadow-sm transition hover:border-indigo-200 hover:bg-indigo-50 hover:text-indigo-700 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-indigo-800 dark:hover:bg-indigo-500/10"
            >
              <ListPlus size={14} />
            </button>
          )}
          <button
            onClick={() => handleExportEml(message)}
            title="Als .eml exportieren"
            className="rounded-full border border-zinc-200 p-1.5 text-zinc-500 shadow-sm transition hover:border-indigo-200 hover:bg-indigo-50 hover:text-indigo-700 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-indigo-800 dark:hover:bg-indigo-500/10"
          >
            <Download size={14} />
          </button>
        </div>
      </div>

      {invite && onReplyToInvite && (
        <InviteBanner
          info={invite.info}
          onRespond={(response) => onReplyToInvite(message.account_id, invite.base64, response)}
        />
      )}

      {message.attachments.length > 0 && (
        <div className="flex flex-wrap gap-2 border-b border-zinc-200/80 px-7 py-3.5 dark:border-zinc-800/80">
          {message.attachments.map((att, i) => (
            <div key={i} className="flex items-center gap-1">
              <button
                onClick={() =>
                  isPreviewable(att) ? setPreviewAttachment(att) : downloadAttachment(att.filename, att.mime_type, att.content_base64)
                }
                className="flex items-center gap-2 rounded-full border border-zinc-200 bg-zinc-50 px-3 py-1.5 text-[12px] text-zinc-600 shadow-sm transition hover:border-indigo-200 hover:bg-indigo-50 hover:text-indigo-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300"
              >
                <Paperclip size={12} />
                <span className="max-w-40 truncate">{att.filename}</span>
                <span className="text-zinc-400">{formatBytes(att.size)}</span>
                {isPreviewable(att) ? (
                  <span
                    onClick={(e) => {
                      e.stopPropagation()
                      downloadAttachment(att.filename, att.mime_type, att.content_base64)
                    }}
                    title="Herunterladen"
                    className="text-zinc-400 hover:text-indigo-600"
                  >
                    <Download size={11} />
                  </span>
                ) : (
                  <Download size={11} className="text-zinc-400" />
                )}
              </button>
              {isIcsAttachment(att) && onImportIcsAttachment && (
                <button
                  onClick={async () => {
                    setImportingIcs(i)
                    try {
                      await onImportIcsAttachment(att.content_base64)
                    } finally {
                      setImportingIcs(null)
                    }
                  }}
                  disabled={importingIcs === i}
                  title="Zum Kalender hinzufügen"
                  className="flex items-center gap-1.5 rounded-full border border-indigo-200 bg-indigo-50 px-3 py-1.5 text-[12px] font-medium text-indigo-700 shadow-sm transition hover:bg-indigo-100 disabled:opacity-60 dark:border-indigo-800 dark:bg-indigo-500/10 dark:text-indigo-300"
                >
                  <CalendarPlus size={12} />
                  {importingIcs === i ? 'Füge hinzu…' : 'Zum Kalender'}
                </button>
              )}
            </div>
          ))}
        </div>
      )}

      <iframe
        title="message-body"
        srcDoc={srcDoc}
        sandbox=""
        className="w-full flex-1 bg-white dark:bg-zinc-950"
      />

      <AttachmentPreviewModal
        attachment={previewAttachment}
        onClose={() => setPreviewAttachment(null)}
        onDownload={(att) => downloadAttachment(att.filename, att.mime_type, att.content_base64)}
      />
    </div>
  )
}
