import { useState, useMemo } from 'react';
import {
  Plus,
  RefreshCw,
  Search,
  Filter,
  List,
} from 'lucide-react';
import { Button } from '@components/atoms/Button';
import { Breadcrumbs } from '@components/organisms/Breadcrumbs';
import { DateRangePicker, type DateRange } from '@components/organisms/DatePicker';
import { Select, type SelectOption } from '@components/organisms/Select';
import { useToast } from '@components/organisms/Toast';
import { KanbanColumn, type StageKey } from '@components/crm/KanbanColumn';
import type { KanbanOpportunity } from '@components/crm/KanbanCard';
import { formatNumber } from '@utils/formatters';
import { Link } from 'react-router-dom';

// Stage labels for display
const stageLabels: Record<StageKey, string> = {
  new: 'Nuevo',
  qualified: 'Calificado',
  proposition: 'Propuesta',
  won: 'Ganado',
  lost: 'Perdido',
};

// Mock users for filter
const mockUsers: SelectOption[] = [
  { value: 'user-1', label: 'Juan Garcia' },
  { value: 'user-2', label: 'Maria Lopez' },
  { value: 'user-3', label: 'Carlos Rodriguez' },
  { value: 'user-4', label: 'Ana Martinez' },
];

// Mock data for opportunities
const generateMockOpportunities = (): Record<StageKey, KanbanOpportunity[]> => ({
  new: [
    {
      id: '1',
      name: 'Proyecto ERP para Constructora ABC',
      expectedRevenue: 150000,
      expectedCloseDate: '2026-02-15',
      assignedTo: { id: 'user-1', name: 'Juan Garcia' },
      probability: 20,
      partnerName: 'Constructora ABC S.A.',
    },
    {
      id: '2',
      name: 'Sistema de Inventarios - Retail Plus',
      expectedRevenue: 75000,
      expectedCloseDate: '2026-02-28',
      assignedTo: { id: 'user-2', name: 'Maria Lopez' },
      probability: 15,
      partnerName: 'Retail Plus',
    },
    {
      id: '3',
      name: 'Integracion CRM - TechCorp',
      expectedRevenue: 45000,
      probability: 10,
      partnerName: 'TechCorp Internacional',
    },
  ],
  qualified: [
    {
      id: '4',
      name: 'Modulo de Facturacion Electronica',
      expectedRevenue: 85000,
      expectedCloseDate: '2026-02-10',
      assignedTo: { id: 'user-1', name: 'Juan Garcia' },
      probability: 40,
      partnerName: 'Distribuidora Nacional',
    },
    {
      id: '5',
      name: 'Dashboard Ejecutivo - Financiera',
      expectedRevenue: 120000,
      expectedCloseDate: '2026-03-01',
      assignedTo: { id: 'user-3', name: 'Carlos Rodriguez' },
      probability: 50,
      partnerName: 'Financiera del Norte',
    },
  ],
  proposition: [
    {
      id: '6',
      name: 'Sistema de Gestion de Proyectos',
      expectedRevenue: 200000,
      expectedCloseDate: '2026-01-30',
      assignedTo: { id: 'user-2', name: 'Maria Lopez' },
      probability: 65,
      partnerName: 'Consultoria Global',
    },
    {
      id: '7',
      name: 'Automatizacion de Procesos - Manufactura',
      expectedRevenue: 180000,
      expectedCloseDate: '2026-02-05',
      assignedTo: { id: 'user-4', name: 'Ana Martinez' },
      probability: 70,
      partnerName: 'Manufactura Industrial',
    },
    {
      id: '8',
      name: 'Portal de Clientes Web',
      expectedRevenue: 95000,
      expectedCloseDate: '2026-02-20',
      assignedTo: { id: 'user-1', name: 'Juan Garcia' },
      probability: 60,
      partnerName: 'Servicios Express',
    },
  ],
  won: [
    {
      id: '9',
      name: 'Implementacion ERP Completo',
      expectedRevenue: 350000,
      expectedCloseDate: '2026-01-15',
      assignedTo: { id: 'user-3', name: 'Carlos Rodriguez' },
      probability: 100,
      partnerName: 'Grupo Industrial MX',
    },
    {
      id: '10',
      name: 'Modulo de Recursos Humanos',
      expectedRevenue: 65000,
      expectedCloseDate: '2026-01-10',
      assignedTo: { id: 'user-2', name: 'Maria Lopez' },
      probability: 100,
      partnerName: 'Corporativo Sur',
    },
  ],
  lost: [
    {
      id: '11',
      name: 'Migracion de Sistema Legacy',
      expectedRevenue: 125000,
      expectedCloseDate: '2026-01-05',
      assignedTo: { id: 'user-4', name: 'Ana Martinez' },
      probability: 0,
      partnerName: 'Empresa Tradicional',
    },
  ],
});

const formatCurrency = (value: number): string => {
  return formatNumber(value, 'es-MX', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
};

export function PipelineKanbanPage() {
  const { success } = useToast();

  // State for filters
  const [searchTerm, setSearchTerm] = useState('');
  const [dateRange, setDateRange] = useState<DateRange>({ start: null, end: null });
  const [selectedUser, setSelectedUser] = useState<string>('');
  const [showFilters, setShowFilters] = useState(false);

  // State for opportunities by stage
  const [opportunitiesByStage, setOpportunitiesByStage] = useState<Record<StageKey, KanbanOpportunity[]>>(
    generateMockOpportunities
  );

  // Filter opportunities based on search and filters
  const filteredOpportunities = useMemo(() => {
    const result: Record<StageKey, KanbanOpportunity[]> = {
      new: [],
      qualified: [],
      proposition: [],
      won: [],
      lost: [],
    };

    (Object.keys(opportunitiesByStage) as StageKey[]).forEach((stage) => {
      result[stage] = opportunitiesByStage[stage].filter((opp) => {
        // Search filter
        if (searchTerm) {
          const searchLower = searchTerm.toLowerCase();
          if (
            !opp.name.toLowerCase().includes(searchLower) &&
            !opp.partnerName?.toLowerCase().includes(searchLower)
          ) {
            return false;
          }
        }

        // User filter
        if (selectedUser && opp.assignedTo?.id !== selectedUser) {
          return false;
        }

        // Date range filter
        if (dateRange.start && dateRange.end && opp.expectedCloseDate) {
          const closeDate = new Date(opp.expectedCloseDate);
          if (closeDate < dateRange.start || closeDate > dateRange.end) {
            return false;
          }
        }

        return true;
      });
    });

    return result;
  }, [opportunitiesByStage, searchTerm, selectedUser, dateRange]);

  // Calculate totals
  const totals = useMemo(() => {
    const allOpps = Object.values(filteredOpportunities).flat();
    const openOpps = [...filteredOpportunities.new, ...filteredOpportunities.qualified, ...filteredOpportunities.proposition];

    return {
      totalOpportunities: allOpps.length,
      totalValue: allOpps.reduce((sum, o) => sum + o.expectedRevenue, 0),
      openValue: openOpps.reduce((sum, o) => sum + o.expectedRevenue, 0),
      weightedValue: openOpps.reduce((sum, o) => sum + (o.expectedRevenue * o.probability / 100), 0),
      wonValue: filteredOpportunities.won.reduce((sum, o) => sum + o.expectedRevenue, 0),
    };
  }, [filteredOpportunities]);

  // Handle card drop (stage change)
  const handleDrop = (opportunity: KanbanOpportunity, targetStage: StageKey) => {
    // Find current stage
    let currentStage: StageKey | null = null;
    for (const [stage, items] of Object.entries(opportunitiesByStage)) {
      if (items.some((item) => item.id === opportunity.id)) {
        currentStage = stage as StageKey;
        break;
      }
    }

    if (!currentStage || currentStage === targetStage) return;

    // Update state
    setOpportunitiesByStage((prev) => {
      const newState = { ...prev };

      // Remove from current stage
      newState[currentStage!] = prev[currentStage!].filter((item) => item.id !== opportunity.id);

      // Update probability based on stage
      const updatedOpp = { ...opportunity };
      if (targetStage === 'won') {
        updatedOpp.probability = 100;
      } else if (targetStage === 'lost') {
        updatedOpp.probability = 0;
      }

      // Add to target stage
      newState[targetStage] = [...prev[targetStage], updatedOpp];

      return newState;
    });

    // Show toast notification
    success(
      'Etapa actualizada',
      `"${opportunity.name}" movida a ${stageLabels[targetStage]}`
    );
  };

  // Handle card click
  const handleCardClick = (opportunity: KanbanOpportunity) => {
    console.log('Card clicked:', opportunity);
    // Here you could navigate to opportunity detail or open a modal
  };

  // Refresh data
  const handleRefresh = () => {
    setOpportunitiesByStage(generateMockOpportunities());
    success('Datos actualizados', 'El pipeline ha sido actualizado');
  };

  // Clear filters
  const handleClearFilters = () => {
    setSearchTerm('');
    setDateRange({ start: null, end: null });
    setSelectedUser('');
  };

  const hasActiveFilters = searchTerm || selectedUser || dateRange.start;

  return (
    <div className="flex flex-col h-full">
      {/* Header */}
      <div className="flex-shrink-0 space-y-4 p-6 pb-0">
        <Breadcrumbs
          items={[
            { label: 'CRM', href: '/crm' },
            { label: 'Pipeline' },
          ]}
        />

        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold text-gray-900">Pipeline de Ventas</h1>
            <p className="text-sm text-gray-500">
              Gestiona oportunidades arrastrando tarjetas entre etapas
            </p>
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={handleRefresh}>
              <RefreshCw className="mr-2 h-4 w-4" />
              Actualizar
            </Button>
            <Link to="/crm/opportunities">
              <Button variant="outline">
                <List className="mr-2 h-4 w-4" />
                Vista Lista
              </Button>
            </Link>
            <Button>
              <Plus className="mr-2 h-4 w-4" />
              Nueva oportunidad
            </Button>
          </div>
        </div>

        {/* Summary Stats */}
        <div className="grid grid-cols-2 gap-4 sm:grid-cols-5">
          <div className="rounded-lg border bg-white p-3">
            <div className="text-sm text-gray-500">Oportunidades</div>
            <div className="text-xl font-bold text-gray-900">{totals.totalOpportunities}</div>
          </div>
          <div className="rounded-lg border bg-white p-3">
            <div className="text-sm text-gray-500">Pipeline Total</div>
            <div className="text-xl font-bold text-blue-600">${formatCurrency(totals.openValue)}</div>
          </div>
          <div className="rounded-lg border bg-white p-3">
            <div className="text-sm text-gray-500">Ponderado</div>
            <div className="text-xl font-bold text-amber-600">${formatCurrency(totals.weightedValue)}</div>
          </div>
          <div className="rounded-lg border bg-white p-3">
            <div className="text-sm text-gray-500">Ganado</div>
            <div className="text-xl font-bold text-green-600">${formatCurrency(totals.wonValue)}</div>
          </div>
          <div className="rounded-lg border bg-white p-3">
            <div className="text-sm text-gray-500">Valor Total</div>
            <div className="text-xl font-bold text-gray-900">${formatCurrency(totals.totalValue)}</div>
          </div>
        </div>

        {/* Filters */}
        <div className="rounded-lg border bg-white p-4">
          <div className="flex flex-wrap items-center gap-4">
            {/* Search */}
            <div className="relative flex-1 min-w-[200px] max-w-md">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
              <input
                type="text"
                placeholder="Buscar oportunidades..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className="w-full rounded-md border border-gray-300 py-2 pl-10 pr-4 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
              />
            </div>

            {/* Toggle Filters */}
            <Button
              variant={showFilters ? 'secondary' : 'outline'}
              size="sm"
              onClick={() => setShowFilters(!showFilters)}
            >
              <Filter className="mr-2 h-4 w-4" />
              Filtros
              {hasActiveFilters && (
                <span className="ml-2 rounded-full bg-primary-600 px-1.5 py-0.5 text-xs text-white">
                  {[searchTerm, selectedUser, dateRange.start].filter(Boolean).length}
                </span>
              )}
            </Button>

            {hasActiveFilters && (
              <Button variant="ghost" size="sm" onClick={handleClearFilters}>
                Limpiar filtros
              </Button>
            )}
          </div>

          {/* Expanded Filters */}
          {showFilters && (
            <div className="mt-4 flex flex-wrap items-end gap-4 border-t pt-4">
              <div className="min-w-[200px]">
                <label className="mb-1.5 block text-sm font-medium text-gray-700">
                  Responsable
                </label>
                <Select
                  options={mockUsers}
                  value={selectedUser}
                  onChange={(v) => setSelectedUser(v as string)}
                  placeholder="Todos los usuarios"
                  clearable
                />
              </div>
              <div className="min-w-[280px]">
                <label className="mb-1.5 block text-sm font-medium text-gray-700">
                  Fecha de cierre esperada
                </label>
                <DateRangePicker
                  value={dateRange}
                  onChange={setDateRange}
                  placeholder="Seleccionar rango"
                />
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Kanban Board */}
      <div className="flex-1 overflow-x-auto p-6">
        <div className="flex gap-4 min-w-max">
          {(Object.keys(stageLabels) as StageKey[]).map((stage) => (
            <KanbanColumn
              key={stage}
              title={stageLabels[stage]}
              stage={stage}
              items={filteredOpportunities[stage]}
              onDrop={handleDrop}
              onCardClick={handleCardClick}
            />
          ))}
        </div>
      </div>
    </div>
  );
}

export default PipelineKanbanPage;
