'use client';

import { useCallback, useState } from 'react';

import Link from 'next/link';
import { useRouter, useSearchParams } from 'next/navigation';

import { ArrowRightLeft, Search, Users } from 'lucide-react';
import { useAction } from 'next-safe-action/hooks';
import { useForm } from 'react-hook-form';

import { formatDate } from '@kit/shared/dates';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@kit/ui/dialog';
import { Input } from '@kit/ui/input';
import { Textarea } from '@kit/ui/textarea';
import { useActionWithToast } from '@kit/ui/use-action-with-toast';

import {
  getTransferPreview,
  transferMember,
} from '../server/actions/hierarchy-actions';
import type { CrossOrgMember, TransferPreview } from '../server/api';

const STATUS_LABELS: Record<string, string> = {
  active: 'Aktiv',
  inactive: 'Inaktiv',
  pending: 'Ausstehend',
  resigned: 'Ausgetreten',
  excluded: 'Ausgeschlossen',
  deceased: 'Verstorben',
};

const STATUS_COLORS: Record<string, string> = {
  active: 'default',
  inactive: 'secondary',
  pending: 'outline',
  resigned: 'secondary',
  excluded: 'destructive',
  deceased: 'secondary',
};

interface CrossOrgMemberSearchProps {
  account: string;
  members: CrossOrgMember[];
  total: number;
  page: number;
  pageSize: number;
  childAccounts: Array<{ id: string; name: string }>;
}

export function CrossOrgMemberSearch({
  account,
  members,
  total,
  page,
  pageSize,
  childAccounts,
}: CrossOrgMemberSearchProps) {
  const router = useRouter();
  const searchParams = useSearchParams();

  const [transferTarget, setTransferTarget] = useState<CrossOrgMember | null>(
    null,
  );
  const [targetAccountId, setTargetAccountId] = useState('');
  const [transferReason, setTransferReason] = useState('');
  const [keepSepa, setKeepSepa] = useState(true);
  const [preview, setPreview] = useState<TransferPreview | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);

  const currentSearch = searchParams.get('q') ?? '';
  const currentStatus = searchParams.get('status') ?? '';
  const currentAccount = searchParams.get('accountId') ?? '';

  const totalPages = Math.ceil(total / pageSize);

  const form = useForm({
    defaultValues: { search: currentSearch },
  });

  const { execute: executePreview } = useAction(getTransferPreview, {
    onSuccess: ({ data }) => {
      if (data?.data) setPreview(data.data);
      setPreviewLoading(false);
    },
    onError: () => {
      setPreviewLoading(false);
    },
  });

  const { execute: executeTransfer, isPending: isTransferring } =
    useActionWithToast(transferMember, {
      successMessage: 'Mitglied erfolgreich transferiert',
      errorMessage: 'Fehler beim Transfer',
      onSuccess: () => {
        setTransferTarget(null);
        setTargetAccountId('');
        setTransferReason('');
        setKeepSepa(true);
        setPreview(null);
      },
    });

  const buildUrl = useCallback(
    (params: Record<string, string | number | null>) => {
      const urlSearchParams = new URLSearchParams(searchParams.toString());

      for (const [key, val] of Object.entries(params)) {
        if (val === null || val === '' || val === undefined) {
          urlSearchParams.delete(key);
        } else {
          urlSearchParams.set(key, String(val));
        }
      }

      return `/home/${account}/verband/members?${urlSearchParams.toString()}`;
    },
    [account, searchParams],
  );

  const handleSearch = useCallback(
    (values: { search: string }) => {
      router.push(buildUrl({ q: values.search || null, page: null }));
    },
    [router, buildUrl],
  );

  const handleStatusChange = useCallback(
    (e: React.ChangeEvent<HTMLSelectElement>) => {
      router.push(buildUrl({ status: e.target.value || null, page: null }));
    },
    [router, buildUrl],
  );

  const handleAccountChange = useCallback(
    (e: React.ChangeEvent<HTMLSelectElement>) => {
      router.push(buildUrl({ accountId: e.target.value || null, page: null }));
    },
    [router, buildUrl],
  );

  const handlePageChange = useCallback(
    (newPage: number) => {
      router.push(buildUrl({ page: newPage > 1 ? newPage : null }));
    },
    [router, buildUrl],
  );

  function handleTransferConfirm() {
    if (!transferTarget || !targetAccountId) return;

    executeTransfer({
      memberId: transferTarget.id,
      targetAccountId,
      reason: transferReason || undefined,
      keepSepa,
    });
  }

  // Accounts available as transfer targets (exclude member's current account)
  const transferTargetAccounts = transferTarget
    ? childAccounts.filter((a) => a.id !== transferTarget.account_id)
    : [];

  return (
    <div className="space-y-6">
      {/* Search + Filters */}
      <div className="flex flex-col gap-4 sm:flex-row sm:items-end">
        <form
          onSubmit={form.handleSubmit(handleSearch)}
          className="flex flex-1 gap-2"
        >
          <Input
            placeholder="Name, E-Mail oder Mitgliedsnr. suchen..."
            {...form.register('search')}
            data-test="cross-org-search-input"
          />
          <Button
            type="submit"
            variant="secondary"
            data-test="cross-org-search-btn"
          >
            <Search className="mr-2 h-4 w-4" />
            Suchen
          </Button>
        </form>

        <div className="flex gap-2">
          <select
            value={currentStatus}
            onChange={handleStatusChange}
            className="border-input bg-background flex h-9 rounded-md border px-3 py-1 text-sm shadow-sm"
            data-test="cross-org-status-filter"
          >
            <option value="">Alle Status</option>
            {Object.entries(STATUS_LABELS).map(([val, label]) => (
              <option key={val} value={val}>
                {label}
              </option>
            ))}
          </select>

          {childAccounts.length > 0 && (
            <select
              value={currentAccount}
              onChange={handleAccountChange}
              className="border-input bg-background flex h-9 rounded-md border px-3 py-1 text-sm shadow-sm"
              data-test="cross-org-account-filter"
            >
              <option value="">Alle Organisationen</option>
              {childAccounts.map((childAccount) => (
                <option key={childAccount.id} value={childAccount.id}>
                  {childAccount.name}
                </option>
              ))}
            </select>
          )}
        </div>
      </div>

      {/* Results */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Users className="h-4 w-4" />
            Mitglieder ({total})
          </CardTitle>
        </CardHeader>
        <CardContent>
          {members.length === 0 ? (
            <div className="flex flex-col items-center justify-center rounded-lg border border-dashed p-12 text-center">
              <h3 className="text-lg font-semibold">
                Keine Mitglieder gefunden
              </h3>
              <p className="text-muted-foreground mt-1 max-w-sm text-sm">
                {currentSearch
                  ? 'Versuchen Sie einen anderen Suchbegriff.'
                  : 'In den verknüpften Organisationen sind noch keine Mitglieder vorhanden.'}
              </p>
            </div>
          ) : (
            <div className="rounded-md border">
              <table className="w-full text-sm">
                <thead>
                  <tr className="bg-muted/50 border-b">
                    <th scope="col" className="p-3 text-left font-medium">
                      Name
                    </th>
                    <th scope="col" className="p-3 text-left font-medium">
                      Organisation
                    </th>
                    <th scope="col" className="p-3 text-left font-medium">
                      E-Mail
                    </th>
                    <th scope="col" className="p-3 text-left font-medium">
                      Ort
                    </th>
                    <th scope="col" className="p-3 text-center font-medium">
                      Status
                    </th>
                    <th scope="col" className="p-3 text-left font-medium">
                      Eintritt
                    </th>
                    <th scope="col" className="p-3 text-right font-medium">
                      Aktion
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {members.map((member) => (
                    <tr key={member.id} className="hover:bg-muted/30 border-b">
                      <td className="p-3 font-medium">
                        {member.last_name}, {member.first_name}
                        {member.member_number && (
                          <span className="text-muted-foreground ml-2 text-xs">
                            #{member.member_number}
                          </span>
                        )}
                      </td>
                      <td className="p-3">
                        {member.account_slug ? (
                          <Link
                            href={`/home/${member.account_slug}/members-cms`}
                            className="text-primary hover:underline"
                          >
                            {member.account_name}
                          </Link>
                        ) : (
                          <span>{member.account_name}</span>
                        )}
                      </td>
                      <td className="text-muted-foreground p-3">
                        {member.email ?? '—'}
                      </td>
                      <td className="text-muted-foreground p-3">
                        {member.city ?? '—'}
                      </td>
                      <td className="p-3 text-center">
                        <Badge
                          variant={
                            (STATUS_COLORS[member.status] ?? 'outline') as
                              | 'default'
                              | 'secondary'
                              | 'destructive'
                              | 'outline'
                          }
                        >
                          {STATUS_LABELS[member.status] ?? member.status}
                        </Badge>
                      </td>
                      <td className="text-muted-foreground p-3">
                        {formatDate(member.entry_date)}
                      </td>
                      <td className="p-3 text-right">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            setTransferTarget(member);
                            setTargetAccountId('');
                            setTransferReason('');
                            setPreview(null);
                            setPreviewLoading(true);
                            executePreview({ memberId: member.id });
                          }}
                          title="Mitglied transferieren"
                          data-test="transfer-member-btn"
                        >
                          <ArrowRightLeft className="h-4 w-4" />
                        </Button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}

          {/* Pagination */}
          {totalPages > 1 && (
            <div className="mt-4 flex items-center justify-between">
              <p className="text-muted-foreground text-sm">
                Seite {page} von {totalPages} ({total} Einträge)
              </p>
              <div className="flex gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  disabled={page <= 1}
                  onClick={() => handlePageChange(page - 1)}
                >
                  Zurück
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  disabled={page >= totalPages}
                  onClick={() => handlePageChange(page + 1)}
                >
                  Weiter
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Transfer Dialog */}
      <Dialog
        open={!!transferTarget}
        onOpenChange={(open) => {
          if (!open) setTransferTarget(null);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Mitglied transferieren</DialogTitle>
            <DialogDescription>
              {transferTarget && (
                <>
                  <strong>
                    {transferTarget.first_name} {transferTarget.last_name}
                  </strong>{' '}
                  wird von <strong>{transferTarget.account_name}</strong> in
                  eine andere Organisation verschoben.
                </>
              )}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4 py-4">
            {/* Preview: side effects */}
            {previewLoading && (
              <div className="bg-muted/50 animate-pulse rounded-md p-4 text-center text-sm">
                Lade Transfervorschau...
              </div>
            )}

            {preview && !previewLoading && (
              <div className="space-y-3">
                {/* Active courses */}
                {preview.courses.length > 0 && (
                  <div className="rounded-md border border-blue-200 bg-blue-50 p-3 text-sm dark:border-blue-800 dark:bg-blue-950">
                    <p className="mb-1 font-medium text-blue-800 dark:text-blue-200">
                      {preview.courses.length} aktive Kurseinschreibung(en)
                    </p>
                    <ul className="space-y-1 text-xs text-blue-700 dark:text-blue-300">
                      {preview.courses.map((course) => (
                        <li key={course.id}>
                          {course.name} ({course.accountName})
                          <Badge variant="outline" className="ml-2 text-[10px]">
                            bleibt erhalten
                          </Badge>
                        </li>
                      ))}
                    </ul>
                  </div>
                )}

                {/* Open invoices */}
                {preview.invoices.length > 0 && (
                  <div className="rounded-md border border-amber-200 bg-amber-50 p-3 text-sm dark:border-amber-800 dark:bg-amber-950">
                    <p className="mb-1 font-medium text-amber-800 dark:text-amber-200">
                      {preview.invoices.length} offene Rechnung(en)
                    </p>
                    <ul className="space-y-1 text-xs text-amber-700 dark:text-amber-300">
                      {preview.invoices.map((inv) => (
                        <li key={inv.id}>
                          {inv.invoiceNumber} — {inv.amount.toFixed(2)} EUR (
                          {inv.accountName})
                          <Badge variant="outline" className="ml-2 text-[10px]">
                            verbleibt beim Quellverein
                          </Badge>
                        </li>
                      ))}
                    </ul>
                  </div>
                )}

                {/* SEPA mandates */}
                {preview.mandates.length > 0 && (
                  <div className="rounded-md border border-amber-200 bg-amber-50 p-3 text-sm dark:border-amber-800 dark:bg-amber-950">
                    <p className="mb-1 font-medium text-amber-800 dark:text-amber-200">
                      {preview.mandates.length} aktive(s) SEPA-Mandat(e)
                    </p>
                    <ul className="space-y-1 text-xs text-amber-700 dark:text-amber-300">
                      {preview.mandates.map((mandate) => (
                        <li key={mandate.id}>
                          {mandate.reference} (Status: {mandate.status})
                          <Badge
                            variant="destructive"
                            className="ml-2 text-[10px]"
                          >
                            wird zurückgesetzt
                          </Badge>
                        </li>
                      ))}
                    </ul>
                  </div>
                )}

                {/* Newsletters */}
                {preview.newsletters.length > 0 && (
                  <div className="bg-muted/50 rounded-md border p-3 text-sm">
                    <p className="mb-1 font-medium">
                      {preview.newsletters.length} Newsletter-Abonnement(s)
                    </p>
                    <ul className="text-muted-foreground space-y-1 text-xs">
                      {preview.newsletters.map((newsletter) => (
                        <li key={newsletter.id}>
                          {newsletter.name} ({newsletter.accountName})
                          <Badge variant="outline" className="ml-2 text-[10px]">
                            bleibt erhalten
                          </Badge>
                        </li>
                      ))}
                    </ul>
                  </div>
                )}

                {/* What gets cleared */}
                <div className="bg-muted/50 rounded-md p-3 text-sm">
                  <p className="mb-1 font-medium">Wird zurückgesetzt:</p>
                  <ul className="text-muted-foreground space-y-1 text-xs">
                    {preview.member.memberNumber && (
                      <li>
                        Mitgliedsnr.{' '}
                        <strong>#{preview.member.memberNumber}</strong> —
                        Neuvergabe im Zielverein nötig
                      </li>
                    )}
                    {preview.member.hasDuesCategory && (
                      <li>
                        Beitragskategorie — muss im Zielverein neu zugewiesen
                        werden
                      </li>
                    )}
                    <li>
                      SEPA-Mandatstatus → &quot;ausstehend&quot; (Neubestätigung
                      nötig)
                    </li>
                  </ul>
                </div>

                {/* No side effects */}
                {preview.courses.length === 0 &&
                  preview.invoices.length === 0 &&
                  preview.mandates.length === 0 &&
                  preview.newsletters.length === 0 && (
                    <div className="rounded-md border border-green-200 bg-green-50 p-3 text-sm dark:border-green-800 dark:bg-green-950">
                      <p className="font-medium text-green-800 dark:text-green-200">
                        Keine aktiven Verknüpfungen gefunden
                      </p>
                      <p className="text-xs text-green-700 dark:text-green-300">
                        Transfer kann ohne Seiteneffekte durchgeführt werden.
                      </p>
                    </div>
                  )}
              </div>
            )}

            <div className="space-y-2">
              <label htmlFor="transfer-target" className="text-sm font-medium">
                Zielorganisation
              </label>
              <select
                id="transfer-target"
                value={targetAccountId}
                onChange={(e) => setTargetAccountId(e.target.value)}
                className="border-input bg-background flex h-9 w-full rounded-md border px-3 py-1 text-sm shadow-sm"
                data-test="transfer-target-select"
              >
                <option value="">Organisation auswählen...</option>
                {transferTargetAccounts.map((targetAccount) => (
                  <option key={targetAccount.id} value={targetAccount.id}>
                    {targetAccount.name}
                  </option>
                ))}
              </select>
            </div>

            <div className="space-y-2">
              <label className="flex items-center gap-2 text-sm font-medium">
                <input
                  type="checkbox"
                  checked={keepSepa}
                  onChange={(e) => setKeepSepa(e.target.checked)}
                  className="rounded border-gray-300"
                  data-test="transfer-keep-sepa"
                />
                SEPA-Bankdaten (IBAN/BIC) übernehmen
              </label>
              <p className="text-muted-foreground text-xs">
                Bankverbindung wird übernommen, Mandat muss im Zielverein neu
                bestätigt werden.
              </p>
            </div>

            <div className="space-y-2">
              <label htmlFor="transfer-reason" className="text-sm font-medium">
                Grund (optional)
              </label>
              <Textarea
                id="transfer-reason"
                value={transferReason}
                onChange={(e) => setTransferReason(e.target.value)}
                placeholder="z.B. Umzug, Vereinswechsel..."
                rows={2}
                data-test="transfer-reason-input"
              />
            </div>
          </div>

          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setTransferTarget(null)}
              disabled={isTransferring}
            >
              Abbrechen
            </Button>
            <Button
              onClick={handleTransferConfirm}
              disabled={!targetAccountId || isTransferring}
              data-test="transfer-confirm-btn"
            >
              <ArrowRightLeft className="mr-2 h-4 w-4" />
              {isTransferring ? 'Wird transferiert...' : 'Transferieren'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
