"use client";
import { api } from "~/utils/api";
import { useState, type FormEvent } from "react";
import {
  Elements,
  PaymentElement,
  useElements,
  useStripe,
} from "@stripe/react-stripe-js";
import { LoadingPage } from "~/components/loading";
import { Status500 } from "~/components/status-page";
import LoadingButton from "~/components/custom_ui/loading-button";
import { useTranslation } from "~/providers/I18nProvider";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import type { Stripe } from "@stripe/stripe-js";
import { formatCurrency } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import type { PaymentsId } from "~/schemas/public/Payments";
import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario";
import { ArrowRight, ExternalLink } from "lucide-react";
import { env } from "~/env.mjs";
import Link from "next/link";

type AcquistoProcessingProps = {
  paymentId: PaymentsId;
  packId: PrezziarioIdprezziario;
  stripePromise: Promise<Stripe | null>;
};

export const AcquistoProcessing = ({
  paymentId,
  packId,
  stripePromise,
}: AcquistoProcessingProps) => {
  const [stripeIntent, setStripeIntent] = useState<{
    clientSecret: string | null;
    titolo: string;
    prezzo: number;
    descrizione: string;
  } | null>(null);
  const { t } = useTranslation();
  const [generatedIntent, setGeneratedIntent] = useState(false);

  const { mutate, isPending } = api.stripe.createIntent.useMutation({
    onSuccess: (data) => {
      setStripeIntent(data);
    },
  });

  if (generatedIntent && !isPending && !stripeIntent) {
    return <Status500 />;
  }

  return (
    <div className="mx-auto my-4 w-full max-w-3xl space-y-8 rounded-md">
      <h3 className="mt-2 text-center text-2xl font-bold tracking-wide text-neutral-700 uppercase">
        {t.acquisto.titolo}
      </h3>
      {!generatedIntent ? (
        <PricePreparation
          packId={packId}
          onProcedi={() => {
            setGeneratedIntent(true);
            mutate({
              paymentId,
            });
          }}
        />
      ) : isPending ? (
        <LoadingPage />
      ) : (
        stripeIntent &&
        stripeIntent.clientSecret && (
          <>
            <Elements
              options={{
                appearance: {
                  theme: "stripe",
                  variables: {
                    colorPrimary: "#18181b",
                    colorText: "#18181b",
                  },
                },
                clientSecret: stripeIntent.clientSecret,
              }}
              stripe={stripePromise}
            >
              <CheckoutForm
                titolo={stripeIntent.titolo}
                prezzo={stripeIntent.prezzo}
                descrizione={stripeIntent.descrizione}
              />
            </Elements>
          </>
        )
      )}
    </div>
  );
};

export const PricePreparation = ({
  packId,
  onProcedi,
}: {
  packId: PrezziarioIdprezziario;
  onProcedi: () => void;
}) => {
  const { data: prezziario, isLoading } =
    api.prezziario.getPrezzoPerServizio.useQuery({
      idprezziario: packId,
    });
  const { t } = useTranslation();
  return (
    <div className="mx-auto mt-4 max-w-2xl p-2 sm:mt-10">
      {isLoading || !prezziario ? (
        <>
          <h3 className="text-2xl font-semibold">{t.acquisto.preparazione}</h3>
          <LoadingPage />
        </>
      ) : (
        <div className="space-y-8">
          <h3 className="text-center text-2xl font-semibold">
            {t.acquisto.servizi_acquisto}
          </h3>

          <div className="space-y-6">
            <p className="text-3xl">{prezziario.nome_it}</p>
            <p className="text-lg">
              Cod: &ldquo;{prezziario.idprezziario}&rdquo;
            </p>
            <p className="text-4xl font-bold">
              {formatCurrency(prezziario.prezzo_cent / 100)}
            </p>
            <p>{prezziario.desc_it}</p>
          </div>

          {prezziario.testo_condizioni && (
            <Link
              aria-label="Leggi le condizioni"
              href={`/servizio/condizioni/${prezziario.testo_condizioni}`}
              target="_blank"
              className="block w-fit"
            >
              <Button className="flex w-full items-center gap-2 text-sm">
                <span>{t.acquisto.leggi_condizioni}</span>
                <ExternalLink />
              </Button>
            </Link>
          )}

          <Button
            onClick={onProcedi}
            className="flex w-full items-center gap-2 text-lg"
            variant="info"
            size="xl"
            disabled={isLoading || !prezziario}
          >
            <span>{t.acquisto.procedi_pagamento}</span> <ArrowRight />
          </Button>
        </div>
      )}
    </div>
  );
};

const CheckoutForm = ({
  titolo,
  prezzo,
  descrizione,
}: {
  titolo: string;
  prezzo: number;
  descrizione: string;
}) => {
  const stripe = useStripe();
  const elements = useElements();

  const [message, setMessage] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  const { t } = useTranslation();

  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    console.log("submitting payment");
    if (!stripe || !elements) {
      return;
    }

    setIsLoading(true);
    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: `${env.NEXT_PUBLIC_BASE_URL}/servizio/acquisto-processing`,
      },
    });
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message || "An unexpected error occurred.");
    } else {
      setMessage("An unexpected error occurred.");
    }
    setIsLoading(false);
  };

  return (
    <Card className="flex w-full flex-col justify-between text-left">
      <CardHeader>
        <CardTitle>
          <p className="text-2xl">{titolo}</p>
        </CardTitle>
        <p>{descrizione}</p>
        <span>
          <span className="text-3xl font-bold">
            {formatCurrency(prezzo / 100)}
          </span>{" "}
          <span className="text-base font-normal sm:text-sm">
            {t.pricing_cmp.risultati_iva}
          </span>
        </span>
      </CardHeader>
      <CardContent>
        <form id="payment-form" onSubmit={handleSubmit} className="space-y-5">
          <PaymentElement
            id="payment-element"
            options={{ layout: "accordion" }}
          />

          <LoadingButton
            aria-label="Procedi al pagamento"
            type="submit"
            className="w-full"
            disabled={isLoading || !stripe || !elements}
            loading={isLoading || !stripe || !elements}
          >
            {t.procedi}
          </LoadingButton>
          {message && <div id="payment-message">{message}</div>}
        </form>
      </CardContent>
    </Card>
  );
};
