"use client";

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

/**
 * Where we send the store its order updates.
 *
 * The address is checked here only for the mistake a person can see — not https — because the
 * server's rule is far stricter (public host, port 443, nothing on our own network) and is the
 * authority. Whatever it refuses is shown under the field in its own words.
 */
export function WebhookCard({ store }: { store: PortalStore }) {
  const t = useT();
  const queryClient = useQueryClient();
  const saved = store.webhook_url ?? "";

  const [value, setValue] = useState(saved);
  const [error, setError] = useState<string | null>(null);

  const dirty = value.trim() !== saved;

  const save = useMutation({
    mutationFn: (url: string) => updatePortalWebhook(url),
    onSuccess: () => {
      setError(null);
      toast.success(t("portal.integration.webhookSaved"));
      void queryClient.invalidateQueries({ queryKey: queryKeys.portal.settings });
    },
    onError: (failure) => {
      const fields = fieldErrorMap(failure, { only: ["webhook_url"] });
      if (fields.webhook_url) setError(fields.webhook_url);
      else toast.error(friendlyErrorMessage(failure, t));
    },
  });

  const test = useMutation({
    mutationFn: testPortalWebhook,
    onSuccess: () => toast.success(t("portal.integration.webhookTestQueued")),
    onError: (failure) => toast.error(friendlyErrorMessage(failure, t)),
  });

  function submit(event: React.FormEvent) {
    event.preventDefault();
    const url = value.trim();
    if (!/^https:\/\//i.test(url)) {
      setError(t("errors.url"));
      return;
    }
    setError(null);
    save.mutate(url);
  }

  return (
    <Card className="p-5 sm:p-6">
      <h3 className="text-sm font-semibold text-foreground">{t("portal.integration.webhookTitle")}</h3>
      <p className="mt-1 text-xs text-muted-foreground">{t("portal.integration.webhookHint")}</p>

      <form onSubmit={submit} className="mt-4 space-y-3" noValidate>
        <FormField
          label={t("portal.integration.webhookLabel")}
          htmlFor="webhook_url"
          hint={saved === "" ? t("portal.integration.webhookNone") : undefined}
          error={error}
        >
          <Input
            id="webhook_url"
            type="url"
            inputMode="url"
            dir="ltr"
            placeholder="https://your-store.com/kapitano/webhook"
            value={value}
            onChange={(event) => {
              setValue(event.target.value);
              setError(null);
            }}
          />
        </FormField>
        <div className="flex flex-wrap gap-2">
          <Button type="submit" size="sm" loading={save.isPending} disabled={!dirty || value.trim() === ""}>
            {t("common.save")}
          </Button>
          <Button
            type="button"
            size="sm"
            variant="outline"
            loading={test.isPending}
            disabled={saved === "" || dirty}
            title={saved === "" || dirty ? t("portal.integration.webhookSaveFirst") : undefined}
            onClick={() => test.mutate()}
          >
            <Send aria-hidden />
            {t("portal.integration.webhookTest")}
          </Button>
        </div>
      </form>
    </Card>
  );
}
