'use client';

import { useEffect, useState, useCallback } from 'react';
import {
  GripVertical,
  Plus,
  Trash2,
  Loader2,
  ChevronDown,
  ChevronRight,
  Pencil,
  RotateCcw,
} from 'lucide-react';
import { cn } from '@/lib/cn';
import { api } from '@/lib/api';
import { useUser } from '@/lib/useUser';

/* ─── Types ─── */

interface LayoutField {
  fieldKey: string;
  source: 'system' | 'custom';
  width: 'full' | 'half';
}

interface LayoutBlock {
  blockKey: string;
  blockName: string;
  fields: (LayoutField & { label: string })[];
}

interface RawBlock {
  blockKey: string;
  blockName: string;
  fields: LayoutField[];
}

interface CustomFieldInfo {
  id: string;
  name: string;
  fieldName: string;
  type: string;
}

interface CardLayoutEditorProps {
  entityType?: string;
}

/* ─── System fields ─── */

const DEAL_SYSTEM_FIELDS = [
  { key: 'contactName', label: 'Контакт' },
  { key: 'contactPhone', label: 'Телефон' },
  { key: 'contactEmail', label: 'Email' },
  { key: 'companyName', label: 'Компания' },
  { key: 'amount', label: 'Сумма' },
  { key: 'source', label: 'Источник' },
  { key: 'assignee', label: 'Ответственный' },
  { key: 'createdBy', label: 'Создал' },
  { key: 'createdAt', label: 'Дата создания' },
  { key: 'updatedAt', label: 'Дата обновления' },
  { key: 'closedAt', label: 'Дата закрытия' },
  { key: 'lostReason', label: 'Причина проигрыша' },
  { key: 'lostComment', label: 'Комментарий' },
];

const SYSTEM_FIELDS_MAP: Record<string, { key: string; label: string }[]> = {
  deal: DEAL_SYSTEM_FIELDS,
};

const DEFAULT_BLOCKS: RawBlock[] = [
  {
    blockKey: 'contact',
    blockName: 'Контакт',
    fields: [
      { fieldKey: 'contactName', source: 'system', width: 'full' },
      { fieldKey: 'contactPhone', source: 'system', width: 'half' },
      { fieldKey: 'contactEmail', source: 'system', width: 'half' },
    ],
  },
  {
    blockKey: 'info',
    blockName: 'Информация',
    fields: [
      { fieldKey: 'source', source: 'system', width: 'half' },
      { fieldKey: 'assignee', source: 'system', width: 'half' },
      { fieldKey: 'amount', source: 'system', width: 'half' },
      { fieldKey: 'createdAt', source: 'system', width: 'half' },
    ],
  },
];

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

/* ─── Component ─── */

export function CardLayoutEditor({ entityType = 'deal' }: CardLayoutEditorProps) {
  const user = useUser();
  const isAdmin = user && ['SUPER_ADMIN', 'CLUB_ADMIN'].includes(user.role.toUpperCase());

  const [blocks, setBlocks] = useState<LayoutBlock[]>([]);
  const [customFields, setCustomFields] = useState<CustomFieldInfo[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [isDefault, setIsDefault] = useState(true);
  const [saveForAll, setSaveForAll] = useState(false);
  const [collapsedBlocks, setCollapsedBlocks] = useState<Set<string>>(new Set());
  const [editingBlockName, setEditingBlockName] = useState<string | null>(null);
  const [editBlockNameValue, setEditBlockNameValue] = useState('');

  const systemFields = SYSTEM_FIELDS_MAP[entityType] || DEAL_SYSTEM_FIELDS;

  const getFieldLabel = (
    f: LayoutField,
    sysFields: { key: string; label: string }[],
    cfList: CustomFieldInfo[],
  ): string => {
    if (f.source === 'system') {
      return sysFields.find((sf) => sf.key === f.fieldKey)?.label || f.fieldKey;
    }
    return cfList.find((cf) => cf.fieldName === f.fieldKey)?.name || f.fieldKey;
  };

  const normalizeToBlocks = (
    data: any,
    sysFields: { key: string; label: string }[],
    cfList: CustomFieldInfo[],
  ): LayoutBlock[] => {
    // New format: array of blocks with blockKey
    if (Array.isArray(data) && data.length > 0 && data[0]?.blockKey) {
      return (data as RawBlock[]).map((b) => ({
        ...b,
        fields: b.fields.map((f) => ({ ...f, label: getFieldLabel(f, sysFields, cfList) })),
      }));
    }

    // Old format: flat array of fields — wrap in single block
    if (Array.isArray(data) && data.length > 0) {
      return [
        {
          blockKey: 'main',
          blockName: 'Основное',
          fields: (data as LayoutField[]).map((f) => ({
            ...f,
            label: getFieldLabel(f, sysFields, cfList),
          })),
        },
      ];
    }

    // Empty — build from defaults, adding custom fields
    const defaultBlocks: LayoutBlock[] = DEFAULT_BLOCKS.map((b) => ({
      ...b,
      fields: b.fields.map((f) => ({ ...f, label: getFieldLabel(f, sysFields, cfList) })),
    }));

    if (cfList.length > 0) {
      defaultBlocks.push({
        blockKey: 'custom',
        blockName: 'Дополнительные поля',
        fields: cfList.map((cf) => ({
          fieldKey: cf.fieldName,
          source: 'custom' as const,
          width: 'half' as const,
          label: cf.name,
        })),
      });
    }

    return defaultBlocks;
  };

  const fetchLayout = useCallback(async () => {
    try {
      const [layoutData, cfData] = await Promise.all([
        api.get<{ blocks: any; isDefault: boolean }>(`/crm/card-layouts?entityType=${entityType}`),
        api.get<CustomFieldInfo[]>(`/crm/fields?entityType=${entityType}`),
      ]);

      setCustomFields(cfData);
      setIsDefault(layoutData.isDefault);
      setBlocks(normalizeToBlocks(layoutData.blocks, systemFields, cfData));
    } catch {
      //
    } finally {
      setLoading(false);
    }
  }, [entityType, systemFields]);

  useEffect(() => {
    setLoading(true);
    void fetchLayout();
  }, [fetchLayout]);

  /* ─── Block operations ─── */

  const addBlock = () => {
    const name = prompt('Название блока:');
    if (!name?.trim()) return;
    const key = `block_${Date.now()}`;
    setBlocks((prev) => [...prev, { blockKey: key, blockName: name.trim(), fields: [] }]);
  };

  const removeBlock = (blockKey: string) => {
    const block = blocks.find((b) => b.blockKey === blockKey);
    if (block && block.fields.length > 0) {
      if (!confirm(`Удалить блок "${block.blockName}" с ${block.fields.length} полями?`)) return;
    }
    setBlocks((prev) => prev.filter((b) => b.blockKey !== blockKey));
  };

  const moveBlock = (fromIdx: number, toIdx: number) => {
    if (toIdx < 0 || toIdx >= blocks.length) return;
    setBlocks((prev) => {
      const next = [...prev];
      const removed = next.splice(fromIdx, 1);
      if (removed[0]) next.splice(toIdx, 0, removed[0]);
      return next;
    });
  };

  const startRenameBlock = (blockKey: string) => {
    const block = blocks.find((b) => b.blockKey === blockKey);
    if (!block) return;
    setEditingBlockName(blockKey);
    setEditBlockNameValue(block.blockName);
  };

  const confirmRenameBlock = () => {
    if (!editingBlockName || !editBlockNameValue.trim()) {
      setEditingBlockName(null);
      return;
    }
    setBlocks((prev) =>
      prev.map((b) =>
        b.blockKey === editingBlockName ? { ...b, blockName: editBlockNameValue.trim() } : b,
      ),
    );
    setEditingBlockName(null);
  };

  const toggleCollapse = (blockKey: string) => {
    setCollapsedBlocks((prev) => {
      const next = new Set(prev);
      if (next.has(blockKey)) next.delete(blockKey);
      else next.add(blockKey);
      return next;
    });
  };

  /* ─── Field operations within a block ─── */

  const addFieldToBlock = (
    blockKey: string,
    fieldKey: string,
    source: 'system' | 'custom',
    label: string,
  ) => {
    // Don't add duplicates across all blocks
    const allFields = blocks.flatMap((b) => b.fields);
    if (allFields.some((f) => f.fieldKey === fieldKey && f.source === source)) return;

    setBlocks((prev) =>
      prev.map((b) =>
        b.blockKey === blockKey
          ? { ...b, fields: [...b.fields, { fieldKey, source, width: 'half' as const, label }] }
          : b,
      ),
    );
  };

  const removeFieldFromBlock = (blockKey: string, fieldIdx: number) => {
    setBlocks((prev) =>
      prev.map((b) =>
        b.blockKey === blockKey ? { ...b, fields: b.fields.filter((_, i) => i !== fieldIdx) } : b,
      ),
    );
  };

  const moveFieldInBlock = (blockKey: string, fromIdx: number, toIdx: number) => {
    setBlocks((prev) =>
      prev.map((b) => {
        if (b.blockKey !== blockKey) return b;
        if (toIdx < 0 || toIdx >= b.fields.length) return b;
        const next = [...b.fields];
        const removed = next.splice(fromIdx, 1);
        if (removed[0]) next.splice(toIdx, 0, removed[0]);
        return { ...b, fields: next };
      }),
    );
  };

  const toggleFieldWidth = (blockKey: string, fieldIdx: number) => {
    setBlocks((prev) =>
      prev.map((b) =>
        b.blockKey === blockKey
          ? {
              ...b,
              fields: b.fields.map((f, i) =>
                i === fieldIdx ? { ...f, width: f.width === 'full' ? 'half' : 'full' } : f,
              ),
            }
          : b,
      ),
    );
  };

  /* ─── Save ─── */

  const handleSave = async () => {
    setSaving(true);
    try {
      const payload = {
        entityType,
        blocks: blocks.map((b) => ({
          blockKey: b.blockKey,
          blockName: b.blockName,
          fields: b.fields.map(({ fieldKey, source, width }) => ({ fieldKey, source, width })),
        })),
        saveForAll: saveForAll && isAdmin,
      };

      await api.put('/crm/card-layouts/me', payload);
      setIsDefault(false);
    } catch (err: any) {
      alert(err?.message || 'Ошибка сохранения');
    } finally {
      setSaving(false);
    }
  };

  const handleReset = async () => {
    if (!confirm('Сбросить к общему виду?')) return;
    try {
      await api.delete(`/crm/card-layouts/me?entityType=${entityType}`);
      setLoading(true);
      await fetchLayout();
    } catch {
      // may not have a personal layout
      setLoading(true);
      await fetchLayout();
    }
  };

  /* ─── Unused fields (across all blocks) ─── */

  const allUsedFields = blocks.flatMap((b) => b.fields);
  const unusedSystemFields = systemFields.filter(
    (sf) => !allUsedFields.some((f) => f.fieldKey === sf.key && f.source === 'system'),
  );
  const unusedCustomFields = customFields.filter(
    (cf) => !allUsedFields.some((f) => f.fieldKey === cf.fieldName && f.source === 'custom'),
  );

  /* ─── Target block for adding fields ─── */
  const [addToBlock, setAddToBlock] = useState<string | null>(null);

  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">
      {/* Header with status */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <h3 className="text-sm font-medium text-text">Раскладка карточки</h3>
          {!isDefault && (
            <span className="text-[10px] px-2 py-0.5 rounded-full bg-primary/10 text-primary">
              Мой вид
            </span>
          )}
        </div>
        <div className="flex items-center gap-2">
          {!isDefault && (
            <button
              onClick={handleReset}
              className="flex items-center gap-1 px-2 py-1 text-xs text-muted hover:text-text transition-colors"
            >
              <RotateCcw className="h-3 w-3" />
              Сбросить к общему
            </button>
          )}
        </div>
      </div>

      {/* Blocks */}
      {blocks.map((block, blockIdx) => {
        const isCollapsed = collapsedBlocks.has(block.blockKey);

        return (
          <div
            key={block.blockKey}
            className="bg-card rounded-xl border border-border overflow-hidden"
          >
            {/* Block header */}
            <div className="flex items-center gap-2 px-4 py-2.5 bg-background/50 border-b border-border/50">
              <div className="flex flex-col gap-0.5">
                <button
                  onClick={() => moveBlock(blockIdx, blockIdx - 1)}
                  disabled={blockIdx === 0}
                  className="text-muted hover:text-text disabled:opacity-20 transition-colors"
                >
                  <GripVertical className="h-3 w-3 rotate-180" />
                </button>
                <button
                  onClick={() => moveBlock(blockIdx, blockIdx + 1)}
                  disabled={blockIdx === blocks.length - 1}
                  className="text-muted hover:text-text disabled:opacity-20 transition-colors"
                >
                  <GripVertical className="h-3 w-3" />
                </button>
              </div>

              <button
                onClick={() => toggleCollapse(block.blockKey)}
                className="p-0.5 text-muted hover:text-text transition-colors"
              >
                {isCollapsed ? (
                  <ChevronRight className="h-4 w-4" />
                ) : (
                  <ChevronDown className="h-4 w-4" />
                )}
              </button>

              {editingBlockName === block.blockKey ? (
                <input
                  type="text"
                  value={editBlockNameValue}
                  onChange={(e) => setEditBlockNameValue(e.target.value)}
                  onBlur={confirmRenameBlock}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter') confirmRenameBlock();
                    if (e.key === 'Escape') setEditingBlockName(null);
                  }}
                  className={cn(inputClass, 'w-40')}
                  autoFocus
                />
              ) : (
                <span
                  className="text-sm font-medium text-text cursor-pointer hover:bg-primary/5 rounded px-1 transition-colors"
                  onDoubleClick={() => startRenameBlock(block.blockKey)}
                  title="Двойной клик для переименования"
                >
                  {block.blockName}
                </span>
              )}

              <span className="text-[10px] text-muted">{block.fields.length} полей</span>

              <div className="flex-1" />

              <button
                onClick={() => startRenameBlock(block.blockKey)}
                className="p-1 rounded hover:bg-background text-muted hover:text-text transition-colors"
                title="Переименовать"
              >
                <Pencil className="h-3 w-3" />
              </button>
              <button
                onClick={() => removeBlock(block.blockKey)}
                className="p-1 rounded hover:bg-error/10 text-muted hover:text-error transition-colors"
                title="Удалить блок"
              >
                <Trash2 className="h-3 w-3" />
              </button>
            </div>

            {/* Block fields */}
            {!isCollapsed && (
              <div>
                {block.fields.length === 0 ? (
                  <div className="text-center py-4 text-muted text-xs">
                    Нет полей.{' '}
                    <button
                      onClick={() => setAddToBlock(block.blockKey)}
                      className="text-primary hover:underline"
                    >
                      Добавить
                    </button>
                  </div>
                ) : (
                  <div className="divide-y divide-border/50">
                    {block.fields.map((field, fieldIdx) => (
                      <div
                        key={`${field.source}-${field.fieldKey}`}
                        className="flex items-center gap-3 px-4 py-2 group"
                      >
                        <div className="flex flex-col gap-0.5">
                          <button
                            onClick={() => moveFieldInBlock(block.blockKey, fieldIdx, fieldIdx - 1)}
                            disabled={fieldIdx === 0}
                            className="text-muted hover:text-text disabled:opacity-20 transition-colors"
                          >
                            <GripVertical className="h-3 w-3 rotate-180" />
                          </button>
                          <button
                            onClick={() => moveFieldInBlock(block.blockKey, fieldIdx, fieldIdx + 1)}
                            disabled={fieldIdx === block.fields.length - 1}
                            className="text-muted hover:text-text disabled:opacity-20 transition-colors"
                          >
                            <GripVertical className="h-3 w-3" />
                          </button>
                        </div>

                        <div className="flex-1 min-w-0">
                          <span className="text-sm text-text">{field.label}</span>
                          <span className="text-[10px] ml-2 text-muted">
                            {field.source === 'system' ? 'системное' : 'кастомное'}
                          </span>
                        </div>

                        <button
                          onClick={() => toggleFieldWidth(block.blockKey, fieldIdx)}
                          className={cn(
                            'text-[10px] px-2 py-0.5 rounded border transition-colors',
                            field.width === 'full'
                              ? 'border-primary/30 bg-primary/5 text-primary'
                              : 'border-border bg-background text-muted',
                          )}
                        >
                          {field.width === 'full' ? 'Полная' : '½'}
                        </button>

                        <button
                          onClick={() => removeFieldFromBlock(block.blockKey, fieldIdx)}
                          className="p-1 rounded hover:bg-error/10 text-muted hover:text-error transition-colors opacity-0 group-hover:opacity-100"
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    ))}
                  </div>
                )}

                {/* Add field button */}
                <div className="px-4 py-2 border-t border-border/30">
                  <button
                    onClick={() =>
                      setAddToBlock(addToBlock === block.blockKey ? null : block.blockKey)
                    }
                    className="flex items-center gap-1 text-xs text-primary hover:text-primary/80 transition-colors"
                  >
                    <Plus className="h-3 w-3" />
                    Добавить поле
                  </button>
                </div>

                {/* Field picker for this block */}
                {addToBlock === block.blockKey &&
                  (unusedSystemFields.length > 0 || unusedCustomFields.length > 0) && (
                    <div className="px-4 py-2 border-t border-border/30 bg-background/30">
                      <div className="flex flex-wrap gap-1.5">
                        {unusedSystemFields.map((sf) => (
                          <button
                            key={sf.key}
                            onClick={() => {
                              addFieldToBlock(block.blockKey, sf.key, 'system', sf.label);
                            }}
                            className="flex items-center gap-1 px-2 py-1 text-[11px] border border-border rounded text-muted hover:text-text hover:border-primary/30 transition-colors"
                          >
                            <Plus className="h-2.5 w-2.5" />
                            {sf.label}
                          </button>
                        ))}
                        {unusedCustomFields.map((cf) => (
                          <button
                            key={cf.fieldName}
                            onClick={() => {
                              addFieldToBlock(block.blockKey, cf.fieldName, 'custom', cf.name);
                            }}
                            className="flex items-center gap-1 px-2 py-1 text-[11px] border border-dashed border-border rounded text-muted hover:text-text hover:border-primary/30 transition-colors"
                          >
                            <Plus className="h-2.5 w-2.5" />
                            {cf.name}
                          </button>
                        ))}
                      </div>
                    </div>
                  )}
              </div>
            )}
          </div>
        );
      })}

      {/* Add block */}
      <button
        onClick={addBlock}
        className="flex items-center gap-1.5 px-4 py-2.5 text-sm text-primary hover:bg-primary/5 rounded-lg transition-colors w-full justify-center border border-dashed border-primary/30"
      >
        <Plus className="h-4 w-4" />
        Добавить блок
      </button>

      {/* Preview */}
      <div>
        <h3 className="text-sm font-medium text-text mb-3">Предпросмотр</h3>
        <div className="space-y-3">
          {blocks.map((block) => (
            <div key={block.blockKey} className="bg-card rounded-xl border border-border p-4">
              <div className="text-xs font-medium text-text mb-2">{block.blockName}</div>
              {block.fields.length === 0 ? (
                <div className="text-[10px] text-muted">Пустой блок</div>
              ) : (
                <div className="grid grid-cols-2 gap-2">
                  {block.fields.map((field) => (
                    <div
                      key={`${field.source}-${field.fieldKey}`}
                      className={cn(
                        'p-1.5 rounded bg-background border border-border/50',
                        field.width === 'full' && 'col-span-2',
                      )}
                    >
                      <div className="text-[10px] text-muted">{field.label}</div>
                      <div className="text-[10px] text-text/50">—</div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
      </div>

      {/* Actions */}
      <div className="flex items-center justify-between">
        <div>
          {isAdmin && (
            <label className="flex items-center gap-2 text-sm text-text cursor-pointer">
              <input
                type="checkbox"
                checked={saveForAll}
                onChange={(e) => setSaveForAll(e.target.checked)}
                className="w-4 h-4 rounded border-border text-primary focus:ring-primary/30"
              />
              Сохранить для всех
            </label>
          )}
        </div>
        <button
          onClick={handleSave}
          disabled={saving}
          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>
    </div>
  );
}
