import { createMemo, createSignal, For, Show } from "solid-js";
import { Building2, Mail, Phone, Plus, Search, Trash2, User } from "lucide-solid";

import Modal from "~/components/modal";
import { useApp } from "~/lib/app-context";
import {
  apiListContacts,
  apiCreateContact,
  apiUpdateContact,
  apiDeleteContact,
  apiListCompanies
} from "~/lib/api-crm";
import type { Contact, Company } from "~/lib/types-crm";
import { formatPrettyDate } from "~/lib/utils";

export default function ContactsRoute() {
  const app = useApp();
  const workspaceSlug = () => app.primaryWorkspace()?.slug ?? "personal";

  const [contacts, setContacts] = createSignal<Contact[]>([]);
  const [companies, setCompanies] = createSignal<Company[]>([]);
  const [loading, setLoading] = createSignal(true);
  const [search, setSearch] = createSignal("");
  const [showAdd, setShowAdd] = createSignal(false);
  const [selectedId, setSelectedId] = createSignal<string | null>(null);

  // Form state
  const [firstName, setFirstName] = createSignal("");
  const [lastName, setLastName] = createSignal("");
  const [email, setEmail] = createSignal("");
  const [phone, setPhone] = createSignal("");
  const [companyId, setCompanyId] = createSignal<string>("");
  const [title, setTitle] = createSignal("");
  const [notes, setNotes] = createSignal("");

  const loadContacts = async () => {
    setLoading(true);
    try {
      const [contactList, companyList] = await Promise.all([
        apiListContacts(workspaceSlug()),
        apiListCompanies(workspaceSlug())
      ]);
      setContacts(contactList);
      setCompanies(companyList);
    } catch (e) {
      console.error("Failed to load contacts", e);
    }
    setLoading(false);
  };

  // Load on mount
  if (contacts().length === 0) {
    loadContacts();
  }

  const filteredContacts = createMemo(() => {
    const q = search().toLowerCase();
    if (!q) return contacts();
    return contacts().filter(c =>
      c.firstName.toLowerCase().includes(q) ||
      c.lastName.toLowerCase().includes(q) ||
      c.email.toLowerCase().includes(q) ||
      c.companyName?.toLowerCase().includes(q)
    );
  });

  const selectedContact = createMemo(() =>
    contacts().find(c => c.id === selectedId())
  );

  const resetForm = () => {
    setFirstName("");
    setLastName("");
    setEmail("");
    setPhone("");
    setCompanyId("");
    setTitle("");
    setNotes("");
  };

  const handleAdd = async () => {
    if (!firstName().trim() && !lastName().trim()) return;

    const contact = await apiCreateContact({
      workspaceSlug: workspaceSlug(),
      firstName: firstName(),
      lastName: lastName(),
      email: email(),
      phone: phone(),
      companyId: companyId() || undefined,
      title: title(),
      notes: notes()
    });

    setContacts([...contacts(), contact]);
    setShowAdd(false);
    resetForm();
  };

  const handleUpdate = async () => {
    const id = selectedId();
    if (!id) return;

    const updated = await apiUpdateContact(id, {
      firstName: firstName(),
      lastName: lastName(),
      email: email(),
      phone: phone(),
      companyId: companyId() || undefined,
      title: title(),
      notes: notes()
    });

    setContacts(contacts().map(c => c.id === id ? updated : c));
    setSelectedId(null);
    resetForm();
  };

  const handleDelete = async (id: string) => {
    await apiDeleteContact(id);
    setContacts(contacts().filter(c => c.id !== id));
    if (selectedId() === id) setSelectedId(null);
  };

  const openEdit = (contact: Contact) => {
    setSelectedId(contact.id);
    setFirstName(contact.firstName);
    setLastName(contact.lastName);
    setEmail(contact.email);
    setPhone(contact.phone);
    setCompanyId(contact.companyId || "");
    setTitle(contact.title);
    setNotes(contact.notes);
  };

  return (
    <div class="flex h-full gap-6">
      {/* Main list */}
      <div class="flex-1 flex flex-col">
        <div class="flex items-center justify-between mb-4">
          <h1 class="text-2xl font-semibold">Contacts</h1>
          <button
            onClick={() => { resetForm(); setShowAdd(true); }}
            class="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-[var(--accent)] text-white hover:opacity-90"
          >
            <Plus class="w-4 h-4" />
            Add Contact
          </button>
        </div>

        {/* Search */}
        <div class="relative mb-4">
          <Search class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-muted)]" />
          <input
            type="text"
            placeholder="Search contacts..."
            value={search()}
            onInput={e => setSearch(e.currentTarget.value)}
            class="w-full pl-9 pr-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
          />
        </div>

        {/* Contact list */}
        <Show when={!loading()} fallback={<div class="text-[var(--text-muted)]">Loading...</div>}>
          <div class="flex-1 overflow-auto space-y-2">
            <Show when={filteredContacts().length === 0}>
              <div class="text-center py-12 text-[var(--text-muted)]">
                No contacts yet. Add your first contact to get started.
              </div>
            </Show>
            <For each={filteredContacts()}>
              {contact => (
                <div
                  class="flex items-center gap-4 p-4 rounded-lg border border-[var(--border)] bg-[var(--surface)] hover:border-[var(--accent)] cursor-pointer transition-colors"
                  onClick={() => openEdit(contact)}
                >
                  <div class="w-10 h-10 rounded-full bg-[var(--accent)] flex items-center justify-center text-white font-medium">
                    {(contact.firstName[0] || "") + (contact.lastName[0] || "")}
                  </div>
                  <div class="flex-1 min-w-0">
                    <div class="font-medium truncate">
                      {contact.firstName} {contact.lastName}
                    </div>
                    <div class="text-sm text-[var(--text-muted)] truncate">
                      {contact.title && <span>{contact.title}</span>}
                      {contact.title && contact.companyName && <span> at </span>}
                      {contact.companyName && <span>{contact.companyName}</span>}
                    </div>
                  </div>
                  <div class="flex items-center gap-2 text-[var(--text-muted)]">
                    {contact.email && <Mail class="w-4 h-4" />}
                    {contact.phone && <Phone class="w-4 h-4" />}
                  </div>
                </div>
              )}
            </For>
          </div>
        </Show>
      </div>

      {/* Add Modal */}
      <Modal open={showAdd()} onClose={() => setShowAdd(false)} title="Add Contact">
        <div class="space-y-4">
          <div class="grid grid-cols-2 gap-4">
            <div>
              <label class="block text-sm font-medium mb-1">First Name</label>
              <input
                type="text"
                value={firstName()}
                onInput={e => setFirstName(e.currentTarget.value)}
                class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
              />
            </div>
            <div>
              <label class="block text-sm font-medium mb-1">Last Name</label>
              <input
                type="text"
                value={lastName()}
                onInput={e => setLastName(e.currentTarget.value)}
                class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
              />
            </div>
          </div>
          <div>
            <label class="block text-sm font-medium mb-1">Email</label>
            <input
              type="email"
              value={email()}
              onInput={e => setEmail(e.currentTarget.value)}
              class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
            />
          </div>
          <div>
            <label class="block text-sm font-medium mb-1">Phone</label>
            <input
              type="tel"
              value={phone()}
              onInput={e => setPhone(e.currentTarget.value)}
              class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
            />
          </div>
          <div>
            <label class="block text-sm font-medium mb-1">Company</label>
            <select
              value={companyId()}
              onChange={e => setCompanyId(e.currentTarget.value)}
              class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
            >
              <option value="">None</option>
              <For each={companies()}>
                {company => <option value={company.id}>{company.name}</option>}
              </For>
            </select>
          </div>
          <div>
            <label class="block text-sm font-medium mb-1">Title</label>
            <input
              type="text"
              value={title()}
              onInput={e => setTitle(e.currentTarget.value)}
              class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
              placeholder="e.g. Product Manager"
            />
          </div>
          <div>
            <label class="block text-sm font-medium mb-1">Notes</label>
            <textarea
              value={notes()}
              onInput={e => setNotes(e.currentTarget.value)}
              class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)] min-h-[80px]"
            />
          </div>
          <div class="flex justify-end gap-2 pt-2">
            <button
              onClick={() => setShowAdd(false)}
              class="px-4 py-2 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-hover)]"
            >
              Cancel
            </button>
            <button
              onClick={handleAdd}
              class="px-4 py-2 rounded-lg bg-[var(--accent)] text-white hover:opacity-90"
            >
              Add Contact
            </button>
          </div>
        </div>
      </Modal>

      {/* Edit Modal */}
      <Modal open={selectedId() !== null} onClose={() => { setSelectedId(null); resetForm(); }} title="Edit Contact">
        <Show when={selectedContact()}>
          {contact => (
            <div class="space-y-4">
              <div class="grid grid-cols-2 gap-4">
                <div>
                  <label class="block text-sm font-medium mb-1">First Name</label>
                  <input
                    type="text"
                    value={firstName()}
                    onInput={e => setFirstName(e.currentTarget.value)}
                    class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                  />
                </div>
                <div>
                  <label class="block text-sm font-medium mb-1">Last Name</label>
                  <input
                    type="text"
                    value={lastName()}
                    onInput={e => setLastName(e.currentTarget.value)}
                    class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                  />
                </div>
              </div>
              <div>
                <label class="block text-sm font-medium mb-1">Email</label>
                <input
                  type="email"
                  value={email()}
                  onInput={e => setEmail(e.currentTarget.value)}
                  class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                />
              </div>
              <div>
                <label class="block text-sm font-medium mb-1">Phone</label>
                <input
                  type="tel"
                  value={phone()}
                  onInput={e => setPhone(e.currentTarget.value)}
                  class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                />
              </div>
              <div>
                <label class="block text-sm font-medium mb-1">Company</label>
                <select
                  value={companyId()}
                  onChange={e => setCompanyId(e.currentTarget.value)}
                  class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                >
                  <option value="">None</option>
                  <For each={companies()}>
                    {company => <option value={company.id}>{company.name}</option>}
                  </For>
                </select>
              </div>
              <div>
                <label class="block text-sm font-medium mb-1">Title</label>
                <input
                  type="text"
                  value={title()}
                  onInput={e => setTitle(e.currentTarget.value)}
                  class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)]"
                />
              </div>
              <div>
                <label class="block text-sm font-medium mb-1">Notes</label>
                <textarea
                  value={notes()}
                  onInput={e => setNotes(e.currentTarget.value)}
                  class="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--surface)] min-h-[80px]"
                />
              </div>
              <div class="flex justify-between pt-2">
                <button
                  onClick={() => handleDelete(contact.id)}
                  class="px-4 py-2 rounded-lg text-red-500 hover:bg-red-50 dark:hover:bg-red-950"
                >
                  Delete
                </button>
                <div class="flex gap-2">
                  <button
                    onClick={() => { setSelectedId(null); resetForm(); }}
                    class="px-4 py-2 rounded-lg border border-[var(--border)] hover:bg-[var(--surface-hover)]"
                  >
                    Cancel
                  </button>
                  <button
                    onClick={handleUpdate}
                    class="px-4 py-2 rounded-lg bg-[var(--accent)] text-white hover:opacity-90"
                  >
                    Save
                  </button>
                </div>
              </div>
            </div>
          )}
        </Show>
      </Modal>
    </div>
  );
}