import { useEffect, useMemo, useState } from 'react';
import { useInbox } from '../context/InboxContext';
import { useLanguage } from '../context/LanguageContext';
import { useToast } from '../context/ToastContext';

const FILTERS = [
  { key: 'inbox', label: 'Inbox' },
  { key: 'sent', label: 'Sent' },
  { key: 'drafts', label: 'Drafts' },
  { key: 'archive', label: 'Archive' },
  { key: 'trash', label: 'Trash' },
];

const AVATARS = [
  { bg: '#e8f0fe', color: '#1a4fa8' },
  { bg: '#e3f7ef', color: '#1c7a50' },
  { bg: '#fdeaea', color: '#a32828' },
  { bg: '#fef3db', color: '#93590a' },
  { bg: '#f0eeff', color: '#4a35b0' },
];

const STYLES = `
.messages-react-page,
.messages-react-page *,
.messages-react-page *::before,
.messages-react-page *::after {
  box-sizing: border-box;
}

.messages-react-page {
  --bg: #f6f5f1;
  --surface: #ffffff;
  --surface2: #f8f7f4;
  --border: rgba(0, 0, 0, 0.08);
  --border-md: rgba(0, 0, 0, 0.14);
  --text-1: #111110;
  --text-2: #5a5955;
  --text-3: #999894;
  --accent: #1a6ef5;
  --accent-bg: #e8f0fe;
  --accent-text: #1a4fa8;
  --amber: #c47d0e;
  --amber-bg: #fef3db;
  --amber-text: #93590a;
  --red: #d63b3b;
  --red-bg: #fdeaea;
  --red-text: #a32828;
  --green: #2d9e6b;
  --green-bg: #e3f7ef;
  --green-text: #1c7a50;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --font: 'DM Sans', system-ui, sans-serif;
  --mono: 'DM Mono', monospace;
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.07), 0 1px 4px rgba(0,0,0,0.04);
  width: 100vw;
  height: calc(100vh - 72px);
  min-height: calc(100vh - 72px);
  margin: -24px calc(50% - 50vw) 0;
  background: var(--bg);
  font-family: var(--font);
  color: var(--text-1);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

.messages-react-page .shell {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  padding: 20px 24px 16px;
}

.messages-react-page .messages-loading-shell {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font-size: 14px;
  color: var(--text-2);
}

.messages-react-page .subheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0 14px;
  flex-shrink: 0;
  gap: 12px;
  flex-wrap: wrap;
}

.messages-react-page .subheader-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.messages-react-page .email-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 6px 6px 6px 16px;
  box-shadow: var(--shadow-sm);
}

.messages-react-page .email-addr {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-2);
  letter-spacing: -0.2px;
}

.messages-react-page .copy-btn {
  height: 28px;
  padding: 0 12px;
  background: var(--accent-bg);
  color: var(--accent-text);
  border: none;
  border-radius: 100px;
  font-size: 12px;
  font-weight: 500;
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.15s;
  display: flex;
  align-items: center;
  gap: 5px;
}

.messages-react-page .copy-btn:hover { background: #d4e4fd; }
.messages-react-page .copy-btn svg { width: 12px; height: 12px; }

.messages-react-page .timer-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 12px;
  background: var(--amber-bg);
  border-radius: 100px;
}

.messages-react-page .timer-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--amber);
  animation: messagesBlink 1.4s infinite;
}

@keyframes messagesBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.2; }
}

.messages-react-page .timer-val {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--amber-text);
}

.messages-react-page .filters {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}

.messages-react-page .filter-btn {
  height: 32px;
  padding: 0 14px;
  border-radius: 100px;
  font-size: 13px;
  font-weight: 500;
  font-family: var(--font);
  border: 1px solid transparent;
  background: none;
  color: var(--text-2);
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  align-items: center;
  gap: 6px;
}

.messages-react-page .filter-btn:hover {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text-1);
}

.messages-react-page .filter-btn.active {
  background: var(--text-1);
  color: #fff;
  border-color: var(--text-1);
}

.messages-react-page .filter-count {
  font-size: 11px;
  font-weight: 500;
  padding: 1px 6px;
  border-radius: 100px;
}

.messages-react-page .filter-btn.active .filter-count {
  background: rgba(255,255,255,0.2);
  color: rgba(255,255,255,0.85);
}

.messages-react-page .filter-btn:not(.active) .filter-count {
  background: var(--surface2);
  color: var(--text-3);
}

.messages-react-page .split {
  display: flex;
  flex: 1;
  min-height: 0;
  gap: 12px;
  overflow: hidden;
  padding-bottom: 0;
}

.messages-react-page .msg-list-panel {
  width: 300px;
  min-width: 300px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.messages-react-page .msg-list-inner {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 8px;
}

.messages-react-page .msg-list-inner::-webkit-scrollbar,
.messages-react-page .preview-body-wrap::-webkit-scrollbar {
  width: 4px;
}

.messages-react-page .msg-list-inner::-webkit-scrollbar-thumb,
.messages-react-page .preview-body-wrap::-webkit-scrollbar-thumb {
  background: var(--border-md);
  border-radius: 2px;
}

.messages-react-page .msg-item {
  display: flex;
  gap: 10px;
  padding: 10px 10px 10px 12px;
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: background 0.12s;
  position: relative;
  border: none;
  border-left: 3px solid transparent;
  animation: messagesItemIn 0.2s ease both;
  width: 100%;
  text-align: initial;
  background: transparent;
}

@keyframes messagesItemIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

.messages-react-page .msg-item:hover { background: var(--surface2); }

.messages-react-page .msg-item.active {
  background: var(--accent-bg);
  border-left-color: var(--accent);
}

.messages-react-page .msg-item.unread .msg-sender { font-weight: 600; }

.messages-react-page .msg-item.unread::after {
  content: '';
  position: absolute;
  top: 14px;
  right: 12px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

.messages-react-page .msg-item.active::after { display: none; }

.messages-react-page .msg-avatar,
.messages-react-page .preview-avatar,
.messages-react-page .attach-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.messages-react-page .msg-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

.messages-react-page .msg-content {
  flex: 1;
  min-width: 0;
}

.messages-react-page .msg-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 2px;
}

.messages-react-page .msg-sender {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.messages-react-page .msg-time {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--text-3);
  white-space: nowrap;
  flex-shrink: 0;
}

.messages-react-page .msg-subject {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 2px;
}

.messages-react-page .msg-preview {
  font-size: 12px;
  color: var(--text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.messages-react-page .msg-item.active .msg-sender,
.messages-react-page .msg-item.active .msg-subject { color: var(--accent-text); }
.messages-react-page .msg-item.active .msg-preview { color: #5b82c9; }
.messages-react-page .msg-item.active .msg-time { color: #7aa3e0; }

.messages-react-page .preview-panel {
  flex: 1;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.messages-react-page .preview-empty-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--text-3);
  text-align: center;
  padding: 48px;
}

.messages-react-page .preview-empty-icon {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1.5px dashed var(--border-md);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 6px;
}

.messages-react-page .preview-empty-icon svg {
  color: var(--text-3);
  width: 22px;
  height: 22px;
}

.messages-react-page .preview-empty-title {
  font-size: 15px;
  font-weight: 500;
  color: var(--text-2);
}

.messages-react-page .preview-empty-sub {
  font-size: 13px;
  color: var(--text-3);
}

.messages-react-page .preview-header {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.messages-react-page .preview-top-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.messages-react-page .preview-avatar {
  width: 42px;
  height: 42px;
  border-radius: var(--radius-lg);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

.messages-react-page .preview-sender-block {
  flex: 1;
  min-width: 0;
}

.messages-react-page .preview-sender-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-1);
}

.messages-react-page .preview-sender-email {
  font-size: 12px;
  font-family: var(--mono);
  color: var(--text-3);
}

.messages-react-page .preview-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.messages-react-page .action-btn {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-2);
  transition: all 0.15s;
  position: relative;
}

.messages-react-page .action-btn svg { width: 15px; height: 15px; }

.messages-react-page .action-btn:hover {
  background: var(--surface2);
  border-color: var(--border-md);
  color: var(--text-1);
}

.messages-react-page .action-btn.star-active {
  color: var(--amber);
  background: var(--amber-bg);
  border-color: transparent;
}

.messages-react-page .action-btn.danger:hover {
  color: var(--red);
  background: var(--red-bg);
  border-color: transparent;
}

.messages-react-page .preview-time {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--text-3);
  margin-left: 8px;
}

.messages-react-page .preview-subject-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.messages-react-page .preview-subject {
  font-size: 18px;
  font-weight: 600;
  color: var(--text-1);
  letter-spacing: -0.3px;
  line-height: 1.3;
}

.messages-react-page .tag {
  font-size: 11px;
  font-weight: 500;
  padding: 3px 9px;
  border-radius: 100px;
}

.messages-react-page .preview-body-wrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 24px;
}

.messages-react-page .preview-body {
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--text-2);
}

.messages-react-page .preview-body p { margin-bottom: 14px; }
.messages-react-page .preview-body p:last-child { margin-bottom: 0; }

.messages-react-page .preview-loading {
  color: var(--text-3);
}

.messages-react-page .attachments {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.messages-react-page .attach-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 10px;
}

.messages-react-page .attach-list {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.messages-react-page .attach-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-size: 13px;
  cursor: default;
  transition: border-color 0.15s;
}

.messages-react-page .attach-item:hover { border-color: var(--border-md); }

.messages-react-page .attach-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
}

.messages-react-page .attach-icon svg { width: 16px; height: 16px; }

.messages-react-page .attach-name {
  font-weight: 500;
  color: var(--text-1);
}

.messages-react-page .attach-meta {
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 1px;
}

.messages-react-page .reply-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

.messages-react-page .reply-input {
  flex: 1;
  height: 36px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0 16px;
  font-size: 13.5px;
  font-family: var(--font);
  color: var(--text-1);
  outline: none;
  transition: border-color 0.15s, background 0.15s;
}

.messages-react-page .reply-input::placeholder { color: var(--text-3); }

.messages-react-page .reply-input:focus {
  background: var(--surface);
  border-color: var(--border-md);
}

.messages-react-page .reply-send {
  width: 36px;
  height: 36px;
  background: var(--text-1);
  border: none;
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: opacity 0.15s, transform 0.15s;
}

.messages-react-page .reply-send:hover {
  opacity: 0.85;
  transform: scale(1.05);
}

.messages-react-page .reply-send svg { width: 15px; height: 15px; }

.messages-react-page .list-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 48px 20px;
  text-align: center;
  color: var(--text-3);
  font-size: 13px;
}

.messages-react-page .list-empty-icon {
  font-size: 28px;
  margin-bottom: 6px;
  opacity: 0.4;
}

@media (max-width: 980px) {
  .messages-react-page {
    width: 100%;
    height: auto;
    min-height: calc(100vh - 72px);
    margin: 0;
  }

  .messages-react-page .shell {
    padding: 16px;
  }

  .messages-react-page .split {
    flex-direction: column;
    overflow: visible;
  }

  .messages-react-page .msg-list-panel {
    width: 100%;
    min-width: 0;
    max-height: 42vh;
  }

  .messages-react-page .preview-panel {
    min-height: 52vh;
  }
}

@media (max-width: 720px) {
  .messages-react-page .subheader,
  .messages-react-page .preview-top-row {
    align-items: stretch;
    flex-direction: column;
  }

  .messages-react-page .filters,
  .messages-react-page .preview-actions {
    width: 100%;
    justify-content: flex-start;
  }

  .messages-react-page .email-strip {
    width: 100%;
    flex-wrap: wrap;
  }

  .messages-react-page .preview-time {
    margin-left: 0;
  }
}
`;

function MailIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <rect x="2" y="4" width="20" height="16" rx="3" />
      <path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
    </svg>
  );
}

function CopyIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <rect x="9" y="9" width="13" height="13" rx="2" />
      <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
    </svg>
  );
}

function StarIcon({ filled = false }) {
  if (filled) {
    return (
      <svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
      </svg>
    );
  }

  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
    </svg>
  );
}

function ArchiveIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <polyline points="21 8 21 21 3 21 3 8" />
      <rect x="1" y="3" width="22" height="5" />
      <line x1="10" y1="12" x2="14" y2="12" />
    </svg>
  );
}

function TrashIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <polyline points="3 6 5 6 21 6" />
      <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
      <path d="M10 11v6" />
      <path d="M14 11v6" />
      <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
    </svg>
  );
}

function SendIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <line x1="22" y1="2" x2="11" y2="13" />
      <polygon points="22 2 15 22 11 13 2 9 22 2" />
    </svg>
  );
}

function FileIcon() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
      <polyline points="14 2 14 8 20 8" />
    </svg>
  );
}

function formatListDate(value) {
  if (!value) return '';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '';
  const now = new Date();
  const sameDay = date.toDateString() === now.toDateString();
  if (sameDay) {
    return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date);
  }
  return new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' }).format(date);
}

function formatCountdown(totalSeconds) {
  const seconds = Math.max(0, Number(totalSeconds || 0));
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = seconds % 60;
  return [hours, minutes, secs].map((value) => String(value).padStart(2, '0')).join(':');
}

function escapeHtml(value) {
  return String(value || '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function makeHtmlBody(message) {
  if (message?.htmlBody) return message.htmlBody;
  const text = String(message?.bodyText || message?.snippet || '').trim();
  return `<p>${escapeHtml(text).replace(/\n/g, '<br />')}</p>`;
}

function getInitials(name) {
  return String(name || '')
    .split(/\s+/)
    .filter(Boolean)
    .map((part) => part[0])
    .join('')
    .slice(0, 2)
    .toUpperCase();
}

function getAvatarColors(seed) {
  const text = String(seed || '0');
  const total = Array.from(text).reduce((sum, char) => sum + char.charCodeAt(0), 0);
  return AVATARS[total % AVATARS.length];
}

function getFolderKey(message) {
  if (message?.draft || message?.isDraft || message?.folder === 'drafts') return 'drafts';
  if (message?.deleted || message?.isDeleted || message?.trashed || message?.folder === 'trash') return 'trash';
  if (message?.archived || message?.isArchived || message?.folder === 'archive') return 'archive';
  if (message?.sent || message?.isSent || message?.folder === 'sent' || message?.direction === 'outgoing') return 'sent';
  return 'inbox';
}

function getMessageSender(message) {
  return message?.from || message?.fromName || message?.fromEmail || 'Unknown sender';
}

function getMessagePreview(message) {
  return String(message?.snippet || message?.bodyText || message?.plainText || '').trim();
}

function getAttachmentItems(message) {
  if (Array.isArray(message?.attachments) && message.attachments.length) {
    return message.attachments;
  }
  if (message?.hasAttachments) {
    return [{ id: 'pending', filename: 'Attachments loading...', size: '', type: '' }];
  }
  return [];
}

export default function InboxPage() {
  const {
    session,
    sessionLoading,
    messages,
    messagesLoading,
    remainingSeconds,
    isGuestInbox,
    inboxAddress,
    fetchMessage,
    markUnread,
    toggleStar,
  } = useInbox();
  const { isRtl } = useLanguage();
  const toast = useToast();

  const [currentFilter, setCurrentFilter] = useState('inbox');
  const [selectedEmailId, setSelectedEmailId] = useState(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [replyText, setReplyText] = useState('');
  const [copyLabel, setCopyLabel] = useState('Copy');

  useEffect(() => {
    const fontLinkId = 'messages-redesign-fonts';
    if (!document.getElementById(fontLinkId)) {
      const link = document.createElement('link');
      link.id = fontLinkId;
      link.rel = 'stylesheet';
      link.href = 'https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=DM+Mono:wght@400;500&display=swap';
      document.head.appendChild(link);
    }
  }, []);

  const decoratedMessages = useMemo(
    () => (Array.isArray(messages) ? messages : []).map((item) => ({
      ...item,
      folderKey: getFolderKey(item),
      senderName: getMessageSender(item),
      previewText: getMessagePreview(item),
      timeLabel: formatListDate(item?.receivedAt),
      attachmentItems: getAttachmentItems(item),
    })),
    [messages],
  );

  const folderCounts = useMemo(
    () => FILTERS.reduce((acc, filter) => {
      acc[filter.key] = decoratedMessages.filter((message) => message.folderKey === filter.key).length;
      return acc;
    }, {}),
    [decoratedMessages],
  );

  const filteredMessages = useMemo(
    () => decoratedMessages.filter((message) => message.folderKey === currentFilter),
    [currentFilter, decoratedMessages],
  );

  const selectedEmail = useMemo(
    () => decoratedMessages.find((message) => message.id === selectedEmailId) || null,
    [decoratedMessages, selectedEmailId],
  );

  useEffect(() => {
    if (selectedEmailId && !decoratedMessages.some((message) => message.id === selectedEmailId)) {
      setSelectedEmailId(null);
      setReplyText('');
    }
  }, [decoratedMessages, selectedEmailId]);

  async function handleCopyInboxEmail() {
    try {
      await navigator.clipboard.writeText(inboxAddress || '');
      setCopyLabel('Copied!');
      toast.success('Email copied');
      window.setTimeout(() => setCopyLabel('Copy'), 1800);
    } catch {
      toast.error('Copy failed');
    }
  }

  async function handleSelectEmail(id) {
    setSelectedEmailId(id);
    setReplyText('');
    setDetailLoading(true);
    try {
      await fetchMessage(id);
    } catch {
      toast.error('Failed to load email');
    } finally {
      setDetailLoading(false);
    }
  }

  async function handleToggleStar(email, event) {
    if (event) event.stopPropagation();
    try {
      await toggleStar(email.id, !email.starred);
    } catch {
      toast.error('Failed to update star');
    }
  }

  async function handleMarkUnread(messageId, event) {
    if (event) event.stopPropagation();
    try {
      await markUnread(messageId);
      toast.success('Marked as unread');
    } catch {
      toast.error('Failed to mark unread');
    }
  }

  function handleArchiveSelected() {
    toast.info('Archive action is not connected yet');
  }

  function handleDeleteSelected() {
    toast.info('Delete action is not connected yet');
  }

  function handleReplySend() {
    if (!selectedEmail?.fromEmail || !replyText.trim()) return;

    const subject = encodeURIComponent(`Re: ${selectedEmail.subject || ''}`);
    const body = encodeURIComponent(replyText.trim());
    window.location.href = `mailto:${selectedEmail.fromEmail}?subject=${subject}&body=${body}`;
    setReplyText('');
  }

  function handleReplyKeyDown(event) {
    if (event.key === 'Enter') {
      event.preventDefault();
      handleReplySend();
    }
  }

  if (sessionLoading && !session) {
    return (
      <div className="messages-react-page" dir={isRtl ? 'rtl' : 'ltr'}>
        <style>{STYLES}</style>
        <div className="messages-loading-shell">Loading inbox...</div>
      </div>
    );
  }

  return (
    <div className="messages-react-page" dir={isRtl ? 'rtl' : 'ltr'}>
      <style>{STYLES}</style>

      <div className="shell">
        <div className="subheader">
          <div className="subheader-left">
            <div className="email-strip">
              <span className="email-addr">{inboxAddress || 'No inbox address'}</span>

              <button type="button" className="copy-btn" onClick={handleCopyInboxEmail}>
                <CopyIcon />
                <span>{copyLabel}</span>
              </button>

              <div className="timer-chip">
                <div className="timer-dot" />
                <span className="timer-val">{isGuestInbox ? formatCountdown(remainingSeconds) : 'Permanent'}</span>
              </div>
            </div>
          </div>

          <div className="filters">
            {FILTERS.map((filter) => {
              const count = folderCounts[filter.key] || 0;
              const isActive = currentFilter === filter.key;

              return (
                <button
                  key={filter.key}
                  type="button"
                  className={`filter-btn ${isActive ? 'active' : ''}`}
                  onClick={() => {
                    setCurrentFilter(filter.key);
                    setSelectedEmailId(null);
                    setReplyText('');
                  }}
                >
                  <span>{filter.label}</span>
                  {count > 0 ? <span className="filter-count">{count}</span> : null}
                </button>
              );
            })}
          </div>
        </div>

        <div className="split">
          <div className="msg-list-panel">
            <div className="msg-list-inner">
              {messagesLoading && !filteredMessages.length ? (
                <div className="list-empty">
                  <div style={{ fontWeight: 500, color: 'var(--text-2)' }}>Loading messages</div>
                </div>
              ) : filteredMessages.length === 0 ? (
                <div className="list-empty">
                  <div className="list-empty-icon">◻</div>
                  <div style={{ fontWeight: 500, color: 'var(--text-2)' }}>No messages</div>
                  <div>This folder is empty</div>
                </div>
              ) : (
                filteredMessages.map((message, index) => {
                  const avatar = getAvatarColors(message.id || message.fromEmail || message.senderName);
                  const isSelected = selectedEmailId === message.id;
                  const isUnread = !message.read;

                  return (
                    <button
                      key={message.id}
                      type="button"
                      className={`msg-item ${isSelected ? 'active' : ''} ${isUnread && !isSelected ? 'unread' : ''}`}
                      onClick={() => handleSelectEmail(message.id)}
                      style={{ animationDelay: `${index * 40}ms` }}
                    >
                      <div className="msg-avatar" style={{ background: avatar.bg, color: avatar.color }}>
                        {getInitials(message.senderName)}
                      </div>

                      <div className="msg-content">
                        <div className="msg-top">
                          <span className="msg-sender">{message.senderName}</span>
                          <span className="msg-time">{message.timeLabel}</span>
                        </div>
                        <div className="msg-subject">{message.subject || '(No subject)'}</div>
                        <div className="msg-preview">{message.previewText || 'No preview available'}</div>
                      </div>
                    </button>
                  );
                })
              )}
            </div>
          </div>

          <div className="preview-panel">
            {!selectedEmail ? (
              <div className="preview-empty-wrap">
                <div className="preview-empty-icon">
                  <MailIcon />
                </div>
                <div className="preview-empty-title">No message selected</div>
                <div className="preview-empty-sub">Pick a message from the list to read it</div>
              </div>
            ) : (
              (() => {
                const avatar = getAvatarColors(selectedEmail.id || selectedEmail.fromEmail || selectedEmail.senderName);
                const hasAttachments = selectedEmail.attachmentItems.length > 0;

                return (
                  <>
                    <div className="preview-header">
                      <div className="preview-top-row">
                        <div className="preview-avatar" style={{ background: avatar.bg, color: avatar.color }}>
                          {getInitials(selectedEmail.senderName)}
                        </div>

                        <div className="preview-sender-block">
                          <div className="preview-sender-name">{selectedEmail.senderName}</div>
                          <div className="preview-sender-email">{selectedEmail.fromEmail || 'Unknown email'}</div>
                        </div>

                        <div className="preview-actions">
                          <button
                            type="button"
                            className={`action-btn ${selectedEmail.starred ? 'star-active' : ''}`}
                            onClick={() => handleToggleStar(selectedEmail)}
                            aria-label="Toggle star"
                            title="Star"
                          >
                            <StarIcon filled={selectedEmail.starred} />
                          </button>

                          <button type="button" className="action-btn" onClick={handleArchiveSelected} aria-label="Archive" title="Archive">
                            <ArchiveIcon />
                          </button>

                          <button type="button" className="action-btn danger" onClick={handleDeleteSelected} aria-label="Delete" title="Delete">
                            <TrashIcon />
                          </button>
                        </div>

                        <span className="preview-time">{selectedEmail.timeLabel}</span>
                      </div>

                      <div className="preview-subject-row">
                        <div className="preview-subject">{selectedEmail.subject || '(No subject)'}</div>
                        {hasAttachments ? <span className="tag" style={{ background: 'var(--amber-bg)', color: 'var(--amber-text)' }}>attachment</span> : null}
                        {!selectedEmail.read ? <span className="tag" style={{ background: 'var(--accent-bg)', color: 'var(--accent-text)' }}>unread</span> : null}
                      </div>
                    </div>

                    <div className="preview-body-wrap">
                      <div className="preview-body">
                        {detailLoading ? (
                          <div className="preview-loading">Loading email...</div>
                        ) : (
                          <>
                            <div dangerouslySetInnerHTML={{ __html: makeHtmlBody(selectedEmail) }} />

                            {hasAttachments ? (
                              <div className="attachments">
                                <div className="attach-label">Attachments ({selectedEmail.attachmentItems.length})</div>
                                <div className="attach-list">
                                  {selectedEmail.attachmentItems.map((attachment, index) => (
                                    <div key={attachment.id || attachment.filename || attachment.original_name || index} className="attach-item">
                                      <div className="attach-icon" style={{ background: avatar.bg, color: avatar.color }}>
                                        <FileIcon />
                                      </div>
                                      <div>
                                        <div className="attach-name">{attachment.original_name || attachment.filename || attachment.name || 'Attachment'}</div>
                                        <div className="attach-meta">
                                          {[attachment.size, attachment.type || attachment.mime_type].filter(Boolean).join(' · ')}
                                        </div>
                                      </div>
                                    </div>
                                  ))}
                                </div>
                              </div>
                            ) : null}
                          </>
                        )}
                      </div>
                    </div>

                    <div className="reply-bar">
                      <input
                        className="reply-input"
                        type="text"
                        value={replyText}
                        onChange={(event) => setReplyText(event.target.value)}
                        onKeyDown={handleReplyKeyDown}
                        placeholder={`Reply to ${selectedEmail.senderName}…`}
                      />

                      <button type="button" className="reply-send" onClick={handleReplySend} aria-label="Send reply">
                        <SendIcon />
                      </button>
                    </div>
                  </>
                );
              })()
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
