/**
 * Contacts page — unified 3-column layout (folder tree + list + detail).
 * Replaces old separate Contacts and Company pages.
 * Uses ResizablePanel for drag-to-resize columns, like Mail.tsx.
 */

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { ResizablePanel } from '@/components/ui/ResizablePanel';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Select } from '@/components/ui/Select';
import { useToast } from '@/components/ui/Toast';
import { EmptyState } from '@/components/ui/EmptyState';
import { usePluginToolbarStore } from '@/store/pluginToolbarStore';
import { ContactFolderTree, type ContactFilter } from '@/components/contacts/ContactFolderTree';
import { ContactList, type ContactViewMode } from '@/components/contacts/ContactList';
import { ContactDetail } from '@/components/contacts/ContactDetail';
import { ContactEditModal } from '@/components/contacts/ContactEditModal';
import {
  useUnifiedContacts,
  useUnifiedContact,
  type UnifiedContact,
} from '@/api/hooks';

const PAGE_SIZE = 25;

export function ContactsListPage() {
  const { t } = useTranslation();
  const toast = useToast();

  const [selectedFilter, setSelectedFilter] = useState<ContactFilter>('all');
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [page, setPage] = useState(1);
  const [sortBy, setSortBy] = useState('displayname');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
  const [viewMode, setViewMode] = useState<ContactViewMode>('list');
  const [selectedContactId, setSelectedContactId] = useState<string | null>(null);
  const [activeView, setActiveView] = useState<'folders' | 'list' | 'detail'>('folders');
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [editingContact, setEditingContact] = useState<UnifiedContact | null>(null);

  // Debounce search
  useEffect(() => {
    const timer = setTimeout(() => setDebouncedSearch(search), 300);
    return () => clearTimeout(timer);
  }, [search]);

  // Derive type filter from selectedFilter
  const contactType = useMemo(() => {
    if (selectedFilter === 'company') return 'company';
    if (selectedFilter === 'person') return 'person';
    return undefined;
  }, [selectedFilter]);

  // Derive tag filter
  const tagFilter = useMemo(() => {
    if (selectedFilter.startsWith('tag:')) return selectedFilter.slice(4);
    return undefined;
  }, [selectedFilter]);

  // Fetch contacts list
  const { data, isLoading } = useUnifiedContacts(
    page,
    PAGE_SIZE,
    debouncedSearch || undefined,
    contactType,
    sortBy,
    sortOrder,
  );

  // Fetch selected contact detail (with contact_persons)
  const { data: selectedContact, isLoading: loadingDetail } = useUnifiedContact(selectedContactId || undefined);

  const contacts = data?.items ?? [];
  const total = data?.total ?? 0;

  // Derive tags from all loaded contacts (for folder tree)
  const allTags = useMemo(() => {
    const tagSet = new Set<string>();
    contacts.forEach((c) => {
      if (c.tags) {
        c.tags.split(',').forEach((tag) => {
          const trimmed = tag.trim();
          if (trimmed) tagSet.add(trimmed);
        });
      }
    });
    return Array.from(tagSet).sort();
  }, [contacts]);

  // Filter by tag client-side if tag filter is active
  const filteredContacts = useMemo(() => {
    if (!tagFilter) return contacts;
    return contacts.filter((c) => {
      if (!c.tags) return false;
      return c.tags.split(',').map((t) => t.trim()).includes(tagFilter);
    });
  }, [contacts, tagFilter]);

  // Handle folder selection
  const handleSelectFilter = useCallback((filter: ContactFilter) => {
    setSelectedFilter(filter);
    setPage(1);
    setSelectedContactId(null);
    setActiveView('list');
  }, []);

  // Handle contact selection
  const handleSelectContact = useCallback((contact: UnifiedContact) => {
    setSelectedContactId(contact.id);
    setActiveView('detail');
  }, []);

  // Handle sort change
  const handleSortChange = useCallback((newSortBy: string, newSortOrder: 'asc' | 'desc') => {
    setSortBy(newSortBy);
    setSortOrder(newSortOrder);
    setPage(1);
  }, []);

  // Handle search
  const handleSearch = useCallback((query: string) => {
    setSearch(query);
    setPage(1);
  }, []);

  // Handle create
  const handleCreate = useCallback(() => {
    setEditingContact(null);
    setEditModalOpen(true);
  }, []);

  // Handle edit
  const handleEdit = useCallback(() => {
    if (selectedContact) {
      setEditingContact(selectedContact);
      setEditModalOpen(true);
    }
  }, [selectedContact]);

  // Handle delete (from detail)
  const handleDeleted = useCallback(() => {
    setSelectedContactId(null);
    setActiveView('list');
  }, []);

  // Handle edit modal saved
  const handleSaved = useCallback((id: string) => {
    setSelectedContactId(id);
    setActiveView('detail');
  }, []);

  // Register toolbar items
  const registerItems = usePluginToolbarStore((s) => s.registerItems);
  const unregisterPlugin = usePluginToolbarStore((s) => s.unregisterPlugin);

  useEffect(() => {
    const items = [
      {
        id: 'search',
        plugin: 'contacts',
        label: t('common.search'),
        type: 'search' as const,
        group: 'search',
        searchPlaceholder: t('contacts.searchPlaceholder'),
        onSearch: handleSearch,
        onClick: () => {},
      },
      {
        id: 'new',
        plugin: 'contacts',
        label: t('contacts.create'),
        group: 'actions',
        icon: (
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
          </svg>
        ),
        onClick: handleCreate,
      },
    ];
    registerItems('contacts', items);
    return () => unregisterPlugin('contacts');
  }, [handleSearch, handleCreate, t, registerItems, unregisterPlugin]);

  // Sort options
  const sortOptions = [
    { value: 'displayname', label: t('contacts.fullName') },
    { value: 'name', label: t('contacts.name') },
    { value: 'email_1', label: t('contacts.email') },
    { value: 'mailing_city', label: t('address.city') },
    { value: 'code', label: t('contacts.code') },
  ];

  const viewModeOptions = [
    { value: 'list', label: t('contacts.viewList') },
    { value: 'table', label: t('contacts.viewTable') },
    { value: 'cards', label: t('contacts.viewCards') },
  ];

  return (
    <div className="flex flex-col h-full" data-testid="contacts-list-page">
      {/* Error display */}
      {/* (errors handled by react-query + toast) */}

      {/* Desktop: three-pane layout with resizable panels */}
      <div className="hidden md:flex flex-1 overflow-hidden">
        {/* Left: Folder tree — resizable */}
        <ResizablePanel
          initialWidth={240}
          minWidth={150}
          maxWidth={400}
          className="border-r border-secondary-200 bg-white"
          data-testid="contact-folder-pane"
        >
          <div className="p-3">
            <ContactFolderTree
              selectedFilter={selectedFilter}
              onSelect={handleSelectFilter}
              tags={allTags}
            />
          </div>
        </ResizablePanel>

        {/* Middle: Contact list — resizable */}
        <ResizablePanel
          initialWidth={400}
          minWidth={250}
          maxWidth={600}
          className="border-r border-secondary-200 bg-white"
          data-testid="contact-list-pane"
        >
          {/* Toolbar */}
          <div className="flex items-center gap-2 px-3 py-2 border-b border-secondary-200 bg-white flex-shrink-0">
            <Input
              type="search"
              value={search}
              onChange={(e) => handleSearch(e.target.value)}
              placeholder={t('contacts.searchPlaceholder')}
              aria-label={t('common.search')}
              className="flex-1"
            />
            <Select
              value={viewMode}
              onChange={(e) => setViewMode(e.target.value as ContactViewMode)}
              options={viewModeOptions}
              aria-label={t('contacts.viewMode')}
              className="w-auto"
            />
            <Select
              value={sortBy}
              onChange={(e) => { setSortBy(e.target.value); setPage(1); }}
              options={sortOptions}
              aria-label={t('common.filter')}
              className="w-auto"
            />
            <Button size="sm" onClick={handleCreate} data-testid="contacts-new-btn">
              {t('contacts.create')}
            </Button>
          </div>

          {/* List */}
          <div className="flex-1 min-h-0">
            <ContactList
              contacts={filteredContacts}
              selectedContactId={selectedContactId}
              onSelectContact={handleSelectContact}
              loading={isLoading}
              currentPage={page}
              total={total}
              pageSize={PAGE_SIZE}
              onPageChange={setPage}
              viewMode={viewMode}
              sortBy={sortBy}
              sortOrder={sortOrder}
              onSortChange={handleSortChange}
            />
          </div>
        </ResizablePanel>

        {/* Right: Detail panel — flex-1, not resizable */}
        <ResizablePanel
          resizable={false}
          className="bg-white"
          data-testid="contact-detail-pane"
        >
          <ContactDetail
            contact={selectedContact ?? null}
            loading={loadingDetail}
            onEdit={handleEdit}
            onDeleted={handleDeleted}
          />
        </ResizablePanel>
      </div>

      {/* Mobile: single-pane view switching */}
      <div className="flex md:hidden flex-1 overflow-hidden flex-col">
        {/* View 1: Folder tree */}
        {activeView === 'folders' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-folder-pane">
            <div className="p-3">
              <ContactFolderTree
                selectedFilter={selectedFilter}
                onSelect={handleSelectFilter}
                tags={allTags}
              />
            </div>
          </div>
        )}

        {/* View 2: Contact list */}
        {activeView === 'list' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-list-pane">
            <div className="flex items-center gap-2 px-3 py-2 border-b border-secondary-200 sticky top-0 bg-white z-10">
              <button
                onClick={() => setActiveView('folders')}
                className="inline-flex items-center gap-1 px-2 py-1 rounded text-sm text-secondary-700 hover:bg-secondary-100 min-h-touch"
                aria-label={t('common.back')}
                data-testid="mobile-back-to-folders"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                <span className="text-sm font-medium">{t('contacts.allContacts')}</span>
              </button>
            </div>
            <div className="px-3 py-2 border-b border-secondary-200">
              <Input
                type="search"
                value={search}
                onChange={(e) => handleSearch(e.target.value)}
                placeholder={t('contacts.searchPlaceholder')}
                aria-label={t('common.search')}
              />
            </div>
            <ContactList
              contacts={filteredContacts}
              selectedContactId={selectedContactId}
              onSelectContact={handleSelectContact}
              loading={isLoading}
              currentPage={page}
              total={total}
              pageSize={PAGE_SIZE}
              onPageChange={setPage}
              viewMode={viewMode}
              sortBy={sortBy}
              sortOrder={sortOrder}
              onSortChange={handleSortChange}
            />
          </div>
        )}

        {/* View 3: Contact detail */}
        {activeView === 'detail' && (
          <div className="flex-1 overflow-y-auto bg-white" data-testid="mobile-detail-pane">
            <div className="flex items-center gap-2 px-3 py-2 border-b border-secondary-200 sticky top-0 bg-white z-10">
              <button
                onClick={() => setActiveView('list')}
                className="inline-flex items-center gap-1 px-2 py-1 rounded text-sm text-secondary-700 hover:bg-secondary-100 min-h-touch"
                aria-label={t('common.back')}
                data-testid="mobile-back-to-list"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                <span className="text-sm font-medium">{t('common.back')}</span>
              </button>
            </div>
            <ContactDetail
              contact={selectedContact ?? null}
              loading={loadingDetail}
              onEdit={handleEdit}
              onDeleted={handleDeleted}
            />
          </div>
        )}
      </div>

      {/* Edit/Create Modal */}
      <ContactEditModal
        open={editModalOpen}
        onClose={() => setEditModalOpen(false)}
        contact={editingContact}
        onSaved={handleSaved}
      />
    </div>
  );
}
