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

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 font-bold text-2xl text-neutral-700 uppercase tracking-wide">
				{t.acquisto.titolo}
			</h3>
			{(() => {
				if (!generatedIntent) {
					return (
						<PricePreparation
							onProcedi={() => {
								setGeneratedIntent(true);
								mutate({
									paymentId,
								});
							}}
							packId={packId}
						/>
					);
				}
				if (isPending) {
					return <LoadingPage />;
				}
				if (stripeIntent?.clientSecret) {
					return (
						<>
							<Elements
								options={{
									appearance: {
										theme: "stripe",
										variables: {
											colorPrimary: "#18181b",
											colorText: "#18181b",
										},
									},
									clientSecret: stripeIntent.clientSecret,
								}}
								stripe={stripePromise}
							>
								<CheckoutForm
									descrizione={stripeIntent.descrizione}
									prezzo={stripeIntent.prezzo}
									titolo={stripeIntent.titolo}
								/>
							</Elements>
						</>
					);
				}
			})()}
		</div>
	);
};

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="font-semibold text-2xl">{t.acquisto.preparazione}</h3>
					<LoadingPage />
				</>
			) : (
				<div className="space-y-8">
					<h3 className="text-center font-semibold text-2xl">
						{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="font-bold text-4xl">
							{formatCurrency(prezziario.prezzo_cent / 100)}
						</p>
						<p>{prezziario.desc_it}</p>
					</div>

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

					<Button
						className="w-full text-lg"
						disabled={isLoading || !prezziario}
						onClick={onProcedi}
						size="xl"
						variant="info"
					>
						<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({
			confirmParams: {
				return_url: `${env.NEXT_PUBLIC_BASE_URL}/servizio/acquisto-processing`,
			},
			elements,
		});
		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="font-bold text-3xl">
						{formatCurrency(prezzo / 100)}
					</span>{" "}
					<span className="font-normal text-base sm:text-sm">
						{t.pricing_cmp.risultati_iva}
					</span>
				</span>
			</CardHeader>
			<CardContent>
				<form className="space-y-5" id="payment-form" onSubmit={handleSubmit}>
					<PaymentElement
						id="payment-element"
						options={{ layout: "accordion" }}
					/>

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