import { useEffect, useState, useMemo, useCallback } from 'react';
import { Link, useLocation, useSearchParams } from 'react-router-dom';
import { useClientsStore } from '@/stores/clients';
import type { ClientCreate } from '@/types';
import { Search, Plus, Users, X, Upload, LayoutGrid, Kanban, ChevronLeft, ChevronRight } from 'lucide-react';
import { cn, getRelativeTime, getInitials } from '@/lib/utils';
import Badge, { StageBadge } from '@/components/Badge';
import EmptyState from '@/components/EmptyState';
import { PageLoader } from '@/components/LoadingSpinner';
import Modal from '@/components/Modal';
import ClientForm from '@/components/ClientForm';
import CSVImportModal from '@/components/CSVImportModal';

const PAGE_SIZES = [25, 50, 100];

export default function ClientsPage() {
  const location = useLocation();
  const [searchParams, setSearchParams] = useSearchParams();
  const { clients, isLoading, searchQuery, selectedTag, setSearchQuery, setSelectedTag, fetchClients, createClient } = useClientsStore();
  const [showCreate, setShowCreate] = useState(false);
  const [showImport, setShowImport] = useState(false);
  const [creating, setCreating] = useState(false);
  const [viewMode, setViewMode] = useState<'grid' | 'pipeline'>(() => 
    (localStorage.getItem('clients-view') as 'grid' | 'pipeline') || 'grid'
  );

  // Pagination state from URL
  const currentPage = parseInt(searchParams.get('page') || '1', 10) || 1;
  const pageSize = parseInt(searchParams.get('pageSize') || '50', 10) || 50;

  const setPage = useCallback((page: number) => {
    const params = new URLSearchParams(searchParams);
    params.set('page', String(page));
    setSearchParams(params, { replace: true });
  }, [searchParams, setSearchParams]);

  const setPageSize = useCallback((size: number) => {
    const params = new URLSearchParams(searchParams);
    params.set('pageSize', String(size));
    params.set('page', '1'); // reset to first page
    setSearchParams(params, { replace: true });
  }, [searchParams, setSearchParams]);

  // Initialize selected tag from URL
  useEffect(() => {
    const urlTag = searchParams.get('tag');
    if (urlTag && urlTag !== selectedTag) {
      setSelectedTag(urlTag);
    }
  }, []);

  useEffect(() => {
    fetchClients();
  }, [fetchClients]);

  useEffect(() => {
    if (location.state?.openCreate) {
      setShowCreate(true);
      window.history.replaceState({}, '');
    }
  }, [location.state]);

  // Client-side filtering for immediate feedback
  const filteredClients = useMemo(() => {
    let result = clients;
    if (searchQuery) {
      const q = searchQuery.toLowerCase();
      result = result.filter(
        (c) =>
          `${c.firstName} ${c.lastName}`.toLowerCase().includes(q) ||
          c.email?.toLowerCase().includes(q) ||
          c.company?.toLowerCase().includes(q)
      );
    }
    if (selectedTag) {
      result = result.filter((c) => c.tags?.includes(selectedTag));
    }
    return result;
  }, [clients, searchQuery, selectedTag]);

  // Pagination for grid view
  const totalClients = filteredClients.length;
  const totalPages = Math.ceil(totalClients / pageSize);
  const paginatedClients = useMemo(() => {
    if (viewMode === 'pipeline') return filteredClients; // pipeline shows all
    const start = (currentPage - 1) * pageSize;
    return filteredClients.slice(start, start + pageSize);
  }, [filteredClients, currentPage, pageSize, viewMode]);

  // Reset page when filters change
  useEffect(() => {
    if (currentPage > 1) {
      setPage(1);
    }
  }, [searchQuery, selectedTag]);

  // Pipeline columns
  const pipelineStages = ['lead', 'prospect', 'onboarding', 'active', 'inactive'] as const;
  const pipelineColumns = useMemo(() => {
    const cols: Record<string, typeof filteredClients> = {};
    pipelineStages.forEach(s => { cols[s] = []; });
    filteredClients.forEach(c => {
      const stage = c.stage || 'lead';
      if (cols[stage]) cols[stage].push(c);
    });
    return cols;
  }, [filteredClients]);

  const stageCounts = useMemo(() => {
    const counts: Record<string, number> = {};
    clients.forEach(c => {
      const s = c.stage || 'lead';
      counts[s] = (counts[s] || 0) + 1;
    });
    return counts;
  }, [clients]);

  // All unique tags
  const allTags = useMemo(() => {
    const tags = new Set<string>();
    clients.forEach((c) => c.tags?.forEach((t) => tags.add(t)));
    return Array.from(tags).sort();
  }, [clients]);

  const handleCreate = async (data: ClientCreate) => {
    setCreating(true);
    try {
      await createClient(data);
      setShowCreate(false);
    } catch (err) {
      console.error(err);
    } finally {
      setCreating(false);
    }
  };

  if (isLoading && clients.length === 0) return <PageLoader />;

  return (
    <div className="max-w-6xl mx-auto space-y-5 animate-fade-in">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">
            Clients{clients.length > 0 && <span className="text-slate-400 dark:text-slate-500 ml-2 text-lg font-normal">({clients.length})</span>}
          </h1>
          <p className="text-slate-500 dark:text-slate-400 text-sm mt-1">{clients.length} contacts in your network</p>
        </div>
        <div className="flex items-center gap-2">
          <div className="flex items-center bg-slate-100 dark:bg-slate-800 rounded-lg p-0.5">
            <button
              onClick={() => { setViewMode('grid'); localStorage.setItem('clients-view', 'grid'); }}
              className={cn(
                'p-1.5 rounded-md transition-colors',
                viewMode === 'grid' ? 'bg-white dark:bg-slate-700 shadow-sm text-slate-900 dark:text-slate-100' : 'text-slate-400 hover:text-slate-600 dark:hover:text-slate-300'
              )}
              title="Grid view"
            >
              <LayoutGrid className="w-4 h-4" />
            </button>
            <button
              onClick={() => { setViewMode('pipeline'); localStorage.setItem('clients-view', 'pipeline'); }}
              className={cn(
                'p-1.5 rounded-md transition-colors',
                viewMode === 'pipeline' ? 'bg-white dark:bg-slate-700 shadow-sm text-slate-900 dark:text-slate-100' : 'text-slate-400 hover:text-slate-600 dark:hover:text-slate-300'
              )}
              title="Pipeline view"
            >
              <Kanban className="w-4 h-4" />
            </button>
          </div>
          <button
            onClick={() => setShowImport(true)}
            className="flex items-center gap-2 px-4 py-2 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 rounded-lg text-sm font-medium hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors"
          >
            <Upload className="w-4 h-4" />
            Import CSV
          </button>
          <button
            onClick={() => setShowCreate(true)}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 transition-colors"
          >
            <Plus className="w-4 h-4" />
            Add Client
          </button>
        </div>
      </div>

      {/* Search + Tags */}
      <div className="space-y-3">
        <div className="relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="Search clients..."
            className="w-full pl-10 pr-4 py-2.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg text-sm text-slate-900 dark:text-slate-100 placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
          />
          {searchQuery && (
            <button onClick={() => setSearchQuery('')} className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600">
              <X className="w-4 h-4" />
            </button>
          )}
        </div>

        {allTags.length > 0 && (
          <div className="flex flex-wrap gap-2">
            {allTags.map((tag) => (
              <Badge
                key={tag}
                color="blue"
                active={selectedTag === tag}
                onClick={() => setSelectedTag(selectedTag === tag ? null : tag)}
              >
                {tag}
              </Badge>
            ))}
            {selectedTag && (
              <button onClick={() => setSelectedTag(null)} className="text-xs text-slate-500 hover:text-slate-700 ml-1">
                Clear filter
              </button>
            )}
          </div>
        )}
      </div>

      {/* Pipeline Summary Bar */}
      {viewMode === 'grid' && clients.length > 0 && (
        <div className="flex items-center gap-1 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl p-3 overflow-x-auto">
          {pipelineStages.map((stage) => {
            const count = stageCounts[stage] || 0;
            const total = clients.length;
            const pct = total > 0 ? Math.max((count / total) * 100, count > 0 ? 4 : 0) : 0;
            const colors: Record<string, string> = {
              lead: 'bg-slate-300 dark:bg-slate-600',
              prospect: 'bg-blue-400 dark:bg-blue-500',
              onboarding: 'bg-amber-400 dark:bg-amber-500',
              active: 'bg-emerald-400 dark:bg-emerald-500',
              inactive: 'bg-red-400 dark:bg-red-500',
            };
            return (
              <div key={stage} className="flex-1 min-w-[60px]" title={`${stage}: ${count}`}>
                <div className="text-center mb-1">
                  <span className="text-xs font-medium text-slate-600 dark:text-slate-300 capitalize">{stage}</span>
                  <span className="text-xs text-slate-400 ml-1">({count})</span>
                </div>
                <div className="h-2 bg-slate-100 dark:bg-slate-700 rounded-full overflow-hidden">
                  <div className={cn('h-full rounded-full transition-all', colors[stage])} style={{ width: `${pct}%` }} />
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* Client Grid / Pipeline View */}
      {filteredClients.length === 0 ? (
        <EmptyState
          icon={Users}
          title={searchQuery || selectedTag ? 'No matches found' : 'No clients yet'}
          description={searchQuery || selectedTag ? 'Try adjusting your search or filters' : 'Add your first client to get started'}
          action={!searchQuery && !selectedTag ? { label: 'Add Client', onClick: () => setShowCreate(true) } : undefined}
        />
      ) : viewMode === 'pipeline' ? (
        /* Pipeline / Kanban View */
        <div className="flex gap-4 overflow-x-auto pb-4">
          {pipelineStages.map((stage) => {
            const stageClients = pipelineColumns[stage] || [];
            const headerColors: Record<string, string> = {
              lead: 'border-t-slate-400',
              prospect: 'border-t-blue-500',
              onboarding: 'border-t-amber-500',
              active: 'border-t-emerald-500',
              inactive: 'border-t-red-500',
            };
            return (
              <div key={stage} className={cn(
                'flex-1 min-w-[220px] max-w-[300px] bg-slate-50 dark:bg-slate-800/50 rounded-xl border-t-4',
                headerColors[stage]
              )}>
                <div className="px-3 py-3 flex items-center justify-between">
                  <h3 className="text-sm font-semibold text-slate-700 dark:text-slate-200 capitalize">{stage}</h3>
                  <span className="text-xs bg-white dark:bg-slate-700 text-slate-500 dark:text-slate-400 px-2 py-0.5 rounded-full font-medium">{stageClients.length}</span>
                </div>
                <div className="px-2 pb-2 space-y-2 max-h-[600px] overflow-y-auto">
                  {stageClients.map((client) => (
                    <Link
                      key={client.id}
                      to={`/clients/${client.id}`}
                      className="block bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg p-3 hover:shadow-md dark:hover:shadow-slate-900/50 transition-all"
                    >
                      <div className="flex items-center gap-2">
                        <div className="w-8 h-8 bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
                          {getInitials(client.firstName, client.lastName)}
                        </div>
                        <div className="flex-1 min-w-0">
                          <p className="text-sm font-medium text-slate-900 dark:text-slate-100 truncate">
                            {client.firstName} {client.lastName}
                          </p>
                          {client.company && (
                            <p className="text-xs text-slate-500 dark:text-slate-400 truncate">{client.company}</p>
                          )}
                        </div>
                      </div>
                      {client.tags && client.tags.length > 0 && (
                        <div className="flex flex-wrap gap-1 mt-2">
                          {client.tags.slice(0, 2).map(tag => (
                            <span key={tag} className="px-1.5 py-0.5 bg-slate-100 dark:bg-slate-700 text-slate-500 dark:text-slate-400 rounded text-[10px]">{tag}</span>
                          ))}
                        </div>
                      )}
                      <p className="text-[10px] text-slate-400 mt-2">
                        {getRelativeTime(client.lastContacted)}
                      </p>
                    </Link>
                  ))}
                  {stageClients.length === 0 && (
                    <p className="text-xs text-slate-400 text-center py-4">No clients</p>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      ) : (
        /* Grid View */
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
          {paginatedClients.map((client) => (
            <Link
              key={client.id}
              to={`/clients/${client.id}`}
              className="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl p-5 hover:shadow-md dark:hover:shadow-slate-900/50 hover:border-slate-300 dark:hover:border-slate-600 transition-all group"
            >
              <div className="flex items-start gap-3">
                <div className="w-11 h-11 bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 rounded-full flex items-center justify-center text-sm font-bold flex-shrink-0 group-hover:bg-blue-200 dark:group-hover:bg-blue-900 transition-colors">
                  {getInitials(client.firstName, client.lastName)}
                </div>
                <div className="flex-1 min-w-0">
                  <h3 className="font-semibold text-slate-900 dark:text-slate-100 truncate">
                    {client.firstName} {client.lastName}
                  </h3>
                  {client.company && (
                    <p className="text-sm text-slate-500 dark:text-slate-400 truncate">{client.role ? `${client.role} at ` : ''}{client.company}</p>
                  )}
                </div>
              </div>

              <div className="flex flex-wrap gap-1.5 mt-3">
                <StageBadge stage={client.stage} />
                {client.tags && client.tags.slice(0, 2).map((tag) => (
                  <span key={tag} className="px-2 py-0.5 bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 rounded-full text-xs">
                    {tag}
                  </span>
                ))}
                {client.tags && client.tags.length > 2 && (
                  <span className="text-xs text-slate-400">+{client.tags.length - 2}</span>
                )}
              </div>

              <div className="mt-3 pt-3 border-t border-slate-100 dark:border-slate-700 text-xs text-slate-400">
                Last contacted: {getRelativeTime(client.lastContacted)}
              </div>
            </Link>
          ))}
        </div>
      )}

      {/* Pagination Controls (grid view only) */}
      {viewMode === 'grid' && totalPages > 1 && (
        <div className="flex items-center justify-between bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl px-4 py-3">
          <div className="flex items-center gap-2 text-sm text-slate-500 dark:text-slate-400">
            <span>Show</span>
            <select
              value={pageSize}
              onChange={(e) => setPageSize(Number(e.target.value))}
              className="px-2 py-1 bg-white dark:bg-slate-700 border border-slate-300 dark:border-slate-600 rounded-lg text-sm text-slate-900 dark:text-slate-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              {PAGE_SIZES.map((size) => (
                <option key={size} value={size}>{size}</option>
              ))}
            </select>
            <span>per page</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-sm text-slate-500 dark:text-slate-400">
              Page {currentPage} of {totalPages}
            </span>
            <div className="flex items-center gap-1">
              <button
                onClick={() => setPage(currentPage - 1)}
                disabled={currentPage <= 1}
                className="p-1.5 rounded-lg border border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                <ChevronLeft className="w-4 h-4" />
              </button>
              <button
                onClick={() => setPage(currentPage + 1)}
                disabled={currentPage >= totalPages}
                className="p-1.5 rounded-lg border border-slate-200 dark:border-slate-600 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                <ChevronRight className="w-4 h-4" />
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Create Modal */}
      <Modal isOpen={showCreate} onClose={() => setShowCreate(false)} title="Add Client" size="lg">
        <ClientForm onSubmit={handleCreate} loading={creating} />
      </Modal>

      {/* Import CSV Modal */}
      <CSVImportModal
        isOpen={showImport}
        onClose={() => setShowImport(false)}
        onComplete={() => fetchClients()}
      />
    </div>
  );
}
