import { PaymentCardInfo } from "@/components/billing/payment-card-info";
import type {
  PaymentCheckoutCheckingOutState,
  PaymentCheckoutCreatingOrderState,
  PaymentCheckoutFailureState,
  PaymentCheckoutProcessingActionState,
  PaymentCheckoutReviewingOrderState,
  PaymentCheckoutSucceedState,
} from "@/components/billing/store";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { useLocaleFunction } from "@/hooks/use-localed";
import type { CreditsOrder } from "@/lib/api/billing";
import { getErrorMessage } from "@/lib/errors";
import { Loader2Icon } from "lucide-react";
import { useMemo } from "react";

export function CreatingOrder({
  state,
}: {
  state: PaymentCheckoutCreatingOrderState;
}) {
  const { paymentMethod } = state;
  const t = useLocaleFunction();

  return (
    <div className="space-y-4">
      <PaymentCardInfo card={paymentMethod} />
      <OrderPlaceholder />
      {t("payment.order.creating")}
    </div>
  );
}

export function ReviewOrder({
  state,
}: {
  state: PaymentCheckoutReviewingOrderState;
}) {
  const { order, paymentMethod } = state;
  const t = useLocaleFunction();

  return (
    <form
      className="space-y-4"
      onSubmit={(e) => {
        e.preventDefault();
        void state.checkout();
      }}
    >
      <PaymentCardInfo card={paymentMethod} />
      <OrderDetails order={order} />

      <Button className="w-full" type="submit">
        {t("payment.order.checkout")}
      </Button>
    </form>
  );
}

export function CheckingOut({
  state,
}: {
  state: PaymentCheckoutCheckingOutState;
}) {
  const { order } = state;
  const t = useLocaleFunction();
  return (
    <div className="space-y-4">
      <OrderDetails order={order} />

      <Button className="w-full" disabled>
        {t("payment.order.checking-out")}
        <Loader2Icon className="animate-spin repeat-infinite" />
      </Button>
    </div>
  );
}

export function Processing({
  state,
}: {
  state: PaymentCheckoutProcessingActionState;
}) {
  const { order } = state;

  return (
    <div className="space-y-4">
      <OrderDetails order={order} />

      <Button className="w-full" disabled>
        Processing Order...
        <Loader2Icon className="animate-spin repeat-infinite" />
      </Button>
    </div>
  );
}

export function Succeed({ state }: { state: PaymentCheckoutSucceedState }) {
  const { order } = state;

  return (
    <div className="space-y-4">
      <OrderDetails order={order} />
    </div>
  );
}

export function Failure({ state }: { state: PaymentCheckoutFailureState }) {
  const { order, error } = state;
  const t = useLocaleFunction();

  return (
    <div className="space-y-4">
      {order ? <OrderDetails order={order} /> : <OrderPlaceholder />}

      <Alert variant="destructive">
        <AlertTitle>
          {t("payment.alerts.failed-to-process-order.title")}
        </AlertTitle>
        <AlertDescription className="whitespace-pre-wrap">
          {t(
            "payment.alerts.failed-to-process-order.description",
            getErrorMessage(error)
          )}
        </AlertDescription>
      </Alert>
    </div>
  );
}

function OrderPlaceholder() {
  return (
    <div className="space-y-4">
      {[0].map((i) => (
        <div key={i} className="flex justify-between">
          <div>
            <div className="font-semibold">
              <Skeleton className="h-4 w-24" />
            </div>
            <div className="text-sm text-muted-foreground">
              <Skeleton className="h-4 w-24" />
            </div>
          </div>
          <span>
            <Skeleton className="h-4 w-24" />
          </span>
        </div>
      ))}

      <Separator className="my-2" />

      <div className="space-y-2">
        <div className="flex justify-between">
          <p className="font-semibold">Tax</p>
          <span>
            <Skeleton className="h-4 w-24" />
          </span>
        </div>
      </div>

      <Separator className="my-2" />

      <div className="flex justify-between text-lg">
        <p className="font-semibold">Total</p>
        <span className="font-semibold">
          <Skeleton className="h-4 w-24" />
        </span>
      </div>
    </div>
  );
}

function OrderDetails({ order }: { order: CreditsOrder }) {
  const t = useLocaleFunction();
  const orderItems = [
    {
      id: 1,
      name: "Lab Credits",
      amount: order.price_details.product_amount,
      quantity: order.quantity,
      discount: order.price_details.discount,
    },
  ];

  const formatter = useMemo(
    () =>
      Intl.NumberFormat(["en-US"], {
        style: "currency",
        currency: order.price_details.currency,
      }),
    [order.price_details.currency]
  );

  return (
    <div className="space-y-4">
      {orderItems.map((item) => (
        <div key={item.id} className="flex justify-between">
          <div>
            <p className="font-semibold">{item.name}</p>
            <p className="text-sm text-muted-foreground">
              {t("payment.order.item-quantity", item.quantity)}
            </p>
          </div>
          <span>{formatter.format(parseFloat(item.amount))}</span>
        </div>
      ))}

      <Separator className="my-2" />

      <div className="space-y-2">
        <div className="flex justify-between">
          <p className="font-semibold">{t("payment.order.tax")}</p>
          <span>
            {formatter.format(parseFloat(order.price_details.tax_amount))}
          </span>
        </div>
      </div>

      <Separator className="my-2" />

      <div className="flex justify-between text-lg">
        <p className="font-semibold">{t("payment.order.total")}</p>
        <span className="font-semibold">
          {formatter.format(parseFloat(order.price_details.amount_total))}
        </span>
      </div>
    </div>
  );
}
