import { useState, useEffect, useCallback, useRef } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import api from '../api/client';

/** Hook: Favicon-URL ueber Backend-Proxy laden */
function useFavicon(url: string): string | null {
  const [faviconUrl, setFaviconUrl] = useState<string | null>(null);

  const fetchFavicon = useCallback(async () => {
    if (!url || url.length < 8) {
      setFaviconUrl(null);
      return;
    }
    try {
      new URL(url); // Validierung
      const res = await api.get<{ faviconUrl: string | null }>(
        `/settings/favicon?url=${encodeURIComponent(url)}`,
      );
      setFaviconUrl(res.data.faviconUrl);
    } catch {
      setFaviconUrl(null);
    }
  }, [url]);

  useEffect(() => {
    // Debounce: nur ausfuehren wenn URL sich 500ms nicht geaendert hat
    const timer = setTimeout(fetchFavicon, 500);
    return () => clearTimeout(timer);
  }, [fetchFavicon]);

  return faviconUrl;
}

/** Einfache ID-Generierung (crypto.randomUUID ist nur ueber HTTPS verfuegbar) */
function generateId(): string {
  return Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
}


interface ExternalLink {
  id: string;
  label: string;
  url: string;
  sortOrder: number;
  customIcon?: string;
}

const cardStyle: React.CSSProperties = {
  background: 'var(--color-bg-card)',
  borderRadius: 'var(--radius-md)',
  boxShadow: 'var(--shadow-sm)',
  border: '1px solid var(--color-border)',
  padding: '1.5rem',
  marginBottom: '1.5rem',
};

const inputStyle: React.CSSProperties = {
  width: '100%',
  padding: '0.5rem 0.75rem',
  fontSize: '0.875rem',
  border: '1px solid var(--color-border)',
  borderRadius: 'var(--radius-sm)',
  background: 'var(--color-bg-card)',
  color: 'var(--color-text)',
  outline: 'none',
  boxSizing: 'border-box' as const,
};

const labelStyle: React.CSSProperties = {
  display: 'block',
  fontSize: '0.75rem',
  fontWeight: 600,
  color: 'var(--color-text-secondary)',
  marginBottom: '0.25rem',
  textTransform: 'uppercase' as const,
  letterSpacing: '0.5px',
};

const btnPrimary: React.CSSProperties = {
  padding: '0.5rem 1.25rem',
  background: 'var(--color-primary)',
  color: 'white',
  border: 'none',
  borderRadius: 'var(--radius-sm)',
  fontSize: '0.875rem',
  fontWeight: 600,
  cursor: 'pointer',
};

const btnSecondary: React.CSSProperties = {
  padding: '0.375rem 0.75rem',
  background: 'none',
  color: 'var(--color-text-secondary)',
  border: '1px solid var(--color-border)',
  borderRadius: 'var(--radius-sm)',
  fontSize: '0.8125rem',
  cursor: 'pointer',
};

function LinkRow({
  link,
  onChange,
  onRemove,
  onMoveUp,
  onMoveDown,
  isFirst,
  isLast,
}: {
  link: ExternalLink;
  onChange: (updated: ExternalLink) => void;
  onRemove: () => void;
  onMoveUp: () => void;
  onMoveDown: () => void;
  isFirst: boolean;
  isLast: boolean;
}) {
  const faviconUrl = useFavicon(link.url);
  const iconInputRef = useRef<HTMLInputElement>(null);

  const handleIconUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (!file.type.startsWith('image/')) return;
    if (file.size > 100_000) {
      alert('Icon darf maximal 100KB gross sein');
      return;
    }
    const reader = new FileReader();
    reader.onload = () => {
      onChange({ ...link, customIcon: reader.result as string });
    };
    reader.readAsDataURL(file);
  };

  const iconSrc = link.customIcon || faviconUrl;

  return (
    <div
      style={{
        display: 'grid',
        gridTemplateColumns: '40px 1fr 1.5fr 80px auto',
        gap: '0.75rem',
        alignItems: 'end',
        padding: '1rem 0',
        borderBottom: '1px solid var(--color-border)',
      }}
    >
      {/* Icon-Vorschau (klickbar fuer Upload) */}
      <div>
        <label style={labelStyle}>Icon</label>
        <input
          ref={iconInputRef}
          type="file"
          accept="image/*"
          style={{ display: 'none' }}
          onChange={handleIconUpload}
        />
        <div
          style={{
            width: 36,
            height: 36,
            borderRadius: 'var(--radius-sm)',
            border: '1px solid var(--color-border)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            overflow: 'hidden',
            background: 'var(--color-bg)',
            cursor: 'pointer',
            position: 'relative',
          }}
          onClick={() => iconInputRef.current?.click()}
          title="Klicken zum Icon hochladen"
        >
          {iconSrc ? (
            <img
              src={iconSrc}
              alt=""
              style={{ width: 20, height: 20, objectFit: 'contain' }}
              onError={(e) => {
                (e.target as HTMLImageElement).style.display = 'none';
              }}
            />
          ) : (
            <svg
              width="16"
              height="16"
              viewBox="0 0 16 16"
              fill="none"
              stroke="var(--color-text-muted)"
              strokeWidth="1.5"
            >
              <circle cx="8" cy="8" r="6" />
              <path d="M2 8h12M8 2a10 10 0 014 6 10 10 0 01-4 6 10 10 0 01-4-6 10 10 0 014-6z" />
            </svg>
          )}
          {link.customIcon && (
            <button
              onClick={(e) => {
                e.stopPropagation();
                onChange({ ...link, customIcon: undefined });
              }}
              style={{
                position: 'absolute',
                top: -4,
                right: -4,
                width: 14,
                height: 14,
                borderRadius: '50%',
                background: 'var(--color-error)',
                color: 'white',
                border: 'none',
                fontSize: '0.5rem',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                cursor: 'pointer',
                lineHeight: 1,
              }}
              title="Eigenes Icon entfernen"
            >
              x
            </button>
          )}
        </div>
      </div>

      {/* Label */}
      <div>
        <label style={labelStyle}>Bezeichnung *</label>
        <input
          type="text"
          value={link.label}
          onChange={(e) => onChange({ ...link, label: e.target.value })}
          placeholder="z.B. Jira, Confluence"
          style={inputStyle}
        />
      </div>

      {/* URL */}
      <div>
        <label style={labelStyle}>URL *</label>
        <input
          type="text"
          value={link.url}
          onChange={(e) => onChange({ ...link, url: e.target.value })}
          placeholder="https://..."
          style={inputStyle}
        />
      </div>

      {/* Reihenfolge */}
      <div
        style={{
          display: 'flex',
          gap: '0.25rem',
          paddingBottom: '0.25rem',
        }}
      >
        <button
          onClick={onMoveUp}
          disabled={isFirst}
          style={{
            ...btnSecondary,
            padding: '0.25rem 0.5rem',
            opacity: isFirst ? 0.3 : 1,
          }}
          title="Nach oben"
        >
          <svg
            width="14"
            height="14"
            viewBox="0 0 14 14"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
          >
            <path d="M7 11V3M3 7l4-4 4 4" />
          </svg>
        </button>
        <button
          onClick={onMoveDown}
          disabled={isLast}
          style={{
            ...btnSecondary,
            padding: '0.25rem 0.5rem',
            opacity: isLast ? 0.3 : 1,
          }}
          title="Nach unten"
        >
          <svg
            width="14"
            height="14"
            viewBox="0 0 14 14"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
          >
            <path d="M7 3v8M3 7l4 4 4-4" />
          </svg>
        </button>
      </div>

      {/* Entfernen */}
      <button
        onClick={onRemove}
        style={{
          ...btnSecondary,
          color: 'var(--color-error)',
          borderColor: 'transparent',
          padding: '0.25rem 0.5rem',
        }}
        title="Entfernen"
      >
        <svg
          width="16"
          height="16"
          viewBox="0 0 16 16"
          fill="none"
          stroke="currentColor"
          strokeWidth="1.5"
        >
          <path d="M4 4l8 8M12 4l-8 8" />
        </svg>
      </button>
    </div>
  );
}

export function AdminExternalLinksPage() {
  const queryClient = useQueryClient();
  const [links, setLinks] = useState<ExternalLink[]>([]);
  const [hasChanges, setHasChanges] = useState(false);
  const [saveSuccess, setSaveSuccess] = useState(false);

  const { data, isLoading } = useQuery<ExternalLink[]>({
    queryKey: ['settings', 'external-links'],
    queryFn: async () => {
      const res = await api.get<ExternalLink[]>('/settings/external-links');
      return res.data;
    },
  });

  useEffect(() => {
    if (data) {
      setLinks(data);
      setHasChanges(false);
    }
  }, [data]);

  const saveMutation = useMutation({
    mutationFn: async (linksToSave: ExternalLink[]) => {
      const res = await api.post('/settings/external-links', {
        links: linksToSave,
      });
      return res.data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: ['settings', 'external-links'],
      });
      setHasChanges(false);
      setSaveSuccess(true);
      setTimeout(() => setSaveSuccess(false), 3000);
    },
  });

  const addLink = () => {
    setLinks((prev) => [
      ...prev,
      {
        id: generateId(),
        label: '',
        url: '',
        sortOrder: prev.length,
      },
    ]);
    setHasChanges(true);
  };

  const updateLink = (index: number, updated: ExternalLink) => {
    setLinks((prev) => prev.map((l, i) => (i === index ? updated : l)));
    setHasChanges(true);
  };

  const removeLink = (index: number) => {
    setLinks((prev) => prev.filter((_, i) => i !== index));
    setHasChanges(true);
  };

  const moveLink = (index: number, direction: -1 | 1) => {
    const newIndex = index + direction;
    if (newIndex < 0 || newIndex >= links.length) return;

    setLinks((prev) => {
      const updated = [...prev];
      const temp = updated[index];
      updated[index] = updated[newIndex];
      updated[newIndex] = temp;
      return updated.map((l, i) => ({ ...l, sortOrder: i }));
    });
    setHasChanges(true);
  };

  const handleSave = () => {
    const valid = links.every((l) => l.label.trim() && l.url.trim());
    if (!valid) {
      alert('Bitte Bezeichnung und URL fuer alle Links ausfuellen');
      return;
    }
    saveMutation.mutate(links);
  };

  if (isLoading) {
    return <p style={{ color: 'var(--color-text-secondary)' }}>Laden...</p>;
  }

  return (
    <div>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginBottom: '1.5rem',
        }}
      >
        <div>
          <h1 style={{ fontSize: '1.5rem', fontWeight: 600 }}>
            Externe Links
          </h1>
          <p
            style={{
              fontSize: '0.875rem',
              color: 'var(--color-text-secondary)',
              marginTop: '0.25rem',
            }}
          >
            Links zu externen Anwendungen, die in der Sidebar fuer alle Benutzer
            angezeigt werden. Das Icon wird automatisch von der Webseite geladen.
          </p>
        </div>
      </div>

      <div style={cardStyle}>
        {links.length === 0 ? (
          <div
            style={{
              padding: '2rem',
              textAlign: 'center',
              color: 'var(--color-text-muted)',
            }}
          >
            <svg
              width="48"
              height="48"
              viewBox="0 0 48 48"
              fill="none"
              stroke="currentColor"
              strokeWidth="1.5"
              style={{ margin: '0 auto 1rem' }}
            >
              <rect x="8" y="8" width="32" height="32" rx="4" />
              <path d="M20 24h8M24 20v8" />
            </svg>
            <p style={{ fontSize: '0.875rem' }}>
              Noch keine externen Links konfiguriert.
            </p>
            <p
              style={{
                fontSize: '0.8125rem',
                color: 'var(--color-text-muted)',
                marginTop: '0.25rem',
              }}
            >
              Klicke auf &ldquo;Link hinzufuegen&rdquo; um einen externen Link
              zur Sidebar hinzuzufuegen.
            </p>
          </div>
        ) : (
          <div>
            {links.map((link, index) => (
              <LinkRow
                key={link.id}
                link={link}
                onChange={(updated) => updateLink(index, updated)}
                onRemove={() => removeLink(index)}
                onMoveUp={() => moveLink(index, -1)}
                onMoveDown={() => moveLink(index, 1)}
                isFirst={index === 0}
                isLast={index === links.length - 1}
              />
            ))}
          </div>
        )}

        {/* Aktionen */}
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            marginTop: '1.25rem',
            paddingTop: links.length > 0 ? '0.5rem' : 0,
          }}
        >
          <button
            onClick={addLink}
            style={{
              ...btnSecondary,
              display: 'flex',
              alignItems: 'center',
              gap: '0.375rem',
            }}
          >
            <svg
              width="14"
              height="14"
              viewBox="0 0 14 14"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
            >
              <path d="M7 2v10M2 7h10" />
            </svg>
            Link hinzufuegen
          </button>

          <div
            style={{
              display: 'flex',
              alignItems: 'center',
              gap: '0.75rem',
            }}
          >
            {saveSuccess && (
              <span
                style={{
                  fontSize: '0.8125rem',
                  color: '#166534',
                  fontWeight: 500,
                }}
              >
                Gespeichert!
              </span>
            )}

            {saveMutation.isError && (
              <span
                style={{
                  fontSize: '0.8125rem',
                  color: 'var(--color-error)',
                }}
              >
                Fehler beim Speichern
              </span>
            )}

            <button
              onClick={handleSave}
              disabled={!hasChanges || saveMutation.isPending}
              style={{
                ...btnPrimary,
                opacity: hasChanges ? 1 : 0.5,
                cursor: hasChanges ? 'pointer' : 'not-allowed',
              }}
            >
              {saveMutation.isPending ? 'Speichern...' : 'Speichern'}
            </button>
          </div>
        </div>
      </div>

      {/* Hinweis */}
      <div
        style={{
          padding: '1rem 1.25rem',
          background: 'color-mix(in srgb, var(--color-primary) 8%, var(--color-bg-card))',
          border: '1px solid color-mix(in srgb, var(--color-primary) 25%, transparent)',
          borderRadius: 'var(--radius-sm)',
          fontSize: '0.8125rem',
          color: 'var(--color-primary)',
        }}
      >
        <strong>Hinweis:</strong> Das Icon wird automatisch als Favicon der
        jeweiligen Webseite geladen. Optional kann ein eigenes Icon hochgeladen
        werden (Klick auf das Icon-Feld). Gib eine vollstaendige URL inkl.{' '}
        <code
          style={{
            background: 'color-mix(in srgb, var(--color-primary) 15%, transparent)',
            padding: '0.125rem 0.25rem',
            borderRadius: 2,
          }}
        >
          https://
        </code>{' '}
        ein.
      </div>
    </div>
  );
}
