import React from 'react';
import { useTranslation } from 'react-i18next';

import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';

import type { EventQrInviteLayout } from '../../api';

export type QrLayoutCustomization = {
  layout_id?: string;
  headline?: string;
  subtitle?: string;
  description?: string;
  badge_label?: string;
  instructions_heading?: string;
  instructions?: string[];
  link_heading?: string;
  link_label?: string;
  cta_label?: string;
  accent_color?: string;
  text_color?: string;
  background_color?: string;
  secondary_color?: string;
  badge_color?: string;
  background_gradient?: { angle?: number; stops?: string[] } | null;
  logo_data_url?: string | null;
  logo_url?: string | null;
};

const MAX_INSTRUCTIONS = 5;

type Props = {
  open: boolean;
  onClose: () => void;
  onSubmit: (customization: QrLayoutCustomization) => Promise<void>;
  onReset: () => Promise<void>;
  saving: boolean;
  inviteUrl: string;
  eventName: string;
  layouts: EventQrInviteLayout[];
  initialCustomization: QrLayoutCustomization | null;
};

export function QrInviteCustomizationDialog({
  open,
  onClose,
  onSubmit,
  onReset,
  saving,
  inviteUrl,
  eventName,
  layouts,
  initialCustomization,
}: Props) {
  const { t } = useTranslation('management');
  const [selectedLayoutId, setSelectedLayoutId] = React.useState<string | undefined>();
  const [form, setForm] = React.useState<QrLayoutCustomization>({});
  const [instructions, setInstructions] = React.useState<string[]>([]);
  const [error, setError] = React.useState<string | null>(null);
  const defaultInstructions = React.useMemo(() => {
    const value = t('tasks.customizer.defaults.instructions', { returnObjects: true }) as unknown;
    return Array.isArray(value) ? (value as string[]) : ['QR-Code scannen', 'Profil anlegen', 'Fotos teilen'];
  }, [t]);

  const selectedLayout = React.useMemo(() => {
    if (layouts.length === 0) {
      return undefined;
    }
    const fallback = layouts[0];
    if (!selectedLayoutId) {
      return fallback;
    }
    return layouts.find((layout) => layout.id === selectedLayoutId) ?? fallback;
  }, [layouts, selectedLayoutId]);

  React.useEffect(() => {
    if (!open) {
      return;
    }

    const defaultLayout = initialCustomization?.layout_id
      ? layouts.find((layout) => layout.id === initialCustomization.layout_id)
      : undefined;

    const layout = defaultLayout ?? layouts[0];
    setSelectedLayoutId(layout?.id);

    const nextInstructions = Array.isArray(initialCustomization?.instructions)
      ? initialCustomization!.instructions!
      : [];

    setInstructions(nextInstructions.length > 0 ? nextInstructions : defaultInstructions);

    setForm({
      layout_id: layout?.id,
      headline: initialCustomization?.headline ?? eventName,
      subtitle: initialCustomization?.subtitle ?? layout?.subtitle ?? '',
      description: initialCustomization?.description ?? layout?.description ?? '',
      badge_label: initialCustomization?.badge_label ?? t('tasks.customizer.defaults.badgeLabel'),
      instructions_heading:
        initialCustomization?.instructions_heading ?? t("tasks.customizer.defaults.instructionsHeading"),
      link_heading: initialCustomization?.link_heading ?? t('tasks.customizer.defaults.linkHeading'),
      link_label: initialCustomization?.link_label ?? inviteUrl,
      cta_label: initialCustomization?.cta_label ?? t('tasks.customizer.defaults.ctaLabel'),
      accent_color: initialCustomization?.accent_color ?? layout?.preview?.accent ?? '#6366F1',
      text_color: initialCustomization?.text_color ?? layout?.preview?.text ?? '#111827',
      background_color: initialCustomization?.background_color ?? layout?.preview?.background ?? '#FFFFFF',
      secondary_color: initialCustomization?.secondary_color ?? 'rgba(15,23,42,0.08)',
      badge_color: initialCustomization?.badge_color ?? layout?.preview?.accent ?? '#2563EB',
      background_gradient: initialCustomization?.background_gradient ?? layout?.preview?.background_gradient ?? null,
      logo_data_url: initialCustomization?.logo_data_url ?? initialCustomization?.logo_url ?? null,
    });
    setError(null);
  }, [open, layouts, initialCustomization, inviteUrl, eventName, t]);

  React.useEffect(() => {
    if (!selectedLayout) {
      return;
    }
    setForm((prev) => ({
      ...prev,
      layout_id: selectedLayout.id,
      accent_color: prev.accent_color ?? selectedLayout.preview?.accent ?? '#6366F1',
      text_color: prev.text_color ?? selectedLayout.preview?.text ?? '#111827',
      background_color: prev.background_color ?? selectedLayout.preview?.background ?? '#FFFFFF',
      background_gradient: prev.background_gradient ?? selectedLayout.preview?.background_gradient ?? null,
    }));
  }, [selectedLayout]);

  const handleColorChange = (key: keyof QrLayoutCustomization) =>
    (event: React.ChangeEvent<HTMLInputElement>) => {
      setForm((prev) => ({ ...prev, [key]: event.target.value }));
    };

  const handleInputChange = (key: keyof QrLayoutCustomization) =>
    (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      setForm((prev) => ({ ...prev, [key]: event.target.value }));
    };

  const handleInstructionChange = (index: number, value: string) => {
    setInstructions((prev) => {
      const next = [...prev];
      next[index] = value;
      return next;
    });
  };

  const handleAddInstruction = () => {
    setInstructions((prev) => (prev.length < MAX_INSTRUCTIONS ? [...prev, ''] : prev));
  };

  const handleRemoveInstruction = (index: number) => {
    setInstructions((prev) => prev.filter((_, idx) => idx !== index));
  };

  const handleLogoUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) {
      return;
    }

    if (file.size > 1024 * 1024) {
      setError(t('tasks.customizer.errors.logoTooLarge', 'Das Logo darf maximal 1 MB groß sein.'));
      return;
    }

    const reader = new FileReader();
    reader.onload = () => {
      setForm((prev) => ({ ...prev, logo_data_url: typeof reader.result === 'string' ? reader.result : null }));
      setError(null);
    };
    reader.readAsDataURL(file);
  };

  const handleLogoRemove = () => {
    setForm((prev) => ({ ...prev, logo_data_url: null }));
  };

  const effectiveInstructions = instructions.filter((entry) => entry.trim().length > 0);

  const preview = React.useMemo(() => {
    const backgroundStyle = form.background_gradient?.stops && form.background_gradient.stops.length > 0
      ? `linear-gradient(${form.background_gradient.angle ?? 180}deg, ${form.background_gradient.stops.join(',')})`
      : form.background_color ?? selectedLayout?.preview?.background ?? '#FFFFFF';

    return {
      background: backgroundStyle,
      accent: form.accent_color ?? selectedLayout?.preview?.accent ?? '#6366F1',
      text: form.text_color ?? selectedLayout?.preview?.text ?? '#111827',
      secondary: form.secondary_color ?? 'rgba(15,23,42,0.08)',
    };
  }, [form, selectedLayout]);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!selectedLayout) {
      setError(t('tasks.customizer.errors.noLayout', 'Bitte wähle ein Layout aus.'));
      return;
    }

    setError(null);
    await onSubmit({
      ...form,
      layout_id: selectedLayout.id,
      instructions: effectiveInstructions,
    });
  };

  const handleReset = async () => {
    setError(null);
    await onReset();
  };

  return (
    <Dialog open={open} onOpenChange={(value) => (!value ? onClose() : null)}>
      <DialogContent className="max-w-4xl">
        <DialogHeader>
          <DialogTitle>{t('tasks.customizer.title', 'QR-Einladung anpassen')}</DialogTitle>
          <DialogDescription>{t('tasks.customizer.description', 'Passe Layout, Texte und Farben deiner QR-Einladung an.')}</DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="grid gap-6 md:grid-cols-[2fr,1fr]">
          <div className="space-y-5">
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="qr-layout">{t('tasks.customizer.layout', 'Layout')}</Label>
                <Select
                  value={selectedLayout?.id}
                  onValueChange={(value) => setSelectedLayoutId(value)}
                  disabled={layouts.length === 0 || saving}
                >
                  <SelectTrigger id="qr-layout">
                    <SelectValue placeholder={t('tasks.customizer.selectLayout', 'Layout auswählen')} />
                  </SelectTrigger>
                  <SelectContent>
                    {layouts.map((layout) => (
                      <SelectItem key={layout.id} value={layout.id}>
                        {layout.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label htmlFor="headline">{t('tasks.customizer.headline', 'Überschrift')}</Label>
                <Input
                  id="headline"
                  value={form.headline ?? ''}
                  onChange={handleInputChange('headline')}
                  maxLength={120}
                  disabled={saving}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="subtitle">{t('tasks.customizer.subtitle', 'Unterzeile')}</Label>
                <Input
                  id="subtitle"
                  value={form.subtitle ?? ''}
                  onChange={handleInputChange('subtitle')}
                  maxLength={160}
                  disabled={saving}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="badgeLabel">{t('tasks.customizer.badgeLabel', 'Badge')}</Label>
                <Input
                  id="badgeLabel"
                  value={form.badge_label ?? ''}
                  onChange={handleInputChange('badge_label')}
                  maxLength={80}
                  disabled={saving}
                />
              </div>
            </div>

            <div className="space-y-2">
              <Label htmlFor="description">{t('tasks.customizer.descriptionLabel', 'Beschreibung')}</Label>
              <Textarea
                id="description"
                rows={3}
                value={form.description ?? ''}
                onChange={handleInputChange('description')}
                maxLength={500}
                disabled={saving}
              />
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="instructionsHeading">{t('tasks.customizer.instructionsHeading', "Anleitungstitel")}</Label>
                <Input
                  id="instructionsHeading"
                  value={form.instructions_heading ?? ''}
                  onChange={handleInputChange('instructions_heading')}
                  maxLength={120}
                  disabled={saving}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="ctaLabel">{t('tasks.customizer.ctaLabel', 'CTA')}</Label>
                <Input
                  id="ctaLabel"
                  value={form.cta_label ?? ''}
                  onChange={handleInputChange('cta_label')}
                  maxLength={120}
                  disabled={saving}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="linkHeading">{t('tasks.customizer.linkHeading', 'Link-Titel')}</Label>
                <Input
                  id="linkHeading"
                  value={form.link_heading ?? ''}
                  onChange={handleInputChange('link_heading')}
                  maxLength={120}
                  disabled={saving}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="linkLabel">{t('tasks.customizer.linkLabel', 'Link')}</Label>
                <Input
                  id="linkLabel"
                  value={form.link_label ?? ''}
                  onChange={handleInputChange('link_label')}
                  maxLength={160}
                  disabled={saving}
                />
              </div>
            </div>

            <div className="space-y-2">
              <Label>{t('tasks.customizer.instructionsLabel', 'Hinweise')}</Label>
              <div className="space-y-2">
                {instructions.map((instruction, index) => (
                  <div key={`instruction-${index}`} className="flex items-start gap-2">
                    <Textarea
                      rows={2}
                      value={instruction}
                      onChange={(event) => handleInstructionChange(index, event.target.value)}
                      maxLength={160}
                      disabled={saving}
                    />
                    <Button type="button" variant="outline" onClick={() => handleRemoveInstruction(index)} disabled={saving}>
                      {t('tasks.customizer.removeInstruction', 'Entfernen')}
                    </Button>
                  </div>
                ))}
                <Button
                  type="button"
                  variant="outline"
                  onClick={handleAddInstruction}
                  disabled={instructions.length >= MAX_INSTRUCTIONS || saving}
                >
                  {t('tasks.customizer.addInstruction', 'Hinweis hinzufügen')}
                </Button>
              </div>
            </div>

            <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
              <ColorField
                label={t('tasks.customizer.colors.accent', 'Akzentfarbe')}
                value={form.accent_color ?? '#6366F1'}
                onChange={handleColorChange('accent_color')}
                disabled={saving}
              />
              <ColorField
                label={t('tasks.customizer.colors.text', 'Textfarbe')}
                value={form.text_color ?? '#111827'}
                onChange={handleColorChange('text_color')}
                disabled={saving}
              />
              <ColorField
                label={t('tasks.customizer.colors.background', 'Hintergrund')}
                value={form.background_color ?? '#FFFFFF'}
                onChange={handleColorChange('background_color')}
                disabled={saving}
              />
              <ColorField
                label={t('tasks.customizer.colors.secondary', 'Sekundärfarbe')}
                value={form.secondary_color ?? '#CBD5F5'}
                onChange={handleColorChange('secondary_color')}
                disabled={saving}
              />
              <ColorField
                label={t('tasks.customizer.colors.badge', 'Badge-Farbe')}
                value={form.badge_color ?? '#2563EB'}
                onChange={handleColorChange('badge_color')}
                disabled={saving}
              />
            </div>

            <div className="space-y-2">
              <Label>{t('tasks.customizer.logo.label', 'Logo')}</Label>
              <div className="flex flex-wrap items-center gap-3">
                <Input type="file" accept="image/png,image/jpeg,image/svg+xml" onChange={handleLogoUpload} disabled={saving} />
                {form.logo_data_url ? (
                  <Button type="button" variant="outline" onClick={handleLogoRemove} disabled={saving}>
                    {t('tasks.customizer.logo.remove', 'Logo entfernen')}
                  </Button>
                ) : null}
              </div>
              <p className="text-xs text-muted-foreground">
                {t('tasks.customizer.logo.hint', 'PNG oder SVG, max. 1 MB. Wird oben rechts platziert.')}
              </p>
            </div>
          </div>

          <aside className="space-y-4">
            <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4">
              <h4 className="text-sm font-semibold text-slate-900">
                {t('tasks.customizer.preview.title', 'Vorschau')}
              </h4>
              <p className="text-xs text-slate-600">
                {t('tasks.customizer.preview.hint', 'Farben und Texte, wie sie im Layout erscheinen. Speichere, um neue PDFs/SVGs zu erhalten.')}
              </p>
            </div>
            <div
              className="space-y-3 rounded-3xl border border-slate-200 p-4 text-xs text-slate-700 shadow-sm"
              style={{
                background: preview.background,
                color: preview.text,
              }}
            >
              <div className="flex items-center justify-between gap-3">
                <span className="rounded-full bg-[var(--badge-color,#1f2937)] px-3 py-1 text-[10px] font-semibold uppercase tracking-wide"
                  style={{ background: form.badge_color ?? preview.accent }}
                >
                  {form.badge_label ?? t('tasks.customizer.defaults.badgeLabel')}
                </span>
                {form.logo_data_url ? (
                  <img src={form.logo_data_url} alt="Logo" className="h-12 w-auto object-contain" />
                ) : null}
              </div>
              <div className="space-y-1">
                <p className="text-base font-semibold">{form.headline ?? eventName}</p>
                {form.subtitle ? <p className="text-sm opacity-80">{form.subtitle}</p> : null}
              </div>
              <div className="space-y-1">
                <p className="text-[11px] font-semibold uppercase tracking-wide" style={{ color: preview.accent }}>
                  {form.instructions_heading ?? t('tasks.customizer.defaults.instructionsHeading')}
                </p>
                <ul className="space-y-1 text-xs">
                  {(effectiveInstructions.length > 0 ? effectiveInstructions : defaultInstructions).map((item, index) => (
                    <li key={`preview-instruction-${index}`}>• {item}</li>
                  ))}
                </ul>
              </div>
              <div className="space-y-1">
                <p className="text-[11px] font-semibold uppercase tracking-wide" style={{ color: preview.accent }}>
                  {form.link_heading ?? t('tasks.customizer.defaults.linkHeading')}
                </p>
                <div className="rounded-lg border border-white/40 bg-white/80 p-2 text-[11px]" style={{ color: preview.text }}>
                  {form.link_label ?? inviteUrl}
                </div>
              </div>
              <div className="text-[11px] font-semibold uppercase tracking-wide" style={{ color: preview.accent }}>
                {form.cta_label ?? t('tasks.customizer.defaults.ctaLabel')}
              </div>
            </div>
          </aside>

          <input type="hidden" value={form.layout_id ?? ''} />

          <DialogFooter className="md:col-span-2">
            <div className="flex flex-1 flex-wrap items-center justify-between gap-3">
              <div className="flex items-center gap-3">
                <Button type="button" variant="ghost" onClick={handleReset} disabled={saving}>
                  {t('tasks.customizer.actions.reset', 'Zurücksetzen')}
                </Button>
                <Button type="button" variant="outline" onClick={onClose} disabled={saving}>
                  {t('tasks.customizer.actions.cancel', 'Abbrechen')}
                </Button>
              </div>
              <div className="flex items-center gap-3">
                {error ? <span className="text-sm text-destructive">{error}</span> : null}
                <Button type="submit" disabled={saving}>
                  {t('tasks.customizer.actions.save', 'Speichern')}
                </Button>
              </div>
            </div>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function ColorField({
  label,
  value,
  onChange,
  disabled,
}: {
  label: string;
  value: string;
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
  disabled: boolean;
}) {
  return (
    <div className="space-y-2">
      <Label>{label}</Label>
      <div className="flex items-center gap-2">
        <Input type="color" value={value} onChange={onChange} disabled={disabled} className="h-10 w-14 p-1" />
        <Input value={value} onChange={onChange} disabled={disabled} pattern="^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$" />
      </div>
    </div>
  );
}

export default QrInviteCustomizationDialog;
