"use client";

import { useReducer, useCallback } from "react";
import type { Contact, ContactSource } from "@/actions/communications/contacts";
import { getContacts, deleteContact, exportContacts } from "@/actions/communications/contacts";
import { formatDate } from "@/lib/format-date";
import AdminButton from "./design-system/AdminButton";

const SOURCE_COLORS: Record<ContactSource, string> = {
  order: "bg-blue-100 text-blue-700",
  import: "bg-purple-100 text-purple-700",
  manual: "bg-emerald-100 text-emerald-700",
  admin: "bg-stone-100 text-stone-600",
};

// Icon components
const Icons = {
  users: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
      <circle cx="9" cy="7" r="4"/>
      <path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
      <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
    </svg>
  ),
  download: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
      <polyline points="7 10 12 15 17 10"/>
      <line x1="12" y1="15" x2="12" y2="3"/>
    </svg>
  ),
  search: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="11" cy="11" r="8"/>
      <path d="m21 21-4.3-4.3"/>
    </svg>
  ),
  trash: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="3 6 5 6 21 6"/>
      <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
      <line x1="10" y1="11" x2="10" y2="17"/>
      <line x1="14" y1="11" x2="14" y2="17"/>
    </svg>
  ),
  chevronLeft: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="m15 18-6-6 6-6"/>
    </svg>
  ),
  chevronRight: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="m9 18 6-6-6-6"/>
    </svg>
  ),
  plus: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <line x1="12" y1="5" x2="12" y2="19"/>
      <line x1="5" y1="12" x2="19" y2="12"/>
    </svg>
  ),
  upload: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
      <polyline points="17 8 12 3 7 8"/>
      <line x1="12" y1="3" x2="12" y2="15"/>
    </svg>
  ),
  mail: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
      <polyline points="22,6 12,13 2,6"/>
    </svg>
  ),
};

// Empty state component
function EmptyState({ hasFilters }: { hasFilters: boolean }) {
  return (
    <div className="text-center py-12 px-4">
      <div className="w-20 h-20 mx-auto mb-4 rounded-2xl bg-gradient-to-br from-emerald-100 to-emerald-50 flex items-center justify-center">
        {Icons.users("w-10 h-10 text-emerald-600")}
      </div>
      <h3 className="text-lg font-semibold text-stone-800">
        {hasFilters ? "No contacts match your filters" : "No contacts yet"}
      </h3>
      <p className="text-sm text-stone-500 mt-1 max-w-sm mx-auto">
        {hasFilters 
          ? "Try adjusting your search or filter criteria to find contacts."
          : "Contacts are added when customers place orders or are imported from other sources."}
      </p>
    </div>
  );
}

// Loading skeleton (rendered as a div so it doesn't get parsed as table rows)
function ContactSkeleton() {
  return (
    <div aria-live="polite" aria-busy="true" aria-label="Loading contacts" className="overflow-hidden rounded-xl border border-[var(--admin-border)] bg-white">
      {[1, 2, 3, 4, 5].map((i) => (
        <div key={i} className="flex items-center gap-4 border-b border-[var(--admin-border)] px-4 py-3 last:border-b-0">
          <div className="h-4 w-24 bg-stone-200 rounded animate-pulse" />
          <div className="h-4 w-32 bg-stone-200 rounded animate-pulse" />
          <div className="h-4 w-20 bg-stone-200 rounded animate-pulse" />
          <div className="h-5 w-16 bg-stone-200 rounded-full animate-pulse" />
          <div className="h-4 w-16 bg-stone-200 rounded animate-pulse" />
          <div className="h-4 w-12 bg-stone-200 rounded animate-pulse" />
        </div>
      ))}
    </div>
  );
}

type State = {
  contacts: Contact[];
  total: number;
  search: string;
  sourceFilter: ContactSource | "";
  page: number;
  loading: boolean;
  deleting: string | null;
  exporting: boolean;
};

type Action =
  | { type: "SET_PAGE_RESULTS"; contacts: Contact[]; total: number }
  | { type: "SET_SEARCH"; value: string }
  | { type: "SET_SOURCE_FILTER"; value: ContactSource | "" }
  | { type: "SET_PAGE"; value: number }
  | { type: "SET_LOADING"; value: boolean }
  | { type: "SET_DELETING"; value: string | null }
  | { type: "SET_EXPORTING"; value: boolean }
  | { type: "REMOVE_CONTACT"; id: string };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_PAGE_RESULTS":
      return { ...state, contacts: action.contacts, total: action.total };
    case "SET_SEARCH":
      return { ...state, search: action.value };
    case "SET_SOURCE_FILTER":
      return { ...state, sourceFilter: action.value };
    case "SET_PAGE":
      return { ...state, page: action.value };
    case "SET_LOADING":
      return { ...state, loading: action.value };
    case "SET_DELETING":
      return { ...state, deleting: action.value };
    case "SET_EXPORTING":
      return { ...state, exporting: action.value };
    case "REMOVE_CONTACT":
      return {
        ...state,
        contacts: state.contacts.filter((c) => c.id !== action.id),
        total: state.total - 1,
      };
    default:
      return state;
  }
}

export default function ContactListPanel({
  initialContacts,
  initialTotal,
  brandId,
}: {
  initialContacts: Contact[];
  initialTotal: number;
  brandId: string;
}) {
  const limit = 50;
  const [state, dispatch] = useReducer(reducer, undefined, () => ({
    contacts: initialContacts,
    total: initialTotal,
    search: "",
    sourceFilter: "" as ContactSource | "",
    page: 0,
    loading: false,
    deleting: null,
    exporting: false,
  }));

  const hasFilters = state.search.length > 0 || state.sourceFilter !== "";

  const loadPage = useCallback(async (searchVal: string, sourceVal: string, pageNum: number) => {
    dispatch({ type: "SET_LOADING", value: true });
    const result = await getContacts({
      brandId,
      search: searchVal || undefined,
      source: sourceVal || undefined,
      limit,
      offset: pageNum * limit,
    });
    dispatch({ type: "SET_LOADING", value: false });
    if (result.success) {
      dispatch({ type: "SET_PAGE_RESULTS", contacts: result.contacts, total: result.total });
    }
  }, [brandId]);

  function handleSearch(e: React.FormEvent) {
    e.preventDefault();
    dispatch({ type: "SET_PAGE", value: 0 });
    loadPage(state.search, state.sourceFilter, 0);
  }

  function handleSourceFilter(val: ContactSource | "") {
    dispatch({ type: "SET_SOURCE_FILTER", value: val });
    dispatch({ type: "SET_PAGE", value: 0 });
    loadPage(state.search, val, 0);
  }

  function handlePage(dir: number) {
    const next = state.page + dir;
    dispatch({ type: "SET_PAGE", value: next });
    loadPage(state.search, state.sourceFilter, next);
  }

  async function handleDelete(id: string) {
    if (!confirm("Delete this contact? This action cannot be undone.")) return;
    dispatch({ type: "SET_DELETING", value: id });
    const result = await deleteContact(id);
    dispatch({ type: "SET_DELETING", value: null });
    if (result.success) {
      dispatch({ type: "REMOVE_CONTACT", id });
    }
  }

  async function handleExport() {
    dispatch({ type: "SET_EXPORTING", value: true });
    const result = await exportContacts({
      brandId,
      brandSlug: "contacts",
      search: state.search || undefined,
      source: state.sourceFilter || undefined,
    });
    dispatch({ type: "SET_EXPORTING", value: false });
    if (!result.success) {
      alert("Export failed: " + result.error);
      return;
    }
    const blob = new Blob([result.csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = result.filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  return (
    <div className="p-4 sm:p-6">
      <ContactsHeader
        total={state.total}
        exporting={state.exporting}
        canExport={state.total > 0}
        onExport={handleExport}
      />

      <form onSubmit={handleSearch}>
        <SearchAndFilters
          search={state.search}
          sourceFilter={state.sourceFilter}
          dispatch={dispatch}
          onSourceFilter={handleSourceFilter}
        />
      </form>

      {/* Table */}
      {state.loading ? (
        <ContactSkeleton />
      ) : state.contacts.length === 0 ? (
        <div className="overflow-hidden rounded-xl border border-[var(--admin-border)]">
          <EmptyState hasFilters={hasFilters} />
        </div>
      ) : (
        <>
          <ContactsList
            contacts={state.contacts}
            deleting={state.deleting}
            onDelete={handleDelete}
          />

          <Pagination
            page={state.page}
            total={state.total}
            limit={limit}
            onPage={handlePage}
          />
        </>
      )}
    </div>
  );
}

function ContactsHeader({
  total,
  exporting,
  canExport,
  onExport,
}: {
  total: number;
  exporting: boolean;
  canExport: boolean;
  onExport: () => void;
}) {
  return (
    <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
      <div className="flex items-center gap-3">
        <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-emerald-500 to-emerald-600 shadow-lg shadow-emerald-500/20">
          {Icons.users("w-6 h-6 text-white")}
        </div>
        <div>
          <h2 className="text-lg font-bold text-stone-900">Contacts</h2>
          <p className="text-sm text-stone-500">{total.toLocaleString()} contact{total !== 1 ? "s" : ""}</p>
        </div>
      </div>
      <div className="flex items-center gap-2">
        <AdminButton variant="secondary" onClick={onExport} disabled={exporting || !canExport} icon={Icons.download("w-4 h-4")}>
          {exporting ? "Exporting..." : "Export"}
        </AdminButton>
      </div>
    </div>
  );
}

function SearchAndFilters({
  search,
  sourceFilter,
  dispatch,
  onSourceFilter,
}: {
  search: string;
  sourceFilter: ContactSource | "";
  dispatch: React.Dispatch<Action>;
  onSourceFilter: (val: ContactSource | "") => void;
}) {
  return (
    <div className="flex flex-col sm:flex-row gap-3 mb-6">
      <div className="relative flex-1">
        <div className="absolute inset-y-0 left-3.5 flex items-center pointer-events-none">
          {Icons.search("h-5 w-5 text-stone-400")}
        </div>
        <input aria-label="Search Email, Name, Phone..."
          type="text"
          value={search}
          onChange={(e) => dispatch({ type: "SET_SEARCH", value: e.target.value })}
          placeholder="Search email, name, phone..."
          className="w-full pl-11 pr-4 py-2.5 text-sm border border-stone-200 rounded-xl bg-white text-stone-900 placeholder:text-stone-400 focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:border-transparent transition-all"
        />
      </div>
      <select aria-label="Select"
        value={sourceFilter}
        onChange={(e) => onSourceFilter(e.target.value as ContactSource | "")}
        className="px-4 py-2.5 text-sm border border-stone-200 rounded-xl bg-white text-stone-900 focus:outline-none focus:ring-2 focus:ring-emerald-500 transition-all"
      >
        <option value="">All Sources</option>
        <option value="order">From Orders</option>
        <option value="import">Imported</option>
        <option value="manual">Manual Entry</option>
        <option value="admin">Admin Added</option>
      </select>
      <button
        type="submit"
        className="rounded-xl bg-emerald-600 px-5 py-2.5 text-sm font-semibold text-white hover:bg-emerald-700 active:bg-emerald-800 transition-colors shadow-sm"
       aria-label="Search">
        Search
      </button>
    </div>
  );
}

function ContactsList({
  contacts,
  deleting,
  onDelete,
}: {
  contacts: Contact[];
  deleting: string | null;
  onDelete: (id: string) => void;
}) {
  return (
    <>
      {/* Desktop Table */}
      <div className="hidden sm:block overflow-hidden rounded-xl border border-[var(--admin-border)]">
        <table className="w-full text-sm">
          <thead className="bg-stone-50 border-b border-[var(--admin-border)]">
            <tr>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Name</th>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email</th>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Phone</th>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Source</th>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email Opt</th>
              <th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Unsubscribed</th>
              <th className="text-right px-4 py-3.5" aria-label="Actions"></th>
            </tr>
          </thead>
          <tbody className="divide-y divide-[var(--admin-border)] bg-white">
            {contacts.map((c) => (
              <ContactTableRow
                key={c.id}
                contact={c}
                deleting={deleting === c.id}
                onDelete={() => onDelete(c.id)}
              />
            ))}
          </tbody>
        </table>
      </div>

      {/* Mobile cards */}
      <div className="sm:hidden space-y-3">
        {contacts.map((c) => (
          <ContactMobileCard
            key={c.id}
            contact={c}
            deleting={deleting === c.id}
            onDelete={() => onDelete(c.id)}
          />
        ))}
      </div>
    </>
  );
}

function ContactTableRow({
  contact: c,
  deleting,
  onDelete,
}: {
  contact: Contact;
  deleting: boolean;
  onDelete: () => void;
}) {
  const displayName = c.full_name || `${c.first_name || ""} ${c.last_name || ""}`.trim() || "—";
  return (
    <tr className="hover:bg-stone-50 transition-colors">
      <td className="px-4 py-3.5 font-semibold text-stone-800">
        <div className="flex items-center gap-3">
          <div className="w-8 h-8 rounded-full bg-gradient-to-br from-emerald-400 to-emerald-500 flex items-center justify-center text-xs font-bold text-white">
            {displayName.slice(0, 2).toUpperCase()}
          </div>
          <span>{displayName}</span>
        </div>
      </td>
      <td className="px-4 py-3.5 text-stone-600">
        <div className="flex items-center gap-1.5">
          {Icons.mail("w-4 h-4 text-stone-400")}
          <span className="truncate max-w-[150px]">{c.email || "—"}</span>
        </div>
      </td>
      <td className="px-4 py-3.5 text-stone-600">{c.phone || "—"}</td>
      <td className="px-4 py-3.5">
        <span className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold capitalize ${SOURCE_COLORS[c.source]}`}>
          {c.source}
        </span>
      </td>
      <td className="px-4 py-3.5">
        {c.email_opt_in ? (
          <span className="inline-flex items-center gap-1 text-emerald-600 text-xs font-semibold">
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
              <polyline points="20 6 9 17 4 12"/>
            </svg>
            Opted in
          </span>
        ) : (
          <span className="inline-flex items-center gap-1 text-red-500 text-xs font-semibold">
            <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
              <line x1="18" y1="6" x2="6" y2="18"/>
              <line x1="6" y1="6" x2="18" y2="18"/>
            </svg>
            Opted out
          </span>
        )}
      </td>
      <td className="px-4 py-3.5 text-stone-500 text-xs">
        {c.unsubscribed_at ? formatDate(new Date(c.unsubscribed_at)) : "—"}
      </td>
      <td className="px-4 py-3.5 text-right">
        <button type="button"
          onClick={onDelete}
          disabled={deleting}
          className="p-1.5 rounded-lg hover:bg-red-50 text-red-500 hover:text-red-700 disabled:opacity-50 transition-colors"
          title="Delete contact"
         aria-label="Delete contact">
          {Icons.trash("h-4 w-4")}
        </button>
      </td>
    </tr>
  );
}

function ContactMobileCard({
  contact: c,
  deleting,
  onDelete,
}: {
  contact: Contact;
  deleting: boolean;
  onDelete: () => void;
}) {
  const displayName = c.full_name || `${c.first_name || ""} ${c.last_name || ""}`.trim() || "—";
  return (
    <div className="rounded-xl border border-[var(--admin-border)] bg-white p-4 space-y-3">
      <div className="flex items-start justify-between">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-full bg-gradient-to-br from-emerald-400 to-emerald-500 flex items-center justify-center text-xs font-bold text-white">
            {displayName.slice(0, 2).toUpperCase()}
          </div>
          <div>
            <div className="font-semibold text-stone-800 text-sm">
              {displayName}
            </div>
            <div className="text-xs text-stone-500">{c.email || "—"}</div>
          </div>
        </div>
        <button type="button"
          onClick={onDelete}
          disabled={deleting}
          className="p-1.5 rounded-lg hover:bg-red-50 text-red-500 hover:text-red-700 disabled:opacity-50"
        >
          {Icons.trash("h-4 w-4")}
        </button>
      </div>
      <div className="flex items-center gap-2 flex-wrap">
        <span className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold capitalize ${SOURCE_COLORS[c.source]}`}>
          {c.source}
        </span>
        {c.phone && (
          <span className="inline-flex items-center gap-1 text-xs text-stone-500">
            {c.phone}
          </span>
        )}
        {c.email_opt_in ? (
          <span className="inline-flex items-center gap-1 text-emerald-600 text-xs font-semibold">
            Opted in
          </span>
        ) : (
          <span className="inline-flex items-center gap-1 text-red-500 text-xs font-semibold">
            Opted out
          </span>
        )}
      </div>
    </div>
  );
}

function Pagination({
  page,
  total,
  limit,
  onPage,
}: {
  page: number;
  total: number;
  limit: number;
  onPage: (dir: number) => void;
}) {
  return (
    <div className="flex items-center justify-between mt-6 pt-4 border-t border-stone-100">
      <span className="text-sm text-stone-500">
        Showing {page * limit + 1}–{Math.min((page + 1) * limit, total)} of {total.toLocaleString()}
      </span>
      <div className="flex gap-2">
        <button type="button"
          onClick={() => onPage(-1)}
          disabled={page === 0}
          className="inline-flex items-center gap-1.5 rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium disabled:opacity-50 hover:bg-stone-50 transition-colors"
         aria-label="Previous">
          {Icons.chevronLeft("h-4 w-4")}
          <span>Previous</span>
        </button>
        <button type="button"
          onClick={() => onPage(1)}
          disabled={(page + 1) * limit >= total}
          className="inline-flex items-center gap-1.5 rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium disabled:opacity-50 hover:bg-stone-50 transition-colors"
         aria-label="Next">
          <span>Next</span>
          {Icons.chevronRight("h-4 w-4")}
        </button>
      </div>
    </div>
  );
}