import { useState } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import { ArrowLeft, Play, Trash2, Save, Plus, X } from 'lucide-react';
import { api } from '../../lib/api-client';
import { AppShell, PageHeader, PageBody } from '../../layout/AppShell';
import { Button, Badge, Card, CardContent, Input, Label, Select, Skeleton, Textarea } from '../../components/ui/primitives';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '../../components/ui/tabs';
import { Table, THead, TBody, TR, TH, TD } from '../../components/ui/table';
import { useJobPoll } from '../../hooks/useJobPoll';
import type { Feed, SyncLog, FieldMapping } from './types';

const TRANSFORMS = [
  '',
  'lowercase',
  'uppercase',
  'trim',
  'strip_html',
  'strip_whitespace',
  'parse_price',
  'parse_boolean',
];

const TARGET_FIELDS = [
  'sku', 'name', 'description', 'brand', 'model', 'category', 'gender',
  'price', 'sale_price', 'currency', 'in_stock', 'stock_count',
  'image_url', 'product_url', 'size', 'color', 'ean', 'gtin', 'mpn',
];

export function FeedDetail() {
  const { id } = useParams<{ id: string }>();
  const feedId = Number(id);
  const navigate = useNavigate();
  const qc = useQueryClient();
  const [activeJobId, setActiveJobId] = useState<number | null>(null);

  const { data: feedData, isLoading } = useQuery({
    queryKey: ['feed', feedId],
    queryFn: () => api.get<{ feed: Feed }>(`/feeds/${feedId}`),
    enabled: !!feedId,
  });

  const { job: syncJob } = useJobPoll(activeJobId);

  const syncMut = useMutation({
    mutationFn: () => api.post<{ jobId: number }>(`/feeds/${feedId}/sync`),
    onSuccess: (res) => {
      setActiveJobId(res.jobId);
      toast.success(`Sync gestart (job #${res.jobId})`);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMut = useMutation({
    mutationFn: () => api.delete(`/feeds/${feedId}`),
    onSuccess: () => {
      toast.success('Feed verwijderd');
      navigate('/cms/feeds');
    },
    onError: (e: Error) => toast.error(e.message),
  });

  function confirmDelete() {
    if (confirm('Weet je zeker dat je deze feed wilt verwijderen? Alle mappings en sync-geschiedenis gaan mee.')) {
      deleteMut.mutate();
    }
  }

  if (isLoading) {
    return (
      <AppShell>
        <PageHeader title="Feed laden..." />
        <PageBody>
          <Skeleton className="h-64 w-full" />
        </PageBody>
      </AppShell>
    );
  }

  const feed = feedData?.feed;
  if (!feed) {
    return (
      <AppShell>
        <PageHeader title="Feed niet gevonden" />
        <PageBody>
          <Button onClick={() => navigate('/cms/feeds')}>Terug</Button>
        </PageBody>
      </AppShell>
    );
  }

  return (
    <AppShell>
      <PageHeader
        title={feed.name}
        description={`${feed.provider_name ?? feed.provider_slug ?? '?'} · ${feed.total_products?.toLocaleString('nl-NL') ?? 0} producten`}
        actions={
          <>
            <Button variant="ghost" size="sm" onClick={() => navigate('/cms/feeds')}>
              <ArrowLeft className="h-4 w-4" />
              Feeds
            </Button>
            <Button
              variant="secondary"
              size="sm"
              onClick={() => syncMut.mutate()}
              disabled={syncMut.isPending || !!(syncJob && !['completed', 'failed', 'cancelled'].includes(syncJob.status))}
            >
              <Play className="h-4 w-4" />
              Sync nu
            </Button>
            <Button variant="danger" size="sm" onClick={confirmDelete}>
              <Trash2 className="h-4 w-4" />
              Verwijder
            </Button>
          </>
        }
      />
      <PageBody>
        {syncJob && (
          <Card className="mb-6">
            <CardContent>
              <div className="flex items-center justify-between mb-2">
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-[#F5F5F5]">Sync job #{syncJob.id}</span>
                  <Badge variant={
                    syncJob.status === 'completed' ? 'success' :
                    syncJob.status === 'failed' ? 'danger' :
                    syncJob.status === 'running' ? 'info' : 'warn'
                  }>
                    {syncJob.status}
                  </Badge>
                </div>
                <button className="text-xs text-[#666] hover:text-[#F5F5F5]" onClick={() => setActiveJobId(null)}>
                  <X className="h-4 w-4" />
                </button>
              </div>
              <div className="h-2 bg-[#1A1A1A] rounded-full overflow-hidden">
                <div
                  className="h-full bg-[#00FF6A] transition-all"
                  style={{ width: `${syncJob.progress}%` }}
                />
              </div>
              {syncJob.log && <p className="text-xs text-[#999] mt-2">{syncJob.log}</p>}
              {syncJob.error && <p className="text-xs text-[#FF3B3B] mt-2">{syncJob.error}</p>}
            </CardContent>
          </Card>
        )}

        <Tabs defaultValue="config">
          <TabsList>
            <TabsTrigger value="config">Configuratie</TabsTrigger>
            <TabsTrigger value="mappings">Field mappings</TabsTrigger>
            <TabsTrigger value="history">Historie</TabsTrigger>
            <TabsTrigger value="tester">Mapping tester</TabsTrigger>
          </TabsList>

          <TabsContent value="config">
            <ConfigTab feed={feed} onSaved={() => qc.invalidateQueries({ queryKey: ['feed', feedId] })} />
          </TabsContent>
          <TabsContent value="mappings">
            <MappingsTab feedId={feedId} />
          </TabsContent>
          <TabsContent value="history">
            <HistoryTab feedId={feedId} />
          </TabsContent>
          <TabsContent value="tester">
            <TesterTab feedId={feedId} />
          </TabsContent>
        </Tabs>
      </PageBody>
    </AppShell>
  );
}

function ConfigTab({ feed, onSaved }: { feed: Feed; onSaved: () => void }) {
  const [form, setForm] = useState({
    name: feed.name,
    feed_url: feed.feed_url,
    is_active: feed.is_active,
    sync_frequency_hours: feed.sync_frequency_hours,
  });

  const saveMut = useMutation({
    mutationFn: (body: typeof form) => api.put<{ feed: Feed }>(`/feeds/${feed.id}`, body),
    onSuccess: () => {
      toast.success('Opgeslagen');
      onSaved();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  return (
    <Card>
      <CardContent>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 max-w-3xl">
          <div>
            <Label htmlFor="name">Naam</Label>
            <Input id="name" className="mt-1" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
          </div>
          <div>
            <Label htmlFor="freq">Sync-frequentie (uren)</Label>
            <Input
              id="freq"
              type="number"
              min={1}
              max={168}
              className="mt-1"
              value={form.sync_frequency_hours}
              onChange={(e) => setForm({ ...form, sync_frequency_hours: Number(e.target.value) })}
            />
          </div>
          <div className="md:col-span-2">
            <Label htmlFor="url">Feed URL</Label>
            <Input id="url" type="url" className="mt-1" value={form.feed_url} onChange={(e) => setForm({ ...form, feed_url: e.target.value })} />
          </div>
          <div className="md:col-span-2">
            <label className="flex items-center gap-2 cursor-pointer">
              <input
                type="checkbox"
                checked={form.is_active}
                onChange={(e) => setForm({ ...form, is_active: e.target.checked })}
                className="h-4 w-4 rounded border-[#333] bg-[#0A0A0A] text-[#00FF6A]"
              />
              <span className="text-sm text-[#F5F5F5]">Actief (automatisch synchroniseren)</span>
            </label>
          </div>
        </div>
        <div className="flex gap-2 pt-4 mt-4 border-t border-[#333]">
          <Button onClick={() => saveMut.mutate(form)} disabled={saveMut.isPending}>
            <Save className="h-4 w-4" />
            Opslaan
          </Button>
        </div>

        <div className="mt-6 pt-6 border-t border-[#333] grid grid-cols-2 md:grid-cols-4 gap-4 text-xs">
          <div>
            <p className="text-[#666]">Totaal producten</p>
            <p className="text-base font-semibold text-[#F5F5F5] mt-0.5">{feed.total_products?.toLocaleString('nl-NL') ?? 0}</p>
          </div>
          <div>
            <p className="text-[#666]">Laatste sync</p>
            <p className="text-sm text-[#F5F5F5] mt-0.5">{feed.last_synced_at ? new Date(feed.last_synced_at).toLocaleString('nl-NL') : '—'}</p>
          </div>
          <div>
            <p className="text-[#666]">Laatste succes</p>
            <p className="text-sm text-[#F5F5F5] mt-0.5">{feed.last_success_at ? new Date(feed.last_success_at).toLocaleString('nl-NL') : '—'}</p>
          </div>
          <div>
            <p className="text-[#666]">Opeenvolgende fouten</p>
            <p className="text-sm text-[#F5F5F5] mt-0.5">{feed.consecutive_failures}</p>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

function MappingsTab({ feedId }: { feedId: number }) {
  const { data, isLoading } = useQuery({
    queryKey: ['feed-mappings', feedId],
    queryFn: () => api.get<{ mappings: FieldMapping[] }>(`/feeds/${feedId}/mappings`),
  });

  const [rows, setRows] = useState<FieldMapping[] | null>(null);
  const current = rows ?? data?.mappings ?? [];

  const qc = useQueryClient();
  const saveMut = useMutation({
    mutationFn: (body: FieldMapping[]) => api.put(`/feeds/${feedId}/mappings`, { mappings: body }),
    onSuccess: () => {
      toast.success('Mappings opgeslagen');
      setRows(null);
      qc.invalidateQueries({ queryKey: ['feed-mappings', feedId] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  function update(i: number, patch: Partial<FieldMapping>) {
    const next = [...current];
    next[i] = { ...next[i], ...patch };
    setRows(next);
  }
  function add() {
    setRows([
      ...current,
      {
        id: 0,
        feed_id: feedId,
        source_field: '',
        target_field: 'name',
        transform: null,
        default_value: null,
        is_required: false,
      },
    ]);
  }
  function remove(i: number) {
    const next = [...current];
    next.splice(i, 1);
    setRows(next);
  }

  if (isLoading) return <Skeleton className="h-48 w-full" />;

  return (
    <Card>
      <CardContent>
        <div className="mb-3 flex items-center justify-between">
          <p className="text-xs text-[#999]">
            Koppel velden uit de feed aan onze product-velden. Gebruik transforms om data op te schonen.
          </p>
          <Button variant="secondary" size="sm" onClick={add}>
            <Plus className="h-4 w-4" />
            Veld toevoegen
          </Button>
        </div>

        {current.length === 0 ? (
          <p className="text-sm text-[#666] py-4">Nog geen mappings. Voeg er één toe.</p>
        ) : (
          <div className="space-y-2">
            {current.map((m, i) => (
              <div key={i} className="grid grid-cols-12 gap-2 items-center">
                <Input
                  className="col-span-3"
                  placeholder="source field (bv. product_name)"
                  value={m.source_field}
                  onChange={(e) => update(i, { source_field: e.target.value })}
                />
                <Select
                  className="col-span-3"
                  value={m.target_field}
                  onChange={(e) => update(i, { target_field: e.target.value })}
                >
                  {TARGET_FIELDS.map((f) => (
                    <option key={f} value={f}>{f}</option>
                  ))}
                </Select>
                <Select
                  className="col-span-2"
                  value={m.transform ?? ''}
                  onChange={(e) => update(i, { transform: e.target.value || null })}
                >
                  {TRANSFORMS.map((t) => (
                    <option key={t} value={t}>{t || '— geen —'}</option>
                  ))}
                </Select>
                <Input
                  className="col-span-2"
                  placeholder="default"
                  value={m.default_value ?? ''}
                  onChange={(e) => update(i, { default_value: e.target.value || null })}
                />
                <label className="col-span-1 flex items-center gap-1 text-xs text-[#999]">
                  <input
                    type="checkbox"
                    checked={m.is_required}
                    onChange={(e) => update(i, { is_required: e.target.checked })}
                  />
                  req
                </label>
                <Button variant="ghost" size="icon" onClick={() => remove(i)}>
                  <Trash2 className="h-4 w-4 text-[#FF3B3B]" />
                </Button>
              </div>
            ))}
          </div>
        )}

        {rows !== null && (
          <div className="flex gap-2 pt-4 mt-4 border-t border-[#333]">
            <Button onClick={() => saveMut.mutate(current)} disabled={saveMut.isPending}>
              <Save className="h-4 w-4" />
              Mappings opslaan
            </Button>
            <Button variant="ghost" onClick={() => setRows(null)}>Reset</Button>
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function HistoryTab({ feedId }: { feedId: number }) {
  const { data, isLoading } = useQuery({
    queryKey: ['feed-logs', feedId],
    queryFn: () => api.get<{ logs: SyncLog[] }>(`/feeds/${feedId}/logs`),
  });

  if (isLoading) return <Skeleton className="h-48 w-full" />;
  const logs = data?.logs ?? [];

  return (
    <Card>
      {logs.length === 0 ? (
        <CardContent>
          <p className="text-sm text-[#666]">Nog geen sync-geschiedenis.</p>
        </CardContent>
      ) : (
        <Table>
          <THead>
            <TR className="hover:bg-transparent">
              <TH>Start</TH>
              <TH>Status</TH>
              <TH>Duur</TH>
              <TH className="text-right">Fetched</TH>
              <TH className="text-right">Nieuw</TH>
              <TH className="text-right">Updated</TH>
              <TH className="text-right">Removed</TH>
              <TH className="text-right">Errors</TH>
            </TR>
          </THead>
          <TBody>
            {logs.map((l) => (
              <TR key={l.id}>
                <TD className="text-xs text-[#999]">
                  {new Date(l.started_at).toLocaleString('nl-NL')}
                </TD>
                <TD>
                  <Badge variant={l.status === 'success' ? 'success' : l.status === 'failed' ? 'danger' : l.status === 'partial' ? 'warn' : 'info'}>
                    {l.status}
                  </Badge>
                </TD>
                <TD className="text-xs">
                  {l.duration_ms ? `${Math.round(l.duration_ms / 1000)}s` : '—'}
                </TD>
                <TD className="text-right tabular-nums">{l.products_fetched}</TD>
                <TD className="text-right tabular-nums text-[#00FF6A]">{l.products_new}</TD>
                <TD className="text-right tabular-nums">{l.products_updated}</TD>
                <TD className="text-right tabular-nums text-[#999]">{l.products_removed}</TD>
                <TD className="text-right tabular-nums">
                  {l.errors_count > 0 ? (
                    <span className="text-[#FF3B3B]">{l.errors_count}</span>
                  ) : (
                    <span className="text-[#666]">0</span>
                  )}
                </TD>
              </TR>
            ))}
          </TBody>
        </Table>
      )}
    </Card>
  );
}

function TesterTab({ feedId }: { feedId: number }) {
  const [sample, setSample] = useState('');
  const [result, setResult] = useState<{ mapped: Record<string, unknown>; normalized: Record<string, unknown>; missingFields: string[] } | null>(null);

  const testMut = useMutation({
    mutationFn: (body: { sample: Record<string, unknown> }) =>
      api.post<{ mapped: Record<string, unknown>; normalized: Record<string, unknown>; missingFields: string[] }>(`/feeds/${feedId}/test-mapping`, body),
    onSuccess: (data) => setResult(data),
    onError: (e: Error) => toast.error(e.message),
  });

  function run() {
    try {
      const parsed = JSON.parse(sample);
      testMut.mutate({ sample: parsed });
    } catch {
      toast.error('Ongeldige JSON — plak een enkel product-object');
    }
  }

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
      <Card>
        <CardContent>
          <Label>Sample JSON (één product)</Label>
          <Textarea
            className="mt-1 font-mono text-xs"
            rows={16}
            value={sample}
            onChange={(e) => setSample(e.target.value)}
            placeholder={`{\n  "product_name": "Nike Air Max 90",\n  "price": "129.99",\n  "in_stock": "true"\n}`}
          />
          <Button className="mt-3" onClick={run} disabled={testMut.isPending}>
            <Play className="h-4 w-4" />
            Test mapping
          </Button>
        </CardContent>
      </Card>

      <Card>
        <CardContent>
          {result ? (
            <div className="space-y-4">
              {result.missingFields.length > 0 && (
                <div className="text-xs">
                  <p className="text-[#FFA500] mb-1">Ontbrekende velden:</p>
                  <div className="flex flex-wrap gap-1">
                    {result.missingFields.map((f) => (
                      <Badge key={f} variant="warn">{f}</Badge>
                    ))}
                  </div>
                </div>
              )}
              <div>
                <Label>Mapped (na transforms)</Label>
                <pre className="mt-1 p-3 bg-[#0A0A0A] border border-[#333] rounded text-xs text-[#F5F5F5] overflow-auto max-h-64">
                  {JSON.stringify(result.mapped, null, 2)}
                </pre>
              </div>
              <div>
                <Label>Normalized (na brand/size cleanup)</Label>
                <pre className="mt-1 p-3 bg-[#0A0A0A] border border-[#333] rounded text-xs text-[#F5F5F5] overflow-auto max-h-64">
                  {JSON.stringify(result.normalized, null, 2)}
                </pre>
              </div>
            </div>
          ) : (
            <p className="text-sm text-[#666]">Plak een product-object en klik 'Test mapping'.</p>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
