import React, { useEffect, useMemo, useState } from 'react';
import { Card, Table, Form, Button } from 'react-bootstrap';
import { Link, router } from '@inertiajs/react';
import IconifyIcon from '@/components/wrappers/IconifyIcon';
import { formatPhone, telDigits } from '../utils';

type AssociationRow = {
  id: number;
  account_contact_id?: number | null;
  name: string;
  title?: string | null;
  position?: string | null;
  email?: string | null;
  status?: string | null;
  relationship_type?: string | null;
  notes?: string | null;
  sort_order?: number | null;
  phone?: string | null;
  mobile?: string | null;
};

type AccountSearchRow = {
  id: number;
  name: string;
};

type AvailableContactRow = {
  id: number;
  name: string;
  email?: string | null;
  title?: string | null;
};

type Props = {
  accountId: number;
  associations: AssociationRow[];
  availableAssociationContacts?: AvailableContactRow[];
  show: boolean;
};

export default function AssociationsCard({ accountId, associations, show }: Props) {
  const [adding, setAdding] = useState(false);
  const [accountSearch, setAccountSearch] = useState('');
  const [accountResults, setAccountResults] = useState<AccountSearchRow[]>([]);
  const [selectedAccountId, setSelectedAccountId] = useState<number | null>(null);
  const [selectedAccountName, setSelectedAccountName] = useState('');
  const [loadingAccounts, setLoadingAccounts] = useState(false);
  const [loadingContacts, setLoadingContacts] = useState(false);
  const [accountContacts, setAccountContacts] = useState<AvailableContactRow[]>([]);
  const [contactId, setContactId] = useState('');
  const [relationshipType, setRelationshipType] = useState('');
  const [notes, setNotes] = useState('');
  const [saving, setSaving] = useState(false);

  const [editingPivotId, setEditingPivotId] = useState<number | null>(null);
  const [editRelationshipType, setEditRelationshipType] = useState('');
  const [editNotes, setEditNotes] = useState('');
  const [updating, setUpdating] = useState(false);

  const rows = useMemo(() => (Array.isArray(associations) ? associations : []), [associations]);

  const resetForm = () => {
    setAccountSearch('');
    setAccountResults([]);
    setSelectedAccountId(null);
    setSelectedAccountName('');
    setAccountContacts([]);
    setContactId('');
    setRelationshipType('');
    setNotes('');
    setLoadingAccounts(false);
    setLoadingContacts(false);
  };

  const toggleAdding = () => {
    if (adding) {
      resetForm();
      setAdding(false);
      return;
    }

    setAdding(true);
  };

  useEffect(() => {
    if (!show || !adding) return;

    const q = accountSearch.trim();

    if (q.length < 2) {
      setAccountResults([]);
      setLoadingAccounts(false);
      return;
    }

    const controller = new AbortController();

    const timer = window.setTimeout(async () => {
      try {
        setLoadingAccounts(true);

        const url =
          route('accounts.associations.account-search', accountId) +
          `?q=${encodeURIComponent(q)}`;

        const res = await fetch(url, {
          method: 'GET',
          headers: {
            Accept: 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
          },
          signal: controller.signal,
        });

        if (!res.ok) throw new Error(`Account search failed: ${res.status}`);

        const data = await res.json();
        setAccountResults(Array.isArray(data) ? data : []);
      } catch (error: any) {
        if (error?.name !== 'AbortError') {
          console.error('Association account search failed', error);
          setAccountResults([]);
        }
      } finally {
        setLoadingAccounts(false);
      }
    }, 250);

    return () => {
      controller.abort();
      window.clearTimeout(timer);
    };
  }, [accountSearch, accountId, adding, show]);

  useEffect(() => {
    if (!show || !adding || !selectedAccountId) {
      setAccountContacts([]);
      setContactId('');
      return;
    }

    const controller = new AbortController();

    const loadContacts = async () => {
      try {
        setLoadingContacts(true);

        const res = await fetch(route('accounts.associations.account-contacts', selectedAccountId), {
          method: 'GET',
          headers: {
            Accept: 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
          },
          signal: controller.signal,
        });

        if (!res.ok) throw new Error(`Contact load failed: ${res.status}`);

        const data = await res.json();
        setAccountContacts(Array.isArray(data) ? data : []);
      } catch (error: any) {
        if (error?.name !== 'AbortError') {
          console.error('Association contact load failed', error);
          setAccountContacts([]);
        }
      } finally {
        setLoadingContacts(false);
      }
    };

    loadContacts();

    return () => controller.abort();
  }, [adding, selectedAccountId, show]);

  const handlePickAccount = (row: AccountSearchRow) => {
    setSelectedAccountId(Number(row.id));
    setSelectedAccountName(row.name);
    setAccountSearch(row.name);
    setAccountResults([]);
    setAccountContacts([]);
    setContactId('');
  };

  const clearSelectedAccount = () => {
    setSelectedAccountId(null);
    setSelectedAccountName('');
    setAccountSearch('');
    setAccountResults([]);
    setAccountContacts([]);
    setContactId('');
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    if (!accountId || !selectedAccountId || !contactId || !relationshipType.trim()) return;

    setSaving(true);

    router.post(
      route('accounts.associations.store', accountId),
      {
        source_account_id: selectedAccountId,
        contact_id: Number(contactId),
        relationship_type: relationshipType.trim(),
        notes: notes.trim() || null,
      },
      {
        preserveScroll: true,
        onSuccess: () => {
          resetForm();
          setAdding(false);
        },
        onFinish: () => setSaving(false),
      }
    );
  };

  const startEdit = (row: AssociationRow) => {
    if (!row.account_contact_id) return;

    setEditingPivotId(row.account_contact_id);
    setEditRelationshipType(row.relationship_type || '');
    setEditNotes(row.notes || '');
  };

  const cancelEdit = () => {
    setEditingPivotId(null);
    setEditRelationshipType('');
    setEditNotes('');
    setUpdating(false);
  };

  const saveEdit = (pivotId: number) => {
    if (!editRelationshipType.trim()) return;

    setUpdating(true);

    router.patch(
      route('accounts.associations.update', [accountId, pivotId]),
      {
        relationship_type: editRelationshipType.trim(),
        notes: editNotes.trim() || null,
      },
      {
        preserveScroll: true,
        onSuccess: cancelEdit,
        onFinish: () => setUpdating(false),
      }
    );
  };

  const removeAssociation = (row: AssociationRow) => {
    if (!row.account_contact_id) return;

    if (window.confirm(`Remove association "${row.name}" from this account?`)) {
      router.delete(route('accounts.associations.destroy', [accountId, row.account_contact_id]), {
        preserveScroll: true,
      });
    }
  };

  if (!show) return null;

  return (
    <Card id="account-section-associations" className="gd-form-card gd-subcard mb-4 p-0 overflow-hidden">
      <Card.Body className="px-4 py-3">
        <div className="d-flex align-items-center justify-content-between mb-3">
          <div className="d-flex align-items-center gap-2 text-uppercase fw-semibold">
            <IconifyIcon icon="tabler:link" width={18} />
            <span style={{ fontSize: '0.8rem', letterSpacing: '0.05em', color: '#013254' }}>
              Associations
            </span>
          </div>

          <Button type="button" size="sm" variant="success" onClick={toggleAdding}>
            {adding ? 'Cancel' : 'Add Association'}
          </Button>
        </div>

        {adding && (
          <Form onSubmit={handleSubmit} className="border rounded p-3 mb-3 bg-light">
            <div className="row g-3">
              <div className="col-md-5 position-relative">
                <Form.Label>Account</Form.Label>
                <Form.Control
                  type="text"
                  value={accountSearch}
                  onChange={(e) => {
                    setAccountSearch(e.target.value);
                    setSelectedAccountId(null);
                    setSelectedAccountName('');
                    setAccountContacts([]);
                    setContactId('');
                  }}
                  placeholder="Search account (min 2 characters)"
                  autoComplete="off"
                />

                {selectedAccountId && selectedAccountName ? (
                  <div className="small text-muted mt-1 d-flex align-items-center gap-2">
                    <span>Selected: {selectedAccountName}</span>
                    <button type="button" className="btn btn-link btn-sm p-0 text-decoration-none" onClick={clearSelectedAccount}>
                      Change
                    </button>
                  </div>
                ) : null}

                {loadingAccounts && <div className="small text-muted mt-1">Searching accounts...</div>}

                {!selectedAccountId && accountSearch.trim().length >= 2 && accountResults.length > 0 && (
                  <div className="border rounded bg-white shadow-sm mt-1 position-absolute start-0 end-0 z-3" style={{ maxHeight: 240, overflowY: 'auto' }}>
                    {accountResults.map((row) => (
                      <button
                        key={row.id}
                        type="button"
                        className="btn btn-link text-start text-decoration-none w-100 px-3 py-2 border-0 rounded-0"
                        style={{ color: '#212529' }}
                        onClick={() => handlePickAccount(row)}
                      >
                        {row.name}
                      </button>
                    ))}
                  </div>
                )}

                {!selectedAccountId && accountSearch.trim().length >= 2 && !loadingAccounts && accountResults.length === 0 && (
                  <div className="small text-muted mt-1">No matching accounts found.</div>
                )}
              </div>

              <div className="col-md-4">
                <Form.Label>Contact</Form.Label>
                <Form.Select value={contactId} onChange={(e) => setContactId(e.target.value)} disabled={!selectedAccountId || loadingContacts} required>
                  <option value="">
                    {!selectedAccountId ? 'Select account first' : loadingContacts ? 'Loading contacts...' : 'Select contact'}
                  </option>

                  {accountContacts.map((row) => (
                    <option key={row.id} value={row.id}>
                      {row.name}
                      {row.title ? ` — ${row.title}` : ''}
                      {row.email ? ` — ${row.email}` : ''}
                    </option>
                  ))}
                </Form.Select>

                {selectedAccountId && !loadingContacts && accountContacts.length === 0 && (
                  <div className="small text-muted mt-1">No active contacts found for that account.</div>
                )}
              </div>

              <div className="col-md-3">
                <Form.Label>Relationship Type</Form.Label>
                <Form.Control
                  type="text"
                  value={relationshipType}
                  onChange={(e) => setRelationshipType(e.target.value)}
                  placeholder="Owner, Engineer, Contractor..."
                  required
                />
              </div>

              <div className="col-12">
                <Form.Label>Notes</Form.Label>
                <Form.Control as="textarea" rows={2} value={notes} onChange={(e) => setNotes(e.target.value)} placeholder="Optional notes" />
              </div>

              <div className="col-12 d-flex justify-content-end gap-2">
                <Button type="button" variant="light" onClick={toggleAdding} disabled={saving}>
                  Cancel
                </Button>

                <Button type="submit" variant="success" disabled={saving || !selectedAccountId || !contactId || !relationshipType.trim()}>
                  {saving ? 'Saving...' : 'Save'}
                </Button>
              </div>
            </div>
          </Form>
        )}

        {rows.length === 0 ? (
          <div className="text-muted">No associations found for this account.</div>
        ) : (
          <div className="table-responsive">
            <Table hover className="align-middle mb-0">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Relationship Type</th>
                  <th>Notes</th>
                  <th>Phone</th>
                  <th>Email</th>
                  <th>Status</th>
                  <th className="text-end">Actions</th>
                </tr>
              </thead>
              <tbody>
                {rows.map((row) => {
                  const phoneDisplay = row.phone || row.mobile || null;
                  const phoneHref = phoneDisplay ? telDigits(phoneDisplay) : '';
                  const pivotId = row.account_contact_id || null;
                  const isEditing = pivotId !== null && editingPivotId === pivotId;

                  return (
                    <tr key={pivotId || row.id}>
                      <td>
                        <Link href={route('contacts.show', row.id)} className="fw-semibold text-decoration-none" style={{ color: '#013254' }}>
                          {row.name || `Contact #${row.id}`}
                        </Link>
                      </td>

                      <td>
                        {isEditing ? (
                          <Form.Control
                            size="sm"
                            type="text"
                            value={editRelationshipType}
                            onChange={(e) => setEditRelationshipType(e.target.value)}
                          />
                        ) : (
                          row.relationship_type || 'Association'
                        )}
                      </td>

                      <td>
                        {isEditing ? (
                          <Form.Control
                            size="sm"
                            type="text"
                            value={editNotes}
                            onChange={(e) => setEditNotes(e.target.value)}
                            placeholder="Optional notes"
                          />
                        ) : (
                          row.notes || <span className="text-muted">—</span>
                        )}
                      </td>

                      <td>
                        {phoneDisplay ? (
                          <a href={`tel:${phoneHref}`}>{formatPhone(phoneDisplay)}</a>
                        ) : (
                          <span className="text-muted">—</span>
                        )}
                      </td>

                      <td>
                        {row.email ? <a href={`mailto:${row.email}`}>{row.email}</a> : <span className="text-muted">—</span>}
                      </td>

                      <td>{row.status || '—'}</td>

                      <td className="text-end" style={{ whiteSpace: 'nowrap' }}>
                        {isEditing && pivotId ? (
                          <>
                            <button
                              type="button"
                              className="btn btn-link p-0 me-2 text-success"
                              title="Save association"
                              disabled={updating || !editRelationshipType.trim()}
                              onClick={() => saveEdit(pivotId)}
                            >
                              <IconifyIcon icon="tabler:check" width={16} />
                            </button>

                            <button type="button" className="btn btn-link p-0 text-muted" title="Cancel edit" onClick={cancelEdit}>
                              <IconifyIcon icon="tabler:x" width={16} />
                            </button>
                          </>
                        ) : (
                          <>
                            <Link href={route('contacts.show', row.id)} className="btn btn-link p-0 me-2" title="View contact">
                              <IconifyIcon icon="tabler:eye" width={16} />
                            </Link>

                            <button type="button" className="btn btn-link p-0 me-2" title="Edit association" onClick={() => startEdit(row)}>
                              <IconifyIcon icon="tabler:pencil" width={16} />
                            </button>

                            <button type="button" className="btn btn-link p-0 text-danger" title="Remove association" onClick={() => removeAssociation(row)}>
                              <IconifyIcon icon="tabler:trash" width={16} />
                            </button>
                          </>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </Table>
          </div>
        )}
      </Card.Body>
    </Card>
  );
}