'use client';

import { useEffect, useState, useCallback } from 'react';
import {
  Plus,
  Trash2,
  Pencil,
  GripVertical,
  ChevronUp,
  ChevronDown,
  Loader2,
  Star,
  X,
} from 'lucide-react';
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core';
import {
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { cn } from '../utils';
import { useCrmApi } from '../context';
import type { StageData, PipelineData } from '../types';

interface PipelineManagerProps {
  entityType?: string;
}

const STAGE_COLORS = [
  '#3B82F6',
  '#8B5CF6',
  '#F59E0B',
  '#EF4444',
  '#EC4899',
  '#14B8A6',
  '#22C55E',
  '#6B7280',
  '#F97316',
  '#06B6D4',
];

const inputClass =
  'w-full px-3 py-2 border border-border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary/30 bg-background text-text';

function SortableStageRow({
  stage,
  index,
  totalCount,
  onMoveUp,
  onMoveDown,
  onEdit,
  onDelete,
}: {
  stage: StageData;
  index: number;
  totalCount: number;
  onMoveUp: () => void;
  onMoveDown: () => void;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
    id: stage.id,
  });
  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    zIndex: isDragging ? 10 : undefined,
    opacity: isDragging ? 0.5 : 1,
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        'flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-background/50 transition-colors group',
        isDragging && 'bg-background shadow-lg',
      )}
    >
      <button
        {...attributes}
        {...listeners}
        className="cursor-grab active:cursor-grabbing touch-none p-0.5 rounded hover:bg-background"
        aria-label="Перетащить"
      >
        <GripVertical className="h-4 w-4 text-muted/50 shrink-0" />
      </button>
      <span className="w-3 h-3 rounded-full shrink-0" style={{ backgroundColor: stage.color }} />
      <span className="text-sm text-text flex-1">{stage.name}</span>
      {stage.isDefault && (
        <span className="text-[10px] text-primary bg-primary/10 px-1.5 py-0.5 rounded">
          default
        </span>
      )}
      <span className="text-xs text-muted bg-background px-2 py-0.5 rounded">{stage.type}</span>
      <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
        <button
          onClick={onMoveUp}
          disabled={index === 0}
          className="p-1 rounded hover:bg-background disabled:opacity-30"
        >
          <ChevronUp className="h-3.5 w-3.5 text-muted" />
        </button>
        <button
          onClick={onMoveDown}
          disabled={index === totalCount - 1}
          className="p-1 rounded hover:bg-background disabled:opacity-30"
        >
          <ChevronDown className="h-3.5 w-3.5 text-muted" />
        </button>
        <button
          onClick={onEdit}
          className="p-1 rounded hover:bg-background text-muted hover:text-text"
        >
          <Pencil className="h-3.5 w-3.5" />
        </button>
        <button
          onClick={onDelete}
          className="p-1 rounded hover:bg-error/10 text-muted hover:text-error"
        >
          <Trash2 className="h-3.5 w-3.5" />
        </button>
      </div>
    </div>
  );
}

// --- Inline Dialog (no external Dialog dependency) ---
function InlineDialog({
  open,
  onClose,
  title,
  children,
  footer,
}: {
  open: boolean;
  onClose: () => void;
  title: string;
  children: React.ReactNode;
  footer: React.ReactNode;
}) {
  useEffect(() => {
    if (!open) return;
    const h = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', h);
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', h);
      document.body.style.overflow = '';
    };
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center"
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
    >
      <div className="fixed inset-0 bg-black/50" />
      <div className="relative z-10 bg-card rounded-2xl shadow-xl w-full max-w-lg mx-4 max-h-[90vh] overflow-y-auto">
        <div className="flex items-start justify-between p-6 pb-0">
          <h2 className="text-lg font-semibold text-text">{title}</h2>
          <button
            onClick={onClose}
            className="p-1.5 rounded-lg hover:bg-muted/20 transition-colors -mt-1 -mr-1"
          >
            <X className="h-4 w-4 text-muted" />
          </button>
        </div>
        <div className="p-6 space-y-4">{children}</div>
        <div className="flex items-center justify-end gap-3 px-6 pb-6">{footer}</div>
      </div>
    </div>
  );
}

export function PipelineManager({ entityType }: PipelineManagerProps = {}) {
  const api = useCrmApi();
  const [pipelines, setPipelines] = useState<PipelineData[]>([]);
  const [loading, setLoading] = useState(true);
  const [showPipelineForm, setShowPipelineForm] = useState(false);
  const [editingPipeline, setEditingPipeline] = useState<PipelineData | null>(null);
  const [pipelineName, setPipelineName] = useState('');
  const [pipelineDefault, setPipelineDefault] = useState(false);
  const [showStageForm, setShowStageForm] = useState(false);
  const [editingStage, setEditingStage] = useState<StageData | null>(null);
  const [stagePipelineId, setStagePipelineId] = useState('');
  const [stageName, setStageName] = useState('');
  const [stageColor, setStageColor] = useState(STAGE_COLORS[0]);
  const [stageType, setStageType] = useState<'OPEN' | 'WON' | 'LOST'>('OPEN');
  const [stageStaleDays, setStageStaleDays] = useState('');
  const [stageIsDefault, setStageIsDefault] = useState(false);
  const [customColorHex, setCustomColorHex] = useState('');
  const [deleteStageData, setDeleteStageData] = useState<{
    stage: StageData;
    pipelineId: string;
  } | null>(null);
  const [moveToStageId, setMoveToStageId] = useState('');
  const [deleting, setDeleting] = useState(false);
  const [saving, setSaving] = useState(false);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  );

  const queryParam = entityType ? `?entityType=${entityType}` : '';

  const fetchPipelines = useCallback(async () => {
    try {
      const data = await api.get<PipelineData[]>(`/crm/pipelines${queryParam}`);
      const enriched = await Promise.all(
        data.map(async (p) => {
          const stages = await api.get<StageData[]>(`/crm/pipelines/${p.id}/stages`);
          return { ...p, stages };
        }),
      );
      setPipelines(enriched);
    } catch {
      /**/
    } finally {
      setLoading(false);
    }
  }, [api, queryParam]);

  useEffect(() => {
    void fetchPipelines();
  }, [fetchPipelines]);

  const openCreatePipeline = () => {
    setEditingPipeline(null);
    setPipelineName('');
    setPipelineDefault(false);
    setShowPipelineForm(true);
  };
  const openEditPipeline = (p: PipelineData) => {
    setEditingPipeline(p);
    setPipelineName(p.name);
    setPipelineDefault(p.isDefault);
    setShowPipelineForm(true);
  };

  const handleSavePipeline = async () => {
    if (!pipelineName.trim()) return;
    setSaving(true);
    try {
      if (editingPipeline) {
        await api.patch(`/crm/pipelines/${editingPipeline.id}`, {
          name: pipelineName.trim(),
          isDefault: pipelineDefault,
        });
      } else {
        const body: Record<string, unknown> = {
          name: pipelineName.trim(),
          isDefault: pipelineDefault,
        };
        if (entityType) body.entityType = entityType;
        await api.post('/crm/pipelines', body);
      }
      setShowPipelineForm(false);
      await fetchPipelines();
    } catch {
      /**/
    } finally {
      setSaving(false);
    }
  };

  const handleDeletePipeline = async (id: string) => {
    if (!confirm('Удалить воронку?')) return;
    try {
      await api.delete(`/crm/pipelines/${id}`);
      await fetchPipelines();
    } catch (err: unknown) {
      alert(err instanceof Error ? err.message : 'Ошибка удаления');
    }
  };

  const openCreateStage = (pipelineId: string) => {
    setEditingStage(null);
    setStagePipelineId(pipelineId);
    setStageName('');
    setStageColor(STAGE_COLORS[0]);
    setStageType('OPEN');
    setStageStaleDays('');
    setStageIsDefault(false);
    setCustomColorHex('');
    setShowStageForm(true);
  };

  const openEditStage = (stage: StageData, pipelineId: string) => {
    setEditingStage(stage);
    setStagePipelineId(pipelineId);
    setStageName(stage.name);
    setStageColor(stage.color);
    setStageType(stage.type as 'OPEN' | 'WON' | 'LOST');
    setStageStaleDays(stage.staleDays?.toString() || '');
    setStageIsDefault(stage.isDefault);
    setCustomColorHex(STAGE_COLORS.includes(stage.color) ? '' : stage.color);
    setShowStageForm(true);
  };

  const handleColorChange = (color: string) => {
    setStageColor(color);
    setCustomColorHex(STAGE_COLORS.includes(color) ? '' : color);
  };
  const handleHexInput = (hex: string) => {
    setCustomColorHex(hex);
    if (/^#[0-9a-fA-F]{6}$/.test(hex)) setStageColor(hex);
  };

  const handleSaveStage = async () => {
    if (!stageName.trim()) return;
    setSaving(true);
    try {
      const data: Record<string, unknown> = {
        name: stageName.trim(),
        color: stageColor,
        type: stageType,
        staleDays: stageStaleDays ? parseInt(stageStaleDays) : null,
        isDefault: stageIsDefault,
      };
      if (editingStage) {
        await api.patch(`/crm/pipelines/stages/${editingStage.id}`, data);
      } else {
        const p = pipelines.find((p) => p.id === stagePipelineId);
        data.position = (p?.stages.length ?? 0) + 1;
        await api.post(`/crm/pipelines/${stagePipelineId}/stages`, data);
      }
      setShowStageForm(false);
      await fetchPipelines();
    } catch {
      /**/
    } finally {
      setSaving(false);
    }
  };

  const handleDeleteStage = async () => {
    if (!deleteStageData) return;
    setDeleting(true);
    try {
      const params = moveToStageId ? `?moveToStageId=${moveToStageId}` : '';
      await api.delete(`/crm/pipelines/stages/${deleteStageData.stage.id}${params}`);
      setDeleteStageData(null);
      setMoveToStageId('');
      await fetchPipelines();
    } catch (err: unknown) {
      alert(err instanceof Error ? err.message : 'Ошибка удаления');
    } finally {
      setDeleting(false);
    }
  };

  const handleMoveStage = async (pipelineId: string, stageId: string, direction: 'up' | 'down') => {
    const pipeline = pipelines.find((p) => p.id === pipelineId);
    if (!pipeline) return;
    const sorted = [...pipeline.stages].sort((a, b) => a.position - b.position);
    const idx = sorted.findIndex((s) => s.id === stageId);
    if (direction === 'up' && idx <= 0) return;
    if (direction === 'down' && idx >= sorted.length - 1) return;
    const swapIdx = direction === 'up' ? idx - 1 : idx + 1;
    const tmp = sorted[idx]!;
    sorted[idx] = sorted[swapIdx]!;
    sorted[swapIdx] = tmp;
    try {
      await api.put('/crm/pipelines/stages/reorder', { stageIds: sorted.map((s) => s.id) });
      await fetchPipelines();
    } catch {
      /**/
    }
  };

  const handleDragEnd = async (pipelineId: string, event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    const pipeline = pipelines.find((p) => p.id === pipelineId);
    if (!pipeline) return;
    const sorted = [...pipeline.stages].sort((a, b) => a.position - b.position);
    const oldIdx = sorted.findIndex((s) => s.id === active.id);
    const newIdx = sorted.findIndex((s) => s.id === over.id);
    if (oldIdx === -1 || newIdx === -1) return;
    const [moved] = sorted.splice(oldIdx, 1);
    sorted.splice(newIdx, 0, moved!);
    setPipelines((prev) =>
      prev.map((p) =>
        p.id === pipelineId
          ? { ...p, stages: sorted.map((s, i) => ({ ...s, position: i + 1 })) }
          : p,
      ),
    );
    try {
      await api.put('/crm/pipelines/stages/reorder', { stageIds: sorted.map((s) => s.id) });
    } catch {
      await fetchPipelines();
    }
  };

  if (loading)
    return (
      <div className="flex items-center justify-center py-12">
        <Loader2 className="h-6 w-6 animate-spin text-primary" />
      </div>
    );

  return (
    <div className="space-y-6">
      <div className="flex justify-end">
        <button
          onClick={openCreatePipeline}
          className="flex items-center gap-1.5 px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-colors"
        >
          <Plus className="h-4 w-4" />
          Добавить воронку
        </button>
      </div>

      {pipelines.map((pipeline) => {
        const sorted = [...pipeline.stages].sort((a, b) => a.position - b.position);
        return (
          <div key={pipeline.id} className="bg-card rounded-xl border border-border p-4">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <h3 className="font-semibold text-text">{pipeline.name}</h3>
                {pipeline.isDefault && (
                  <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-primary/10 text-primary flex items-center gap-0.5">
                    <Star className="h-3 w-3" />
                    по умолчанию
                  </span>
                )}
              </div>
              <div className="flex items-center gap-1">
                <button
                  onClick={() => openEditPipeline(pipeline)}
                  className="p-1.5 rounded-lg hover:bg-background text-muted hover:text-text transition-colors"
                  title="Редактировать"
                >
                  <Pencil className="h-4 w-4" />
                </button>
                <button
                  onClick={() => void handleDeletePipeline(pipeline.id)}
                  className="p-1.5 rounded-lg hover:bg-error/10 text-muted hover:text-error transition-colors"
                  title="Удалить"
                >
                  <Trash2 className="h-4 w-4" />
                </button>
              </div>
            </div>
            <DndContext
              sensors={sensors}
              collisionDetection={closestCenter}
              onDragEnd={(e) => void handleDragEnd(pipeline.id, e)}
            >
              <SortableContext
                items={sorted.map((s) => s.id)}
                strategy={verticalListSortingStrategy}
              >
                <div className="space-y-1">
                  {sorted.map((stage, idx) => (
                    <SortableStageRow
                      key={stage.id}
                      stage={stage}
                      index={idx}
                      totalCount={sorted.length}
                      onMoveUp={() => void handleMoveStage(pipeline.id, stage.id, 'up')}
                      onMoveDown={() => void handleMoveStage(pipeline.id, stage.id, 'down')}
                      onEdit={() => openEditStage(stage, pipeline.id)}
                      onDelete={() => setDeleteStageData({ stage, pipelineId: pipeline.id })}
                    />
                  ))}
                </div>
              </SortableContext>
            </DndContext>
            <button
              onClick={() => openCreateStage(pipeline.id)}
              className="flex items-center gap-1.5 mt-3 px-3 py-2 text-sm text-primary hover:bg-primary/5 rounded-lg transition-colors"
            >
              <Plus className="h-4 w-4" />
              Добавить стадию
            </button>
          </div>
        );
      })}

      {pipelines.length === 0 && (
        <div className="text-center py-12 text-muted text-sm">
          Нет воронок. Нажмите кнопку выше, чтобы создать первую.
        </div>
      )}

      {/* Pipeline dialog */}
      <InlineDialog
        open={showPipelineForm}
        onClose={() => setShowPipelineForm(false)}
        title={editingPipeline ? 'Редактировать воронку' : 'Новая воронка'}
        footer={
          <>
            <button
              onClick={() => setShowPipelineForm(false)}
              className="px-4 py-2 text-sm text-muted hover:text-text transition-colors"
            >
              Отмена
            </button>
            <button
              onClick={() => void handleSavePipeline()}
              disabled={saving || !pipelineName.trim()}
              className="px-4 py-2 text-sm bg-primary text-white rounded-lg hover:bg-primary/90 disabled:opacity-50 transition-colors"
            >
              {saving ? 'Сохранение...' : 'Сохранить'}
            </button>
          </>
        }
      >
        <div>
          <label className="block text-sm font-medium text-text mb-1">Название</label>
          <input
            type="text"
            value={pipelineName}
            onChange={(e) => setPipelineName(e.target.value)}
            placeholder="Продажи B2C"
            className={inputClass}
          />
        </div>
        <label className="flex items-center gap-2 text-sm text-text cursor-pointer">
          <input
            type="checkbox"
            checked={pipelineDefault}
            onChange={(e) => setPipelineDefault(e.target.checked)}
            className="rounded border-border"
          />
          По умолчанию
        </label>
      </InlineDialog>

      {/* Stage dialog */}
      <InlineDialog
        open={showStageForm}
        onClose={() => setShowStageForm(false)}
        title={editingStage ? 'Редактировать стадию' : 'Новая стадия'}
        footer={
          <>
            <button
              onClick={() => setShowStageForm(false)}
              className="px-4 py-2 text-sm text-muted hover:text-text transition-colors"
            >
              Отмена
            </button>
            <button
              onClick={() => void handleSaveStage()}
              disabled={saving || !stageName.trim()}
              className="px-4 py-2 text-sm bg-primary text-white rounded-lg hover:bg-primary/90 disabled:opacity-50 transition-colors"
            >
              {saving ? 'Сохранение...' : 'Сохранить'}
            </button>
          </>
        }
      >
        <div>
          <label className="block text-sm font-medium text-text mb-1">Название</label>
          <input
            type="text"
            value={stageName}
            onChange={(e) => setStageName(e.target.value)}
            placeholder="Квалификация"
            className={inputClass}
          />
        </div>
        <div>
          <label className="block text-sm font-medium text-text mb-1">Цвет</label>
          <div className="flex items-center gap-2 flex-wrap">
            {STAGE_COLORS.map((c) => (
              <button
                key={c}
                onClick={() => handleColorChange(c)}
                className={cn(
                  'w-7 h-7 rounded-full border-2 transition-all',
                  stageColor === c ? 'border-text scale-110' : 'border-transparent hover:scale-105',
                )}
                style={{ backgroundColor: c }}
              />
            ))}
          </div>
          <div className="flex items-center gap-2 mt-2">
            <input
              type="color"
              value={stageColor}
              onChange={(e) => handleColorChange(e.target.value)}
              className="w-8 h-8 rounded cursor-pointer border border-border bg-transparent p-0"
            />
            <input
              type="text"
              value={customColorHex || stageColor}
              onChange={(e) => handleHexInput(e.target.value)}
              placeholder="#FF5733"
              maxLength={7}
              className="w-28 px-2 py-1.5 border border-border rounded-lg text-sm font-mono bg-background text-text focus:outline-none focus:ring-2 focus:ring-primary/30"
            />
            <span
              className="w-6 h-6 rounded-full border border-border shrink-0"
              style={{ backgroundColor: stageColor }}
            />
          </div>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="block text-sm font-medium text-text mb-1">Тип</label>
            <select
              value={stageType}
              onChange={(e) => setStageType(e.target.value as 'OPEN' | 'WON' | 'LOST')}
              className={inputClass}
            >
              <option value="OPEN">OPEN (рабочая)</option>
              <option value="WON">WON (выиграна)</option>
              <option value="LOST">LOST (проиграна)</option>
            </select>
          </div>
          <div>
            <label className="block text-sm font-medium text-text mb-1">Устаревание (дни)</label>
            <input
              type="number"
              value={stageStaleDays}
              onChange={(e) => setStageStaleDays(e.target.value)}
              placeholder="—"
              min={0}
              className={inputClass}
            />
          </div>
        </div>
        <label className="flex items-center gap-2 text-sm text-text cursor-pointer">
          <input
            type="checkbox"
            checked={stageIsDefault}
            onChange={(e) => setStageIsDefault(e.target.checked)}
            className="rounded border-border"
          />
          Стадия по умолчанию
        </label>
      </InlineDialog>

      {/* Delete stage dialog */}
      <InlineDialog
        open={!!deleteStageData}
        onClose={() => setDeleteStageData(null)}
        title="Удалить стадию"
        footer={
          <>
            <button
              onClick={() => setDeleteStageData(null)}
              className="px-4 py-2 text-sm text-muted hover:text-text transition-colors"
            >
              Отмена
            </button>
            <button
              onClick={() => void handleDeleteStage()}
              disabled={deleting}
              className="px-4 py-2 text-sm bg-error text-white rounded-lg hover:bg-error/90 disabled:opacity-50 transition-colors"
            >
              {deleting ? 'Удаление...' : 'Удалить'}
            </button>
          </>
        }
      >
        {deleteStageData && (
          <>
            <p className="text-sm text-text">
              Вы удаляете стадию <strong>{deleteStageData.stage.name}</strong>.
            </p>
            {(() => {
              const p = pipelines.find((p) => p.id === deleteStageData.pipelineId);
              const other = p?.stages.filter((s) => s.id !== deleteStageData.stage.id) || [];
              return other.length > 0 ? (
                <div>
                  <label className="block text-sm font-medium text-text mb-1">
                    Перенести сделки в стадию:
                  </label>
                  <select
                    value={moveToStageId}
                    onChange={(e) => setMoveToStageId(e.target.value)}
                    className={inputClass}
                  >
                    <option value="">— Не переносить —</option>
                    {other
                      .sort((a, b) => a.position - b.position)
                      .map((s) => (
                        <option key={s.id} value={s.id}>
                          {s.name} ({s.type})
                        </option>
                      ))}
                  </select>
                </div>
              ) : null;
            })()}
          </>
        )}
      </InlineDialog>
    </div>
  );
}
