/**
 * 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 clsx from 'clsx';
import { ResizablePanel } from '@/components/ui/ResizablePanel';
import { Input } from '@/components/ui/Input';
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 { SavedFilters } from '@/components/SavedFilters';
import { ArrowDownAZ, ArrowUpZA, ChevronLeft, LayoutGrid, List, Plus } from 'lucide-react';
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 folder filter
  const folderId = useMemo(() => {
    if (selectedFilter.startsWith('folder:')) return selectedFilter.slice(7);
    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,
    folderId,
  );

  // 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: (
          <Plus className="w-3.5 h-3.5" strokeWidth={2} />
        ),
        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}
              contacts={contacts}
            />
          </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 — minimal: sort toggle + view toggle + new */}
          <div className="flex items-center gap-1 px-3 py-1.5 border-b border-secondary-200 bg-white flex-shrink-0">
            {/* Sort */}
            <div className="flex items-center gap-1">
              <select
                value={sortBy}
                onChange={(e) => { setSortBy(e.target.value); setPage(1); }}
                className="text-xs border border-secondary-300 rounded-md px-2 py-1 bg-white text-secondary-700 focus:outline-none focus:ring-1 focus:ring-primary-500"
                aria-label={t('common.sort')}
              >
                {sortOptions.map((opt) => (
                  <option key={opt.value} value={opt.value}>{opt.label}</option>
                ))}
              </select>
              <button
                onClick={() => handleSortChange(sortBy, sortOrder === 'asc' ? 'desc' : 'asc')}
                className="p-1.5 rounded-md hover:bg-secondary-100 min-h-touch min-w-touch flex items-center justify-center"
                aria-label={sortOrder === 'asc' ? t('common.sortDesc') : t('common.sortAsc')}
                title={sortOrder === 'asc' ? 'Absteigend' : 'Aufsteigend'}
              >
                {sortOrder === 'asc' ? <ArrowDownAZ className="w-3.5 h-3.5 text-secondary-600" aria-hidden="true" strokeWidth={2} /> : <ArrowUpZA className="w-3.5 h-3.5 text-secondary-600" aria-hidden="true" strokeWidth={2} />}
              </button>
            </div>

            <div className="flex-1" />

            {/* Type filter toggle */}
            <div className="flex items-center gap-0.5 bg-secondary-100 rounded-md p-0.5 mr-1">
              {[
                { value: 'all' as ContactFilter, label: t('common.all') },
                { value: 'company' as ContactFilter, label: t('contacts.companies') },
                { value: 'person' as ContactFilter, label: t('contacts.persons') },
              ].map((opt) => (
                <button
                  key={opt.value}
                  onClick={() => handleSelectFilter(opt.value)}
                  className={clsx(
                    'px-2 py-1 rounded text-xs font-medium transition-colors min-h-touch',
                    selectedFilter === opt.value
                      ? 'bg-white text-primary-600 shadow-sm'
                      : 'text-secondary-500 hover:text-secondary-700',
                  )}
                  aria-label={opt.label}
                  aria-pressed={selectedFilter === opt.value}
                >
                  {opt.label}
                </button>
              ))}
            </div>

            {/* View mode toggle */}
            <div className="flex items-center gap-0.5 bg-secondary-100 rounded-md p-0.5">
              {viewModeOptions.map((opt) => (
                <button
                  key={opt.value}
                  onClick={() => setViewMode(opt.value as ContactViewMode)}
                  className={clsx(
                    'px-2 py-1 rounded text-xs font-medium transition-colors min-h-touch',
                    viewMode === opt.value
                      ? 'bg-white text-primary-600 shadow-sm'
                      : 'text-secondary-500 hover:text-secondary-700',
                  )}
                  aria-label={opt.label}
                  aria-pressed={viewMode === opt.value}
                >
                  {opt.value === 'list' && (
                    <List className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
                  )}
                  {opt.value === 'table' && (
                    <LayoutGrid className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
                  )}
                  {opt.value === 'cards' && (
                    <LayoutGrid className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
                  )}
                </button>
              ))}
            </div>

            {/* New contact */}
            <button
              onClick={handleCreate}
              className="p-1.5 rounded-md hover:bg-secondary-100 min-h-touch min-w-touch flex items-center justify-center"
              aria-label={t('contacts.create')}
              title={t('contacts.create')}
              data-testid="contacts-new-btn"
            >
              <Plus className="w-4 h-4 text-primary-600" aria-hidden="true" strokeWidth={2} />
            </button>
          </div>

          {/* Saved Filters */}
          <div className="px-3 py-1.5 border-b border-secondary-200 bg-secondary-50 flex-shrink-0">
            <SavedFilters
              entityType="contacts"
              currentCriteria={{ search: debouncedSearch, type: contactType, sortBy, sortOrder, folderId }}
              onLoadFilter={(criteria) => {
                if (criteria.search) setSearch(criteria.search); else setSearch('');
                if (criteria.sortBy) setSortBy(criteria.sortBy);
                if (criteria.sortOrder) setSortOrder(criteria.sortOrder);
                if (criteria.type) setSelectedFilter(criteria.type as ContactFilter);
                setPage(1);
              }}
            />
          </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}
                contacts={contacts}
              />
            </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"
              >
                <ChevronLeft className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
                <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"
              >
                <ChevronLeft className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
                <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>
  );
}
