"use client";

import { useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { FormField } from "@/components/ui/form-field";
import { Textarea } from "@/components/ui/input";
import { useT } from "@/i18n";
import { fieldErrorMap, friendlyErrorMessage } from "@/lib/errors";
import { queryKeys } from "@/lib/query-keys";
import { updatePortalAllowedIps } from "@/services/portal";
import type { PortalStore } from "@/types/portal";

/** One address per line, commas tolerated, blanks and repeats dropped. */
function parseAddresses(text: string): string[] {
  return [...new Set(text.split(/[\s,]+/).map((line) => line.trim()).filter(Boolean))];
}

/**
 * Which addresses may call our API for this store.
 *
 * Empty means "any address", which is the safe default for a shop still setting up and the wrong
 * one for a shop in production — so the card states plainly which of the two it is in rather than
 * leaving an empty box to be read either way.
 */
export function AllowedIpsCard({ store }: { store: PortalStore }) {
  const t = useT();
  const queryClient = useQueryClient();
  const saved = store.allowed_ips;

  const [text, setText] = useState(saved.join("\n"));
  const [error, setError] = useState<string | null>(null);

  const parsed = parseAddresses(text);
  const dirty = parsed.join("\n") !== saved.join("\n");

  const save = useMutation({
    mutationFn: (ips: string[]) => updatePortalAllowedIps(ips),
    onSuccess: () => {
      setError(null);
      toast.success(t("portal.integration.ipsSaved"));
      void queryClient.invalidateQueries({ queryKey: queryKeys.portal.settings });
    },
    onError: (failure) => {
      // `allowed_ips.2` is about one line of the one textarea, so it collapses onto the field.
      const fields = fieldErrorMap(failure, { only: ["allowed_ips"], collapse: ["allowed_ips"] });
      if (fields.allowed_ips) setError(fields.allowed_ips);
      else toast.error(friendlyErrorMessage(failure, t));
    },
  });

  return (
    <Card className="p-5 sm:p-6">
      <div className="flex items-start justify-between gap-3">
        <div>
          <h3 className="text-sm font-semibold text-foreground">{t("portal.integration.ipsTitle")}</h3>
          <p className="mt-1 text-xs text-muted-foreground">{t("portal.integration.ipsHint")}</p>
        </div>
        {saved.length > 0 ? (
          <Badge variant="primary">{t("portal.integration.ipsCount", { count: saved.length })}</Badge>
        ) : null}
      </div>

      <form
        onSubmit={(event) => {
          event.preventDefault();
          save.mutate(parsed);
        }}
        className="mt-4 space-y-3"
        noValidate
      >
        <FormField
          label={t("portal.integration.ipsLabel")}
          htmlFor="allowed_ips"
          hint={parsed.length === 0 ? t("portal.integration.ipsAny") : undefined}
          error={error}
        >
          <Textarea
            id="allowed_ips"
            dir="ltr"
            rows={4}
            spellCheck={false}
            placeholder={"203.0.113.10\n203.0.113.11"}
            value={text}
            onChange={(event) => {
              setText(event.target.value);
              setError(null);
            }}
          />
        </FormField>
        <Button type="submit" size="sm" loading={save.isPending} disabled={!dirty}>
          {t("common.save")}
        </Button>
      </form>
    </Card>
  );
}
