'use client';

import { useEffect, useState, useCallback } from 'react';
import toast from 'react-hot-toast';
import { getApiErrorMessage } from '@/lib/utils/apiError';

type MessageStatus = 'new' | 'read' | 'replied';

interface ContactMessage {
  id: string;
  name: string;
  email: string;
  subject: string;
  message: string;
  status: MessageStatus;
  ip_address: string | null;
  created_at: string;
}

interface Counts {
  all: number;
  new: number;
  read: number;
  replied: number;
}

interface ContactMessagesTableProps {
  canUpdate: boolean;
  canDelete: boolean;
}

const STATUS_STYLE: Record<MessageStatus, { bg: string; color: string }> = {
  new: { bg: 'var(--color-warning-light)', color: 'var(--color-warning)' },
  read: { bg: 'var(--color-info-light)', color: 'var(--color-info)' },
  replied: { bg: 'var(--color-success-light)', color: 'var(--color-success)' },
};

const SUBJECT_LABEL: Record<string, string> = {
  order: 'Order related',
  delivery: 'Delivery issue',
  product: 'Product quality',
  feedback: 'Feedback',
  other: 'Other',
};

const TABS: Array<MessageStatus | 'all'> = ['new', 'read', 'replied', 'all'];
const PAGE_SIZE = 20;

export default function ContactMessagesTable({ canUpdate, canDelete }: ContactMessagesTableProps) {
  const [tab, setTab] = useState<(typeof TABS)[number]>('new');
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [page, setPage] = useState(1);
  const [messages, setMessages] = useState<ContactMessage[]>([]);
  const [counts, setCounts] = useState<Counts>({ all: 0, new: 0, read: 0, replied: 0 });
  const [totalPages, setTotalPages] = useState(1);
  const [loading, setLoading] = useState(true);
  const [openId, setOpenId] = useState<string | null>(null);
  const [busyId, setBusyId] = useState<string | null>(null);

  useEffect(() => {
    const t = setTimeout(() => {
      setDebouncedSearch(search.trim());
      setPage(1);
    }, 300);
    return () => clearTimeout(t);
  }, [search]);

  const load = useCallback(() => {
    const params = new URLSearchParams({ limit: String(PAGE_SIZE), page: String(page) });
    if (tab !== 'all') params.set('status', tab);
    if (debouncedSearch) params.set('search', debouncedSearch);
    fetch(`/api/contact-messages?${params}`, { credentials: 'include' })
      .then((res) => res.json())
      .then((data) => {
        if (data.success) {
          setMessages(data.data.messages);
          setCounts(data.data.counts);
          setTotalPages(Math.max(1, data.data.pagination.totalPages));
        } else {
          toast.error(getApiErrorMessage(data, 'Failed to load messages'));
        }
      })
      .catch(() => toast.error('Network error'))
      .finally(() => setLoading(false));
  }, [tab, debouncedSearch, page]);

  useEffect(() => {
    load();
  }, [load]);

  const setStatus = async (id: string, status: MessageStatus) => {
    setBusyId(id);
    try {
      const res = await fetch(`/api/contact-messages/${id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ status }),
      });
      const data = await res.json();
      if (!res.ok || !data.success) {
        toast.error(getApiErrorMessage(data, 'Failed to update message'));
        return;
      }
      load();
    } catch {
      toast.error('Network error');
    } finally {
      setBusyId(null);
    }
  };

  // Opening a "new" message counts as reading it.
  const toggleOpen = (m: ContactMessage) => {
    const opening = openId !== m.id;
    setOpenId(opening ? m.id : null);
    if (opening && m.status === 'new' && canUpdate) void setStatus(m.id, 'read');
  };

  const remove = async (m: ContactMessage) => {
    if (!window.confirm(`Delete the message from ${m.name}? This cannot be undone.`)) return;
    setBusyId(m.id);
    try {
      const res = await fetch(`/api/contact-messages/${m.id}`, { method: 'DELETE', credentials: 'include' });
      const data = await res.json();
      if (!res.ok || !data.success) {
        toast.error(getApiErrorMessage(data, 'Failed to delete message'));
        return;
      }
      toast.success(data.message);
      setOpenId(null);
      load();
    } catch {
      toast.error('Network error');
    } finally {
      setBusyId(null);
    }
  };

  return (
    <div>
      <div className="flex flex-wrap items-center justify-between gap-3 mb-4">
        <div className="flex flex-wrap gap-2">
          {TABS.map((t) => (
            <button
              key={t}
              onClick={() => {
                setTab(t);
                setPage(1);
                setLoading(true);
              }}
              className="px-3 py-1.5 rounded-full text-sm font-medium transition-all capitalize"
              style={{
                background: tab === t ? 'var(--color-cta)' : 'var(--color-surface-alt)',
                color: tab === t ? 'white' : 'var(--color-text)',
                border: '1px solid var(--color-border)',
              }}
            >
              {t} ({counts[t]})
            </button>
          ))}
        </div>
        <input
          type="search"
          placeholder="Search name, email or message…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="px-3 py-1.5 rounded-lg text-sm outline-none w-full sm:w-72"
          style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)', color: 'var(--color-text)' }}
        />
      </div>

      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 4 }).map((_, i) => (
            <div key={i} className="skeleton h-16 w-full rounded-lg" />
          ))}
        </div>
      ) : messages.length === 0 ? (
        <p className="text-sm text-center py-12" style={{ color: 'var(--color-text-tertiary)' }}>
          {debouncedSearch ? 'No messages match your search.' : `No ${tab === 'all' ? '' : `${tab} `}messages.`}
        </p>
      ) : (
        <div className="space-y-3">
          {messages.map((m) => {
            const isOpen = openId === m.id;
            return (
              <div
                key={m.id}
                className="rounded-lg"
                style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}
              >
                <button
                  type="button"
                  onClick={() => toggleOpen(m)}
                  className="w-full text-left p-4 flex flex-wrap justify-between items-start gap-3"
                  aria-expanded={isOpen}
                >
                  <div className="min-w-0 flex-1">
                    <p className="font-medium" style={{ color: 'var(--color-text)', fontWeight: m.status === 'new' ? 700 : 500 }}>
                      {m.name}{' '}
                      <span className="text-xs font-normal" style={{ color: 'var(--color-text-tertiary)' }}>
                        · {m.email}
                      </span>
                    </p>
                    <p className="text-sm mt-0.5 truncate" style={{ color: 'var(--color-text-secondary)' }}>
                      <span className="font-medium">{SUBJECT_LABEL[m.subject] ?? m.subject}</span> — {m.message}
                    </p>
                  </div>
                  <div className="text-right shrink-0">
                    <span
                      className="inline-block text-xs px-2 py-0.5 rounded-full font-medium capitalize"
                      style={{ background: STATUS_STYLE[m.status].bg, color: STATUS_STYLE[m.status].color }}
                    >
                      {m.status}
                    </span>
                    <p className="text-xs mt-1" style={{ color: 'var(--color-text-tertiary)' }}>
                      {new Date(m.created_at).toLocaleString()}
                    </p>
                  </div>
                </button>

                {isOpen && (
                  <div className="px-4 pb-4 pt-3" style={{ borderTop: '1px solid var(--color-border)' }}>
                    <p className="text-sm whitespace-pre-wrap break-words" style={{ color: 'var(--color-text)' }}>
                      {m.message}
                    </p>
                    {m.ip_address && (
                      <p className="text-xs mt-3" style={{ color: 'var(--color-text-tertiary)' }}>
                        Sent from {m.ip_address}
                      </p>
                    )}
                    <div className="flex flex-wrap items-center gap-2 mt-4">
                      <a
                        href={`mailto:${m.email}?subject=${encodeURIComponent(`Re: ${SUBJECT_LABEL[m.subject] ?? m.subject}`)}`}
                        onClick={() => canUpdate && m.status !== 'replied' && void setStatus(m.id, 'replied')}
                        className="px-3 py-1.5 rounded-lg text-sm font-medium text-white"
                        style={{ background: 'var(--color-cta)' }}
                      >
                        Reply by email
                      </a>
                      {canUpdate && m.status !== 'replied' && (
                        <button
                          disabled={busyId === m.id}
                          onClick={() => setStatus(m.id, 'replied')}
                          className="px-3 py-1.5 rounded-lg text-sm font-medium disabled:opacity-50"
                          style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)', color: 'var(--color-text)' }}
                        >
                          Mark as replied
                        </button>
                      )}
                      {canUpdate && m.status !== 'new' && (
                        <button
                          disabled={busyId === m.id}
                          onClick={() => setStatus(m.id, 'new')}
                          className="px-3 py-1.5 rounded-lg text-sm font-medium disabled:opacity-50"
                          style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)', color: 'var(--color-text)' }}
                        >
                          Mark as new
                        </button>
                      )}
                      {canDelete && (
                        <button
                          disabled={busyId === m.id}
                          onClick={() => remove(m)}
                          className="ml-auto px-3 py-1.5 rounded-lg text-sm font-medium text-white disabled:opacity-50"
                          style={{ background: 'var(--color-danger)' }}
                        >
                          Delete
                        </button>
                      )}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {totalPages > 1 && (
        <div className="flex items-center justify-center gap-3 mt-6 text-sm" style={{ color: 'var(--color-text-secondary)' }}>
          <button
            disabled={page <= 1}
            onClick={() => setPage((p) => p - 1)}
            className="px-3 py-1.5 rounded-lg disabled:opacity-40"
            style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)' }}
          >
            Previous
          </button>
          <span>
            Page {page} of {totalPages}
          </span>
          <button
            disabled={page >= totalPages}
            onClick={() => setPage((p) => p + 1)}
            className="px-3 py-1.5 rounded-lg disabled:opacity-40"
            style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)' }}
          >
            Next
          </button>
        </div>
      )}
    </div>
  );
}
