import Image from 'next/image';
import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
import { toPrintDate } from 'lib/utils';
import PaymentsDetails from './payment-details';
import Price from 'components/price';
import Divider from 'components/divider';
import Markdown from 'markdown-to-jsx';
import { Order, OrderConfirmationContent } from 'lib/shopify/types';
import { FormEventHandler, useEffect, useRef, useState, useTransition } from 'react';
import { confirmOrder, fetchOrderConfirmationContent } from 'components/orders/actions';
import { Button, Heading, Text, Label, Input } from 'components/ui';
import LoadingDots from 'components/loading-dots';

function OrderConfirmationDetails({
  content,
  order
}: {
  content: OrderConfirmationContent;
  order: Order;
}) {
  return (
    <div className="space-y-4">
      <figure>
        <Image
          src={content?.logo?.url}
          alt={content?.logo?.altText || 'Logo'}
          width={content?.logo?.width || 400}
          height={content?.logo?.height || 400}
        />
      </figure>
      <Heading className="text-primary" size="sm">
        ORDER INFORMATION:
      </Heading>
      <div>
        <Text>Order number: {order.name}</Text>
        <Text>Email: {order.customer?.emailAddress}</Text>
        <Text>Date: {toPrintDate(order.processedAt)}</Text>
      </div>
      <div className="flex">
        <div className="flex-1 space-y-2">
          <Label>Shipping Address</Label>
          <div>
            <Text>
              {order.shippingAddress!.firstName} {order.shippingAddress!.lastName}
            </Text>
            <Text>{order.shippingAddress!.address1}</Text>
            {order.shippingAddress!.address2 && <Text>{order.shippingAddress!.address2}</Text>}
            <Text>
              {order.shippingAddress!.city} {order.shippingAddress!.provinceCode}{' '}
              {order.shippingAddress!.zip}
            </Text>
            <Text>{order.shippingAddress!.country}</Text>
          </div>
        </div>
        <div className="flex-1 space-y-2">
          <Label>Billing Address</Label>
          <div>
            <Text>
              {order.billingAddress!.firstName} {order.billingAddress!.lastName}
            </Text>
            <Text>{order.billingAddress!.address1}</Text>
            {order.billingAddress!.address2 && <Text>{order.billingAddress!.address2}</Text>}
            <Text>
              {order.billingAddress!.city} {order.billingAddress!.provinceCode}{' '}
              {order.billingAddress!.zip}
            </Text>
            <Text>{order.billingAddress!.country}</Text>
          </div>
        </div>
      </div>
      <div className="flex flex-col gap-2">
        <Label>Payment</Label>
        <PaymentsDetails order={order} hideIcon />
      </div>
      <div className="mb-4">
        <Heading size="sm">Products</Heading>
        <Divider />
        <table className="w-full table-auto">
          <thead>
            <tr>
              <th className="text-start">
                <Label>Product</Label>
              </th>
              <th className="text-start">
                <Label>Quantity</Label>
              </th>
              <th className="text-start">
                <Label>Price</Label>
              </th>
            </tr>
          </thead>
          <tbody>
            {order.lineItems.map((lineItem, index) => (
              <tr key={index}>
                <td className="py-4 text-start">
                  <Text className="max-w-sm">{lineItem.title}</Text>
                </td>
                <td className="text-start">
                  <Text>{lineItem.quantity}</Text>
                </td>
                <td className="text-start">
                  <Price
                    className="text-sm"
                    amount={lineItem.totalPrice!.amount}
                    currencyCode={lineItem.totalPrice!.currencyCode}
                  />
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        <Divider />
        <div className="ml-auto flex w-60 flex-col gap-4">
          <div className="flex justify-between">
            <Text>Subtotal</Text>
            <Price
              className="text-sm font-semibold"
              amount={order.subtotal!.amount}
              currencyCode={order.subtotal!.currencyCode}
            />
          </div>
          <div className="flex items-center justify-between">
            <Text>Shipping</Text>
            {order.shippingMethod && order.shippingMethod.price.amount !== '0.0' ? (
              <Price
                className="text-sm font-semibold"
                amount={order.shippingMethod.price.amount}
                currencyCode={order.shippingMethod.price.currencyCode}
              />
            ) : (
              <Text className="font-semibold">Free</Text>
            )}
          </div>
          <div className="flex items-center justify-between">
            <Heading as="span" size="sm">
              Total
            </Heading>
            <Price
              className="font-semibold"
              amount={order.totalPrice.amount}
              currencyCode={order.totalPrice.currencyCode}
            />
          </div>
        </div>
      </div>
      <Markdown
        options={{
          overrides: {
            h1: {
              props: {
                className: 'text-primary font-semibold mt-4 mb-2 text-xl'
              }
            },
            h2: {
              props: {
                className: 'text-primary font-semibold mt-4 mb-2'
              }
            },
            h3: {
              props: {
                className: 'text-primary text-sm font-semibold mt-4 mb-2'
              }
            },
            p: {
              props: {
                className: 'text-sm'
              }
            },
            a: {
              props: {
                className: 'text-sm, text-primary underline'
              }
            }
          }
        }}
      >
        {content?.body || ''}
      </Markdown>
    </div>
  );
}
export default function OrderConfirmationModal({
  order,
  isOpen,
  onClose
}: {
  order: Order;
  isOpen: boolean;
  onClose: () => void;
}) {
  const [loading, setLoading] = useState(true);
  const [orderConfirmationContent, setOrderConfirmationContent] =
    useState<OrderConfirmationContent>();
  const [submitting, startTransition] = useTransition();
  const formRef = useRef<HTMLFormElement>(null);

  useEffect(() => {
    // If the order has already been confirmed, don't fetch the content
    if (order.orderConfirmation) return;

    if (!isOpen) return;

    (async () => {
      const data = await fetchOrderConfirmationContent();
      setOrderConfirmationContent(data);
      setLoading(false);
    })();
  }, [isOpen, order.orderConfirmation]);

  const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
    event.preventDefault();
    const form = formRef.current;
    if (!form) return;

    startTransition(async () => {
      const formData = new FormData(form);
      await confirmOrder({
        order,
        content: orderConfirmationContent!,
        formData
      });
    });
  };

  if (!loading && !orderConfirmationContent) return null;

  return (
    <Dialog open={isOpen} onClose={onClose} className="relative z-50">
      <DialogBackdrop
        transition
        className="fixed inset-0 bg-black/30 duration-300 ease-out data-[closed]:opacity-0"
      />
      <div className="fixed inset-0 w-screen overflow-y-auto p-4">
        <div className="flex min-h-full items-center justify-center">
          <DialogPanel
            transition
            className="w-full max-w-3xl space-y-4 rounded bg-white p-5 duration-300 ease-out data-[closed]:scale-95 data-[closed]:opacity-0"
          >
            <DialogTitle className="mb-2 font-bold">Confirm Order</DialogTitle>
            {loading ? (
              <LoadingDots size="lg" rootClassName="flex justify-center" />
            ) : (
              <OrderConfirmationDetails content={orderConfirmationContent!} order={order} />
            )}
            <form onSubmit={handleSubmit} ref={formRef}>
              <div className="max-w-md space-y-4">
                <Input
                  type="date"
                  readOnly
                  label="Date"
                  value={new Date().toLocaleDateString('en-CA', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit'
                  })}
                />
                <Input required label="Print your name to sign" />
                <Input required label="Credit card holder's electronic signature" />
              </div>
              <div className="flex justify-end gap-2">
                <Button variant="text" onClick={onClose}>
                  Cancel
                </Button>
                <Button
                  type="submit"
                  variant="solid"
                  color="primary"
                  disabled={submitting || loading}
                  isLoading={submitting}
                  loadingText="Submitting"
                >
                  Submit
                </Button>
              </div>
            </form>
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  );
}