'use client';

import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation';
import { useMemo, useRef, useState } from 'react';

type ContactRow = {
  id: string;
  name: string;
  email: string | null;
  phoneNumber: string;
  company: string | null;
  status: 'Active' | 'Inactive';
  tags: string[];
  location: string;
  lastMessageLabel: string;
  avatarInitials: string;
};

type Props = {
  data: {
    items: ContactRow[];
    total: number;
    page: number;
    pageSize: number;
    totalPages: number;
    availableTags: string[];
    statusCounts: {
      active: number;
      inactive: number;
    };
  };
  filters: {
    search: string;
    status: string;
    tag: string;
  };
};

export function ContactsDirectoryBoard({ data, filters }: Props) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const [form, setForm] = useState({
    name: '',
    phoneNumber: '',
    email: '',
    company: '',
    notes: '',
  });

  const pageNumbers = useMemo(() => {
    const pages = new Set<number>();
    pages.add(1);
    pages.add(data.totalPages);
    pages.add(data.page);
    pages.add(Math.max(1, data.page - 1));
    pages.add(Math.min(data.totalPages, data.page + 1));
    return Array.from(pages).sort((left, right) => left - right);
  }, [data.page, data.totalPages]);

  function updateQuery(updates: Record<string, string | number | null>) {
    const params = new URLSearchParams(searchParams.toString());
    for (const [key, value] of Object.entries(updates)) {
      if (value === null || value === '' || value === 'all') {
        params.delete(key);
      } else {
        params.set(key, String(value));
      }
    }

    if (Object.keys(updates).some((key) => key !== 'page')) {
      params.set('page', '1');
    }

    router.push(`/dashboard/contacts${params.toString() ? `?${params.toString()}` : ''}`);
  }

  async function importCsv(file: File) {
    const text = await file.text();
    const rows = text
      .split(/\r?\n/)
      .map((row) => row.trim())
      .filter(Boolean);
    if (rows.length < 2) {
      throw new Error('CSV file is empty.');
    }

    const headers = rows[0].split(',').map((value) => value.trim().toLowerCase());
    const items = rows.slice(1).map((row) => {
      const cols = row.split(',').map((value) => value.trim().replace(/^"|"$/g, ''));
      const get = (key: string) => cols[headers.indexOf(key)] || '';
      return {
        name: get('name'),
        phoneNumber: get('phonenumber') || get('phone_number') || get('phone'),
        email: get('email'),
        company: get('company'),
        notes: get('notes'),
      };
    }).filter((item) => item.name && item.phoneNumber);

    if (items.length === 0) {
      throw new Error('CSV does not contain valid contact rows.');
    }

    for (const item of items) {
      const response = await fetch('/api/contacts', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(item),
      });

      if (!response.ok) {
        const payload = await response.json().catch(() => ({}));
        throw new Error(typeof payload?.message === 'string' ? payload.message : `Failed to import contact ${item.name}`);
      }
    }

    return items.length;
  }

  return (
    <div className="contacts-directory-page">
      <section className="contacts-directory-header">
        <div>
          <h1>Contacts Directory</h1>
          <p>Manage your customer database and communication segments.</p>
        </div>
        <div className="contacts-directory-actions">
          <input
            ref={fileInputRef}
            type="file"
            accept=".csv,text/csv"
            hidden
            onChange={async (event) => {
              const file = event.target.files?.[0];
              if (!file) return;
              try {
                setError(null);
                setNotice(null);
                setIsSubmitting(true);
                const imported = await importCsv(file);
                setNotice(`Imported ${imported} contacts successfully.`);
                router.refresh();
              } catch (importError) {
                setError(importError instanceof Error ? importError.message : 'Failed to import contacts');
              } finally {
                setIsSubmitting(false);
                event.target.value = '';
              }
            }}
          />
          <button type="button" className="contacts-secondary-button" onClick={() => fileInputRef.current?.click()}>
            <span className="material-symbols-outlined">upload</span>
            Import
          </button>
          <a
            className="contacts-secondary-button"
            href={`/api/contacts/export?${new URLSearchParams({
              ...(filters.search ? { search: filters.search } : {}),
              ...(filters.status ? { status: filters.status } : {}),
              ...(filters.tag ? { tag: filters.tag } : {}),
            }).toString()}`}
          >
            <span className="material-symbols-outlined">download</span>
            Export
          </a>
          <button type="button" className="contacts-primary-button" onClick={() => setIsCreateOpen(true)}>
            <span className="material-symbols-outlined">person_add</span>
            Add Contact
          </button>
        </div>
      </section>

      {notice ? <p className="contacts-form-success">{notice}</p> : null}
      {error && !isCreateOpen ? <p className="contacts-form-error">{error}</p> : null}

      <section className="contacts-filter-bar">
        <div className="contacts-filter-label">
          <span className="material-symbols-outlined">filter_list</span>
          <span>Filters</span>
        </div>

        <input
          className="contacts-filter-input"
          value={filters.search}
          onChange={(event) => updateQuery({ search: event.target.value })}
          placeholder="Search contacts..."
        />

        <select
          className="contacts-filter-select"
          value={filters.status || 'all'}
          onChange={(event) => updateQuery({ status: event.target.value })}
        >
          <option value="all">All Statuses</option>
          <option value="Active">Active</option>
          <option value="Inactive">Inactive</option>
        </select>

        <select
          className="contacts-filter-select"
          value={filters.tag || 'all'}
          onChange={(event) => updateQuery({ tag: event.target.value })}
        >
          <option value="all">All Tags</option>
          {data.availableTags.map((tag) => (
            <option key={tag} value={tag}>
              {tag}
            </option>
          ))}
        </select>

        <button type="button" className="contacts-clear-button" onClick={() => router.push('/dashboard/contacts')}>
          Clear all filters
        </button>
      </section>

      <section className="contacts-table-card">
        <div className="contacts-table-wrap">
          <table className="contacts-table">
            <thead>
              <tr>
                <th>Contact Name</th>
                <th>Phone Number</th>
                <th>Status</th>
                <th>Tags</th>
                <th>Last Message</th>
                <th />
              </tr>
            </thead>
            <tbody>
              {data.items.map((contact) => (
                <tr key={contact.id}>
                  <td>
                    <Link href={`/dashboard/contacts/${contact.id}`} className="contacts-contact-cell">
                      <span className="contacts-avatar">{contact.avatarInitials}</span>
                      <span>
                        <strong>{contact.name}</strong>
                        <small>{contact.email || contact.location}</small>
                      </span>
                    </Link>
                  </td>
                  <td className="contacts-mono-cell">{contact.phoneNumber}</td>
                  <td>
                    <span className={contact.status === 'Active' ? 'contacts-status-chip is-active' : 'contacts-status-chip is-inactive'}>
                      {contact.status}
                    </span>
                  </td>
                  <td>
                    <div className="contacts-tags-inline">
                      {contact.tags.slice(0, 2).map((tag) => (
                        <span key={tag} className="contacts-tag-chip">
                          {tag}
                        </span>
                      ))}
                    </div>
                  </td>
                  <td>{contact.lastMessageLabel}</td>
                  <td className="contacts-table-actions">
                    <Link href={`/dashboard/contacts/${contact.id}`} className="contacts-icon-button">
                      <span className="material-symbols-outlined">more_vert</span>
                    </Link>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="contacts-table-footer">
          <div>
            Showing <strong>{data.total === 0 ? 0 : (data.page - 1) * data.pageSize + 1} - {(data.page - 1) * data.pageSize + data.items.length}</strong> of{' '}
            <strong>{data.total}</strong> contacts
          </div>

          <div className="contacts-pagination">
            <button
              type="button"
              className="contacts-page-button"
              disabled={data.page <= 1}
              onClick={() => updateQuery({ page: data.page - 1 })}
            >
              <span className="material-symbols-outlined">chevron_left</span>
            </button>
            {pageNumbers.map((pageNumber, index) => (
              <span key={pageNumber}>
                {index > 0 && pageNumber - pageNumbers[index - 1] > 1 ? <span className="contacts-page-gap">...</span> : null}
                <button
                  type="button"
                  className={pageNumber === data.page ? 'contacts-page-button is-active' : 'contacts-page-button'}
                  onClick={() => updateQuery({ page: pageNumber })}
                >
                  {pageNumber}
                </button>
              </span>
            ))}
            <button
              type="button"
              className="contacts-page-button"
              disabled={data.page >= data.totalPages}
              onClick={() => updateQuery({ page: data.page + 1 })}
            >
              <span className="material-symbols-outlined">chevron_right</span>
            </button>
          </div>

          <label className="contacts-rows-label">
            <span>Rows per page:</span>
            <select
              value={String(data.pageSize)}
              onChange={(event) => updateQuery({ limit: event.target.value })}
            >
              <option value="10">10</option>
              <option value="20">20</option>
              <option value="50">50</option>
              <option value="100">100</option>
            </select>
          </label>
        </div>
      </section>

      <button type="button" className="contacts-fab" onClick={() => setIsCreateOpen(true)}>
        <span className="material-symbols-outlined">add</span>
      </button>

      {isCreateOpen ? (
        <div className="contacts-modal-backdrop" onClick={() => setIsCreateOpen(false)}>
          <div className="contacts-modal-card" onClick={(event) => event.stopPropagation()}>
            <div className="contacts-modal-head">
              <div>
                <p>New Contact</p>
                <h2>Add a new contact profile</h2>
              </div>
              <button type="button" className="contacts-icon-button" onClick={() => setIsCreateOpen(false)}>
                <span className="material-symbols-outlined">close</span>
              </button>
            </div>

            <form
              className="contacts-form-grid"
              onSubmit={async (event) => {
                event.preventDefault();
                try {
                  setError(null);
                  setIsSubmitting(true);
                  const response = await fetch('/api/contacts', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(form),
                  });
                  const payload = await response.json();
                  if (!response.ok) {
                    throw new Error(typeof payload?.message === 'string' ? payload.message : 'Failed to create contact');
                  }

                  setIsCreateOpen(false);
                  setForm({ name: '', phoneNumber: '', email: '', company: '', notes: '' });
                  router.refresh();
                } catch (submissionError) {
                  setError(submissionError instanceof Error ? submissionError.message : 'Failed to create contact');
                } finally {
                  setIsSubmitting(false);
                }
              }}
            >
              <label className="contacts-form-field">
                <span>Full Name</span>
                <input value={form.name} onChange={(event) => setForm((current) => ({ ...current, name: event.target.value }))} />
              </label>
              <label className="contacts-form-field">
                <span>Phone Number</span>
                <input value={form.phoneNumber} onChange={(event) => setForm((current) => ({ ...current, phoneNumber: event.target.value }))} />
              </label>
              <label className="contacts-form-field">
                <span>Email Address</span>
                <input value={form.email} onChange={(event) => setForm((current) => ({ ...current, email: event.target.value }))} />
              </label>
              <label className="contacts-form-field">
                <span>Company</span>
                <input value={form.company} onChange={(event) => setForm((current) => ({ ...current, company: event.target.value }))} />
              </label>
              <label className="contacts-form-field is-full">
                <span>Notes</span>
                <textarea rows={4} value={form.notes} onChange={(event) => setForm((current) => ({ ...current, notes: event.target.value }))} />
              </label>

              {error ? <p className="contacts-form-error">{error}</p> : null}

              <div className="contacts-form-actions">
                <button type="button" className="contacts-secondary-button" onClick={() => setIsCreateOpen(false)}>
                  Cancel
                </button>
                <button type="submit" className="contacts-primary-button" disabled={isSubmitting}>
                  <span className="material-symbols-outlined">save</span>
                  {isSubmitting ? 'Saving...' : 'Save Contact'}
                </button>
              </div>
            </form>
          </div>
        </div>
      ) : null}
    </div>
  );
}
