'use client';

import { useState, useCallback } from 'react';

import { useRouter } from 'next/navigation';

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 { Input } from '@kit/ui/input';
import { toast } from '@kit/ui/sonner';

import { formatIban } from '../lib/member-utils';
import { createMandate, revokeMandate } from '../server/actions/member-actions';

interface MandateManagerProps {
  mandates: Array<Record<string, unknown>>;
  memberId: string;
  accountId: string;
}

const SEQUENCE_LABELS: Record<string, string> = {
  FRST: 'Erstlastschrift',
  RCUR: 'Wiederkehrend',
  FNAL: 'Letzte',
  OOFF: 'Einmalig',
};

function getMandateStatusColor(
  status: string,
): 'default' | 'secondary' | 'destructive' | 'outline' {
  switch (status) {
    case 'active':
      return 'default';
    case 'pending':
      return 'outline';
    case 'revoked':
    case 'expired':
      return 'destructive';
    default:
      return 'secondary';
  }
}

const MANDATE_STATUS_LABELS: Record<string, string> = {
  active: 'Aktiv',
  pending: 'Ausstehend',
  revoked: 'Widerrufen',
  expired: 'Abgelaufen',
};

interface MandateFormValues {
  mandateReference: string;
  iban: string;
  bic: string;
  accountHolder: string;
  mandateDate: string;
  sequence: string;
}

export function MandateManager({
  mandates,
  memberId,
  accountId,
}: MandateManagerProps) {
  const router = useRouter();
  const [showForm, setShowForm] = useState(false);

  const form = useForm<MandateFormValues>({
    defaultValues: {
      mandateReference: '',
      iban: '',
      bic: '',
      accountHolder: '',
      mandateDate: new Date().toISOString().split('T')[0]!,
      sequence: 'FRST',
    },
  });

  const { execute: executeCreate, isPending: isCreating } = useAction(
    createMandate,
    {
      onSuccess: ({ data }) => {
        if (data?.success) {
          toast.success('SEPA-Mandat erstellt');
          form.reset();
          setShowForm(false);
          router.refresh();
        }
      },
      onError: ({ error }) => {
        toast.error(error.serverError ?? 'Fehler beim Erstellen');
      },
    },
  );

  const { execute: executeRevoke, isPending: isRevoking } = useAction(
    revokeMandate,
    {
      onSuccess: ({ data }) => {
        if (data?.success) {
          toast.success('Mandat widerrufen');
          router.refresh();
        }
      },
      onError: ({ error }) => {
        toast.error(error.serverError ?? 'Fehler beim Widerrufen');
      },
    },
  );

  const handleSubmit = useCallback(
    (values: MandateFormValues) => {
      executeCreate({
        memberId,
        accountId,
        mandateReference: values.mandateReference,
        iban: values.iban,
        bic: values.bic,
        accountHolder: values.accountHolder,
        mandateDate: values.mandateDate,
        sequence: values.sequence as 'FRST' | 'RCUR' | 'FNAL' | 'OOFF',
      });
    },
    [executeCreate, memberId, accountId],
  );

  const handleRevoke = useCallback(
    (mandateId: string, reference: string) => {
      if (!window.confirm(`Mandat "${reference}" wirklich widerrufen?`)) {
        return;
      }
      executeRevoke({ mandateId });
    },
    [executeRevoke],
  );

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold">SEPA-Mandate</h2>
        <Button
          size="sm"
          variant={showForm ? 'outline' : 'default'}
          onClick={() => setShowForm(!showForm)}
        >
          {showForm ? 'Abbrechen' : 'Neues Mandat'}
        </Button>
      </div>

      {/* Inline Create Form */}
      {showForm && (
        <Card>
          <CardHeader>
            <CardTitle>Neues SEPA-Mandat</CardTitle>
          </CardHeader>
          <CardContent>
            <form
              onSubmit={form.handleSubmit(handleSubmit)}
              className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"
            >
              <div className="space-y-1">
                <label className="text-sm font-medium">Mandatsreferenz *</label>
                <Input
                  placeholder="MANDATE-001"
                  {...form.register('mandateReference', { required: true })}
                />
              </div>
              <div className="space-y-1">
                <label className="text-sm font-medium">IBAN *</label>
                <Input
                  placeholder="DE89 3704 0044 0532 0130 00"
                  data-test="mandate-iban-input"
                  {...form.register('iban', { required: true })}
                  onChange={(e) => {
                    const value = e.target.value
                      .toUpperCase()
                      .replace(/[^A-Z0-9]/g, '');
                    form.setValue('iban', value);
                  }}
                />
              </div>
              <div className="space-y-1">
                <label className="text-sm font-medium">BIC</label>
                <Input
                  placeholder="COBADEFFXXX"
                  data-test="mandate-bic-input"
                  {...form.register('bic')}
                />
              </div>
              <div className="space-y-1">
                <label className="text-sm font-medium">Kontoinhaber *</label>
                <Input
                  placeholder="Max Mustermann"
                  data-test="mandate-holder-input"
                  {...form.register('accountHolder', { required: true })}
                />
              </div>
              <div className="space-y-1">
                <label className="text-sm font-medium">Mandatsdatum *</label>
                <Input
                  type="date"
                  {...form.register('mandateDate', { required: true })}
                />
              </div>
              <div className="space-y-1">
                <label className="text-sm font-medium">Sequenz</label>
                <select
                  className="border-input bg-background flex h-10 w-full rounded-md border px-3 py-2 text-sm"
                  {...form.register('sequence')}
                >
                  <option value="FRST">FRST – Erstlastschrift</option>
                  <option value="RCUR">RCUR – Wiederkehrend</option>
                  <option value="FNAL">FNAL – Letzte</option>
                  <option value="OOFF">OOFF – Einmalig</option>
                </select>
              </div>
              <div className="sm:col-span-2 lg:col-span-3">
                <Button
                  type="submit"
                  disabled={isCreating}
                  data-test="mandate-create-btn"
                >
                  {isCreating ? 'Erstelle...' : 'Mandat erstellen'}
                </Button>
              </div>
            </form>
          </CardContent>
        </Card>
      )}

      {/* Table */}
      <div className="rounded-md border">
        <table className="w-full text-sm">
          <thead>
            <tr className="bg-muted/50 border-b">
              <th className="px-4 py-3 text-left font-medium">Referenz</th>
              <th className="px-4 py-3 text-left font-medium">IBAN</th>
              <th className="px-4 py-3 text-left font-medium">Kontoinhaber</th>
              <th className="px-4 py-3 text-left font-medium">Datum</th>
              <th className="px-4 py-3 text-left font-medium">Status</th>
              <th className="px-4 py-3 text-center font-medium">Primär</th>
              <th className="px-4 py-3 text-right font-medium">Aktionen</th>
            </tr>
          </thead>
          <tbody>
            {mandates.length === 0 ? (
              <tr>
                <td
                  colSpan={7}
                  className="text-muted-foreground px-4 py-8 text-center"
                >
                  Keine SEPA-Mandate vorhanden.
                </td>
              </tr>
            ) : (
              mandates.map((mandate) => {
                const mandateId = String(mandate.id ?? '');
                const reference = String(mandate.mandate_reference ?? '—');
                const mandateStatus = String(mandate.status ?? 'pending');
                const isPrimary = Boolean(mandate.is_primary);
                const canRevoke =
                  mandateStatus === 'active' || mandateStatus === 'pending';

                return (
                  <tr key={mandateId} className="border-b">
                    <td className="px-4 py-3 font-mono text-xs">{reference}</td>
                    <td className="px-4 py-3 font-mono text-xs">
                      {formatIban(mandate.iban as string | null | undefined)}
                    </td>
                    <td className="px-4 py-3">
                      {String(mandate.account_holder ?? '—')}
                    </td>
                    <td className="text-muted-foreground px-4 py-3">
                      {formatDate(mandate.mandate_date as string)}
                    </td>
                    <td className="px-4 py-3">
                      <Badge variant={getMandateStatusColor(mandateStatus)}>
                        {MANDATE_STATUS_LABELS[mandateStatus] ?? mandateStatus}
                      </Badge>
                    </td>
                    <td className="px-4 py-3 text-center">
                      {isPrimary ? '✓' : '✗'}
                    </td>
                    <td className="px-4 py-3 text-right">
                      {canRevoke && (
                        <Button
                          size="sm"
                          variant="destructive"
                          disabled={isRevoking}
                          data-test="mandate-revoke-btn"
                          onClick={() => handleRevoke(mandateId, reference)}
                        >
                          Widerrufen
                        </Button>
                      )}
                    </td>
                  </tr>
                );
              })
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
