'use client';

import { useState, useCallback } from 'react';

import { useRouter } from 'next/navigation';

import {
  Upload,
  ArrowRight,
  ArrowLeft,
  CheckCircle,
  AlertTriangle,
} from 'lucide-react';
import { useAction } from 'next-safe-action/hooks';
import Papa from 'papaparse';

import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import { toast } from '@kit/ui/sonner';

import { createMember } from '../server/actions/member-actions';

const MEMBER_FIELDS = [
  { key: 'memberNumber', label: 'Mitgliedsnr.' },
  { key: 'salutation', label: 'Anrede' },
  { key: 'firstName', label: 'Vorname' },
  { key: 'lastName', label: 'Nachname' },
  { key: 'dateOfBirth', label: 'Geburtsdatum' },
  { key: 'email', label: 'E-Mail' },
  { key: 'phone', label: 'Telefon' },
  { key: 'mobile', label: 'Mobil' },
  { key: 'street', label: 'Straße' },
  { key: 'houseNumber', label: 'Hausnummer' },
  { key: 'postalCode', label: 'PLZ' },
  { key: 'city', label: 'Ort' },
  { key: 'entryDate', label: 'Eintrittsdatum' },
  { key: 'iban', label: 'IBAN' },
  { key: 'bic', label: 'BIC' },
  { key: 'accountHolder', label: 'Kontoinhaber' },
  { key: 'notes', label: 'Notizen' },
] as const;

interface Props {
  accountId: string;
  account: string;
}

type Step = 'upload' | 'mapping' | 'preview' | 'importing' | 'done';

export function MemberImportWizard({ accountId, account }: Props) {
  const router = useRouter();
  const [step, setStep] = useState<Step>('upload');
  const [rawData, setRawData] = useState<string[][]>([]);
  const [headers, setHeaders] = useState<string[]>([]);
  const [mapping, setMapping] = useState<Record<string, string>>({});
  const [importResults, setImportResults] = useState<{
    success: number;
    errors: string[];
  }>({ success: 0, errors: [] });

  const { execute: executeCreate } = useAction(createMember);

  // Step 1: Parse file
  const handleFileUpload = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (!file) return;

      Papa.parse(file, {
        delimiter: ';',
        encoding: 'UTF-8',
        complete: (result) => {
          const data = result.data as string[][];
          if (data.length < 2) {
            toast.error('Datei enthält keine Daten');
            return;
          }
          setHeaders(data[0]!);
          setRawData(
            data.slice(1).filter((row) => row.some((cell) => cell?.trim())),
          );

          // Auto-map by header name similarity
          const autoMap: Record<string, string> = {};
          for (const field of MEMBER_FIELDS) {
            const match = data[0]!.findIndex(
              (h) =>
                h
                  .toLowerCase()
                  .includes(field.label.toLowerCase().replace('.', '')) ||
                h.toLowerCase().includes(field.key.toLowerCase()),
            );
            if (match >= 0) autoMap[field.key] = String(match);
          }
          setMapping(autoMap);
          setStep('mapping');
          toast.success(`${data.length - 1} Zeilen erkannt`);
        },
        error: (err) => {
          toast.error(`Fehler beim Lesen: ${err.message}`);
        },
      });
    },
    [],
  );

  // Step 3: Execute import
  const executeImport = useCallback(async () => {
    setStep('importing');
    let success = 0;
    const errors: string[] = [];

    for (let i = 0; i < rawData.length; i++) {
      const row = rawData[i]!;
      try {
        const memberData: Record<string, string> = { accountId };
        for (const field of MEMBER_FIELDS) {
          const colIdx = mapping[field.key];
          if (colIdx !== undefined && row[Number(colIdx)]) {
            memberData[field.key] = row[Number(colIdx)]!.trim();
          }
        }

        if (!memberData.firstName || !memberData.lastName) {
          errors.push(`Zeile ${i + 2}: Vor-/Nachname fehlt`);
          continue;
        }

        await executeCreate(memberData as any);
        success++;
      } catch (err) {
        errors.push(
          `Zeile ${i + 2}: ${err instanceof Error ? err.message : 'Unbekannter Fehler'}`,
        );
      }
    }

    setImportResults({ success, errors });
    setStep('done');
    toast.success(`${success} Mitglieder importiert`);
  }, [rawData, mapping, accountId, executeCreate]);

  const getMappedValue = (rowIdx: number, fieldKey: string): string => {
    const colIdx = mapping[fieldKey];
    if (colIdx === undefined) return '';
    return rawData[rowIdx]?.[Number(colIdx)]?.trim() ?? '';
  };

  return (
    <div className="space-y-6">
      {/* Step indicator */}
      <div className="flex items-center justify-center gap-2">
        {(['upload', 'mapping', 'preview', 'done'] as const).map((s, i) => {
          const labels = [
            'Datei hochladen',
            'Spalten zuordnen',
            'Vorschau & Import',
            'Fertig',
          ];
          const isActive =
            ['upload', 'mapping', 'preview', 'importing', 'done'].indexOf(
              step,
            ) >= i;
          return (
            <div key={s} className="flex items-center gap-2">
              <div
                className={`flex h-8 w-8 items-center justify-center rounded-full text-xs font-bold ${
                  isActive
                    ? 'bg-primary text-primary-foreground'
                    : 'bg-muted text-muted-foreground'
                }`}
              >
                {i + 1}
              </div>
              <span
                className={`text-sm ${isActive ? 'font-semibold' : 'text-muted-foreground'}`}
              >
                {labels[i]}
              </span>
              {i < 3 && (
                <ArrowRight className="text-muted-foreground h-4 w-4" />
              )}
            </div>
          );
        })}
      </div>

      {/* Step 1: Upload */}
      {step === 'upload' && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Upload className="h-4 w-4" />
              Datei hochladen
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-12 text-center">
              <Upload className="text-muted-foreground mb-4 h-10 w-10" />
              <p className="text-lg font-semibold">CSV-Datei auswählen</p>
              <p className="text-muted-foreground mt-1 text-sm">
                Semikolon-getrennt (;), UTF-8
              </p>
              <input
                type="file"
                accept=".csv"
                onChange={handleFileUpload}
                className="file:bg-primary file:text-primary-foreground mt-4 block w-full max-w-xs text-sm file:mr-4 file:rounded-md file:border-0 file:px-4 file:py-2 file:text-sm file:font-semibold"
              />
            </div>
          </CardContent>
        </Card>
      )}

      {/* Step 2: Column mapping */}
      {step === 'mapping' && (
        <Card>
          <CardHeader>
            <CardTitle>Spalten zuordnen</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-muted-foreground mb-4 text-sm">
              {rawData.length} Zeilen erkannt. Ordnen Sie die CSV-Spalten den
              Mitgliedsfeldern zu.
            </p>
            <div className="space-y-2">
              {MEMBER_FIELDS.map((field) => (
                <div key={field.key} className="flex items-center gap-4">
                  <span className="w-40 text-sm font-medium">
                    {field.label}
                  </span>
                  <span className="text-muted-foreground">→</span>
                  <select
                    value={mapping[field.key] ?? ''}
                    onChange={(e) =>
                      setMapping((prev) => ({
                        ...prev,
                        [field.key]: e.target.value,
                      }))
                    }
                    className="border-input bg-background flex h-9 w-64 rounded-md border px-3 py-1 text-sm"
                  >
                    <option value="">— Nicht zuordnen —</option>
                    {headers.map((h, i) => (
                      <option key={i} value={String(i)}>
                        {h}
                      </option>
                    ))}
                  </select>
                  {mapping[field.key] !== undefined && rawData[0] && (
                    <span className="text-muted-foreground text-xs">
                      z.B. &quot;{rawData[0][Number(mapping[field.key])]}&quot;
                    </span>
                  )}
                </div>
              ))}
            </div>
            <div className="mt-6 flex justify-between">
              <Button variant="outline" onClick={() => setStep('upload')}>
                <ArrowLeft className="mr-2 h-4 w-4" />
                Zurück
              </Button>
              <Button onClick={() => setStep('preview')}>
                Vorschau <ArrowRight className="ml-2 h-4 w-4" />
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Step 3: Preview + execute */}
      {step === 'preview' && (
        <Card>
          <CardHeader>
            <CardTitle>Vorschau ({rawData.length} Einträge)</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="max-h-96 overflow-auto rounded-md border">
              <table className="w-full text-xs">
                <thead>
                  <tr className="bg-muted/50 border-b">
                    <th scope="col" className="p-2 text-left">
                      #
                    </th>
                    {MEMBER_FIELDS.filter(
                      (f) => mapping[f.key] !== undefined,
                    ).map((f) => (
                      <th key={f.key} className="p-2 text-left">
                        {f.label}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {rawData.slice(0, 20).map((_, i) => {
                    const hasName =
                      getMappedValue(i, 'firstName') &&
                      getMappedValue(i, 'lastName');
                    return (
                      <tr
                        key={i}
                        className={`border-b ${hasName ? '' : 'bg-red-50 dark:bg-red-950'}`}
                      >
                        <td className="p-2">
                          {i + 1}{' '}
                          {!hasName && (
                            <AlertTriangle className="text-destructive inline h-3 w-3" />
                          )}
                        </td>
                        {MEMBER_FIELDS.filter(
                          (f) => mapping[f.key] !== undefined,
                        ).map((f) => (
                          <td key={f.key} className="max-w-32 truncate p-2">
                            {getMappedValue(i, f.key) || '—'}
                          </td>
                        ))}
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
            {rawData.length > 20 && (
              <p className="text-muted-foreground mt-2 text-xs">
                ... und {rawData.length - 20} weitere Einträge
              </p>
            )}
            <div className="mt-6 flex justify-between">
              <Button variant="outline" onClick={() => setStep('mapping')}>
                <ArrowLeft className="mr-2 h-4 w-4" />
                Zurück
              </Button>
              <Button onClick={executeImport}>
                <CheckCircle className="mr-2 h-4 w-4" />
                {rawData.length} Mitglieder importieren
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Importing */}
      {step === 'importing' && (
        <Card>
          <CardContent className="flex flex-col items-center justify-center p-12">
            <div className="border-primary h-8 w-8 animate-spin rounded-full border-4 border-t-transparent" />
            <p className="mt-4 text-lg font-semibold">
              Importiere Mitglieder...
            </p>
            <p className="text-muted-foreground text-sm">
              Bitte warten Sie, bis der Import abgeschlossen ist.
            </p>
          </CardContent>
        </Card>
      )}

      {/* Done */}
      {step === 'done' && (
        <Card>
          <CardContent className="p-8 text-center">
            <CheckCircle className="mx-auto h-12 w-12 text-green-500" />
            <h3 className="mt-4 text-xl font-semibold">Import abgeschlossen</h3>
            <div className="mt-4 flex justify-center gap-4">
              <Badge variant="default">
                {importResults.success} erfolgreich
              </Badge>
              {importResults.errors.length > 0 && (
                <Badge variant="destructive">
                  {importResults.errors.length} Fehler
                </Badge>
              )}
            </div>
            {importResults.errors.length > 0 && (
              <div className="mt-4 max-h-40 overflow-auto rounded-md border p-3 text-left text-xs">
                {importResults.errors.map((err, i) => (
                  <p key={i} className="text-destructive">
                    {err}
                  </p>
                ))}
              </div>
            )}
            <div className="mt-6">
              <Button
                onClick={() => router.push(`/home/${account}/members-cms`)}
              >
                Zur Mitgliederliste
              </Button>
            </div>
          </CardContent>
        </Card>
      )}
    </div>
  );
}
