import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useQuery, useMutation } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import { ArrowLeft, Save, Plus, Trash2, Send, GripVertical } from 'lucide-react';
import {
  DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent,
} from '@dnd-kit/core';
import {
  arrayMove, SortableContext, useSortable, verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { api } from '../../lib/api-client';
import { AppShell, PageHeader, PageBody } from '../../layout/AppShell';
import { Button, Card, CardContent, Input, Label, Select, Textarea } from '../../components/ui/primitives';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '../../components/ui/dialog';

type BlockType = 'heading' | 'paragraph' | 'image' | 'button' | 'product-grid' | 'divider' | 'spacer' | 'html';

interface Block {
  id: string;
  type: BlockType;
  content: Record<string, unknown>;
}

interface Template {
  id: number;
  name: string;
  type: string;
  blocks_json: Block[];
  html_cache: string;
}

const BLOCK_DEFAULTS: Record<BlockType, Record<string, unknown>> = {
  heading: { text: 'Nieuwe titel', level: 2 },
  paragraph: { text: 'Schrijf hier je tekst...' },
  image: { url: '', alt: '', width: 600 },
  button: { text: 'Shop nu', url: '#', color: '#00FF6A' },
  'product-grid': { collection_slug: '', limit: 6 },
  divider: {},
  spacer: { height: 32 },
  html: { html: '<p>Custom HTML...</p>' },
};

export function EmailEditor() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [template, setTemplate] = useState<Template | null>(null);
  const [testOpen, setTestOpen] = useState(false);
  const [testEmail, setTestEmail] = useState('');

  const { data } = useQuery({
    queryKey: ['email-template', id],
    queryFn: () => api.get<{ template: Template }>(`/emails/${id}`),
    enabled: !!id,
  });

  useEffect(() => {
    if (data?.template) {
      setTemplate({
        ...data.template,
        blocks_json: (data.template.blocks_json ?? []).map((b, i) => ({
          ...b,
          id: b.id ?? `block-${i}-${Date.now()}`,
        })),
      });
    }
  }, [data?.template]);

  const saveMut = useMutation({
    mutationFn: () => {
      if (!template) throw new Error('no template');
      return api.put(`/emails/${id}`, {
        name: template.name,
        type: template.type,
        blocks_json: template.blocks_json,
      });
    },
    onSuccess: () => toast.success('Template opgeslagen'),
    onError: (e: Error) => toast.error(e.message),
  });

  const testSendMut = useMutation({
    mutationFn: () => api.post<{ jobId: number }>('/emails/test-send', { template_id: Number(id), to: testEmail }),
    onSuccess: (res) => {
      toast.success(`Test-email in wachtrij (job #${res.jobId})`);
      setTestOpen(false);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));

  if (!template) {
    return (
      <AppShell>
        <PageHeader title="Laden..." />
      </AppShell>
    );
  }

  function onDragEnd(ev: DragEndEvent) {
    const { active, over } = ev;
    if (!template || !over || active.id === over.id) return;
    const oldIdx = template.blocks_json.findIndex((b) => b.id === active.id);
    const newIdx = template.blocks_json.findIndex((b) => b.id === over.id);
    setTemplate({ ...template, blocks_json: arrayMove(template.blocks_json, oldIdx, newIdx) });
  }

  function addBlock(type: BlockType) {
    if (!template) return;
    const block: Block = {
      id: `block-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
      type,
      content: { ...BLOCK_DEFAULTS[type] },
    };
    setTemplate({ ...template, blocks_json: [...template.blocks_json, block] });
  }

  function updateBlock(id: string, content: Record<string, unknown>) {
    if (!template) return;
    setTemplate({
      ...template,
      blocks_json: template.blocks_json.map((b) => (b.id === id ? { ...b, content } : b)),
    });
  }

  function removeBlock(id: string) {
    if (!template) return;
    setTemplate({ ...template, blocks_json: template.blocks_json.filter((b) => b.id !== id) });
  }

  return (
    <AppShell>
      <PageHeader
        title={template.name}
        description={`Type: ${template.type}`}
        actions={
          <>
            <Button variant="ghost" size="sm" onClick={() => navigate('/cms/emails')}>
              <ArrowLeft className="h-4 w-4" />
              Terug
            </Button>
            <Button variant="secondary" size="sm" onClick={() => setTestOpen(true)}>
              <Send className="h-4 w-4" />
              Test-email
            </Button>
            <Button size="sm" onClick={() => saveMut.mutate()} disabled={saveMut.isPending}>
              <Save className="h-4 w-4" />
              Opslaan
            </Button>
          </>
        }
      />
      <PageBody>
        <div className="grid grid-cols-12 gap-6">
          <div className="col-span-3">
            <Card>
              <div className="px-4 py-3 border-b border-[#333]">
                <span className="text-sm font-medium text-[#F5F5F5]">Blokken</span>
              </div>
              <div className="px-3 py-3 space-y-1">
                {(Object.keys(BLOCK_DEFAULTS) as BlockType[]).map((t) => (
                  <button
                    key={t}
                    onClick={() => addBlock(t)}
                    className="w-full text-left px-3 py-2 text-xs text-[#F5F5F5] rounded-md hover:bg-[#1A1A1A] flex items-center gap-2"
                  >
                    <Plus className="h-3 w-3 text-[#666]" />
                    {t}
                  </button>
                ))}
              </div>
            </Card>

            <Card className="mt-4">
              <div className="px-4 py-3 border-b border-[#333]">
                <span className="text-sm font-medium text-[#F5F5F5]">Info</span>
              </div>
              <CardContent>
                <div className="space-y-3">
                  <div>
                    <Label>Naam</Label>
                    <Input className="mt-1" value={template.name} onChange={(e) => setTemplate({ ...template, name: e.target.value })} />
                  </div>
                  <div>
                    <Label>Type</Label>
                    <Select className="mt-1" value={template.type} onChange={(e) => setTemplate({ ...template, type: e.target.value })}>
                      <option value="newsletter">Newsletter</option>
                      <option value="campaign">Campaign</option>
                      <option value="transactional">Transactional</option>
                      <option value="price-drop">Price drop</option>
                      <option value="custom">Custom</option>
                    </Select>
                  </div>
                </div>
              </CardContent>
            </Card>
          </div>

          <div className="col-span-9">
            <Card>
              <div className="px-5 py-3 border-b border-[#333] text-xs text-[#999]">
                {template.blocks_json.length} blokken · sleep om volgorde aan te passen
              </div>
              <div className="px-5 py-4">
                {template.blocks_json.length === 0 ? (
                  <div className="py-12 text-center text-sm text-[#666]">
                    Nog geen blokken. Kies links een type om te beginnen.
                  </div>
                ) : (
                  <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>
                    <SortableContext items={template.blocks_json.map((b) => b.id)} strategy={verticalListSortingStrategy}>
                      <div className="space-y-2">
                        {template.blocks_json.map((b) => (
                          <SortableBlock
                            key={b.id}
                            block={b}
                            onChange={(content) => updateBlock(b.id, content)}
                            onRemove={() => removeBlock(b.id)}
                          />
                        ))}
                      </div>
                    </SortableContext>
                  </DndContext>
                )}
              </div>
            </Card>
          </div>
        </div>
      </PageBody>

      <Dialog open={testOpen} onOpenChange={setTestOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Test-email sturen</DialogTitle>
          </DialogHeader>
          <div>
            <Label>Naar e-mailadres</Label>
            <Input type="email" className="mt-1" value={testEmail} onChange={(e) => setTestEmail(e.target.value)} placeholder="jij@voorbeeld.nl" />
          </div>
          <DialogFooter>
            <Button variant="ghost" onClick={() => setTestOpen(false)}>Annuleer</Button>
            <Button onClick={() => testSendMut.mutate()} disabled={!testEmail || testSendMut.isPending}>
              <Send className="h-4 w-4" />
              Verstuur
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </AppShell>
  );
}

function SortableBlock({
  block,
  onChange,
  onRemove,
}: {
  block: Block;
  onChange: (c: Record<string, unknown>) => void;
  onRemove: () => void;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: block.id });
  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  };
  return (
    <div ref={setNodeRef} style={style} className="border border-[#333] rounded-md bg-[#0A0A0A] p-3">
      <div className="flex items-start gap-2">
        <button {...attributes} {...listeners} className="mt-1 text-[#666] hover:text-[#F5F5F5] cursor-grab">
          <GripVertical className="h-4 w-4" />
        </button>
        <div className="flex-1">
          <div className="flex items-center justify-between mb-2">
            <span className="text-xs font-medium text-[#00FF6A] uppercase">{block.type}</span>
            <Button variant="ghost" size="icon" onClick={onRemove}>
              <Trash2 className="h-4 w-4 text-[#FF3B3B]" />
            </Button>
          </div>
          <BlockEditor block={block} onChange={onChange} />
        </div>
      </div>
    </div>
  );
}

function BlockEditor({ block, onChange }: { block: Block; onChange: (c: Record<string, unknown>) => void }) {
  const c = block.content;
  if (block.type === 'heading') {
    return (
      <div className="space-y-2">
        <Input value={(c.text as string) ?? ''} onChange={(e) => onChange({ ...c, text: e.target.value })} />
        <Select value={String(c.level ?? 2)} onChange={(e) => onChange({ ...c, level: Number(e.target.value) })}>
          <option value="1">H1</option>
          <option value="2">H2</option>
          <option value="3">H3</option>
        </Select>
      </div>
    );
  }
  if (block.type === 'paragraph') {
    return <Textarea rows={3} value={(c.text as string) ?? ''} onChange={(e) => onChange({ ...c, text: e.target.value })} />;
  }
  if (block.type === 'image') {
    return (
      <div className="grid grid-cols-2 gap-2">
        <Input placeholder="URL" value={(c.url as string) ?? ''} onChange={(e) => onChange({ ...c, url: e.target.value })} />
        <Input placeholder="Alt" value={(c.alt as string) ?? ''} onChange={(e) => onChange({ ...c, alt: e.target.value })} />
      </div>
    );
  }
  if (block.type === 'button') {
    return (
      <div className="grid grid-cols-2 gap-2">
        <Input placeholder="Tekst" value={(c.text as string) ?? ''} onChange={(e) => onChange({ ...c, text: e.target.value })} />
        <Input placeholder="URL" value={(c.url as string) ?? ''} onChange={(e) => onChange({ ...c, url: e.target.value })} />
      </div>
    );
  }
  if (block.type === 'product-grid') {
    return (
      <div className="grid grid-cols-2 gap-2">
        <Input placeholder="Collectie slug" value={(c.collection_slug as string) ?? ''} onChange={(e) => onChange({ ...c, collection_slug: e.target.value })} />
        <Input type="number" placeholder="Aantal" value={Number(c.limit ?? 6)} onChange={(e) => onChange({ ...c, limit: Number(e.target.value) })} />
      </div>
    );
  }
  if (block.type === 'spacer') {
    return <Input type="number" value={Number(c.height ?? 32)} onChange={(e) => onChange({ ...c, height: Number(e.target.value) })} />;
  }
  if (block.type === 'html') {
    return <Textarea rows={5} className="font-mono text-xs" value={(c.html as string) ?? ''} onChange={(e) => onChange({ ...c, html: e.target.value })} />;
  }
  return <p className="text-xs text-[#666]">Geen opties voor "{block.type}"</p>;
}
