import React, { useState, useEffect, Fragment } from "react";
import { AuthContext, tokenExpireError } from "Src/authContext";
import { GlobalContext, showToast } from "Src/globalContext";
import MkdSDK from "Utils/MkdSDK";
import { LazyLoad } from "Components/LazyLoad";
import { InteractiveButton } from "Components/InteractiveButton";
import CustomSelect2 from "Components/CustomSelect2";
import { Dialog, Transition } from "@headlessui/react";
import { XMarkIcon } from "@heroicons/react/24/solid";
import { ClipboardDocumentIcon } from "@heroicons/react/24/outline";
import {
  CardElement,
  Elements,
  useStripe,
  useElements,
} from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import Spinner from "Components/Spinner";
import { useNavigate } from "react-router";

const stripePromise = loadStripe(
  "pk_test_51Ll5ukBgOlWo0lDUrBhA2W7EX2MwUH9AR5Y3KQoujf7PTQagZAJylWP1UOFbtH4UwxoufZbInwehQppWAq53kmNC00UIKSmebO"
);

const CardDetailsModal = ({ isOpen, closeModal, onSubmit, loading }) => {
  const [cardReady, setCardReady] = useState(false);
  const stripe = useStripe();
  const elements = useElements();

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!stripe || !elements) return;

    const result = await stripe.createToken(elements.getElement(CardElement));
    onSubmit(result);
  };

  return (
    <Transition appear show={isOpen} as={Fragment}>
      <Dialog as="div" className="relative z-50" onClose={closeModal}>
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-black bg-opacity-25" />
        </Transition.Child>

        <div className="fixed inset-0 overflow-y-auto">
          <div className="flex min-h-full items-center justify-center p-4 text-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-boxdark p-6 text-left align-middle shadow-xl transition-all">
                <div className="flex items-center justify-between">
                  <Dialog.Title className="text-lg font-semibold text-white">
                    Enter Card Details
                  </Dialog.Title>
                  <button
                    onClick={closeModal}
                    className="text-bodydark hover:text-white"
                  >
                    <XMarkIcon className="h-6 w-6" />
                  </button>
                </div>

                <form onSubmit={handleSubmit} className="mt-4">
                  <div className="mb-4">
                    <CardElement
                      className="rounded border border-form-strokedark bg-form-input p-4 text-bodydark"
                      options={{
                        hidePostalCode: true,
                        style: {
                          base: {
                            fontSize: "16px",
                            color: "#E5E7EB",
                            "::placeholder": {
                              color: "#9CA3AF",
                            },
                          },
                        },
                      }}
                      onReady={() => setCardReady(true)}
                    />
                  </div>

                  <div className="mt-6 flex justify-end gap-4">
                    <button
                      type="button"
                      onClick={closeModal}
                      className="rounded-lg border border-stroke px-4 py-2 text-bodydark hover:bg-boxdark/50"
                    >
                      Cancel
                    </button>
                    <InteractiveButton
                      type="submit"
                      loading={loading}
                      disabled={loading || !cardReady}
                      className="rounded-lg bg-primary px-4 py-2 text-white hover:bg-primary/80"
                    >
                      {loading ? "Processing..." : "Subscribe"}
                    </InteractiveButton>
                  </div>
                </form>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  );
};

const InvoicesTab = () => {
  const sdk = new MkdSDK();
  const { dispatch } = React.useContext(AuthContext);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);
  const [initialId, setInitialId] = React.useState(null);
  const [data, setData] = React.useState({});
  const [pageSize, setPageSize] = React.useState(10);
  const [canPreviousPage, setCanPreviousPage] = React.useState(false);
  const [canNextPage, setCanNextPage] = React.useState(false);
  const [loading, setLoading] = React.useState(true);

  const columns = [
    {
      header: "Status",
      accessor: "status",
    },
    {
      header: "Currency",
      accessor: "currency",
    },
    {
      header: "Amount due",
      accessor: "amount_due",
      type: "currency",
    },
    {
      header: "Amount paid",
      accessor: "amount_paid",
      type: "currency",
    },
    {
      header: "Amount remaining",
      accessor: "amount_remaining",
      type: "currency",
    },
    {
      header: "Created at",
      accessor: "created",
      type: "timestamp",
    },
  ];

  function updatePageSize(limit) {
    (async function () {
      setPageSize(limit);
      await getData({ limit });
    })();
  }

  function previousPage() {
    (async function () {
      await getData({ limit: pageSize, before: data?.data[0].id });
    })();
  }

  function nextPage() {
    (async function () {
      await getData({
        limit: pageSize,
        after: data?.data[data?.data.length - 1].id,
      });
    })();
  }

  async function getData(paginationParams) {
    try {
      setLoading(true);
      const {
        list: invoices,
        limit,
        error,
        message,
      } = await sdk.getCustomerStripeInvoices(paginationParams);

      if (error) {
        showToast(globalDispatch, message, 5000);
      }
      if (!invoices) {
        return;
      }

      if (!initialId) {
        setInitialId(invoices?.data[0]?.id ?? "");
      }
      setData(invoices);
      setPageSize(+limit);
      setCanPreviousPage(initialId && initialId !== invoices.data[0]?.id);
      setCanNextPage(invoices.has_more);
      setLoading(false);
    } catch (error) {
      console.error("ERROR", error);
      showToast(globalDispatch, error.message, 5000);
      tokenExpireError(dispatch, error.message);
      setLoading(false);
    }
  }

  React.useEffect(() => {
    getData({});
  }, []);

  if (loading) return <Spinner />;

  return (
    <div className="bg-brown-main-bg overflow-hidden rounded p-5 px-5 pt-8 sm:px-8">
      <div className="bg-brown-main-bg">
        <div className="w-full rounded p-5 px-0">
          <div className="mb-6 flex w-full justify-between text-center">
            <div className="flex w-full flex-row justify-between">
              <div className="text-left text-[16px] font-[600] sm:text-[20px]">
                Invoices
              </div>
            </div>
          </div>
          <div
            className={`${loading ? "" : "custom-overflow overflow-x-auto"}`}
          >
            {loading ? (
              <div className="flex max-h-fit min-h-fit min-w-fit max-w-full items-center justify-center py-5">
                <Spinner />
              </div>
            ) : (
              <table className="min-w-full divide-y divide-[#1f1d1a]/10">
                <thead>
                  <tr>
                    {columns.map((column, i) => (
                      <th
                        key={i}
                        scope="col"
                        className="font whitespace-nowrap border-b-[#1f1d1a]/10 px-4 text-left font-[700] md:border-0 md:border-b-[3px] md:border-dashed md:px-6 md:py-3"
                      >
                        {column.header}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody className="font-iowan-regular divide-y divide-[#1f1d1a]/10">
                  {data?.data?.map((row, i) => (
                    <tr key={i}>
                      {columns.map((cell, index) => {
                        if (cell.type === "timestamp") {
                          return (
                            <td
                              key={index}
                              className="whitespace-nowrap px-6 py-4"
                            >
                              {new Date(
                                row[cell.accessor] * 1000
                              ).toLocaleString("en-US")}
                            </td>
                          );
                        } else if (cell.type === "currency") {
                          return (
                            <td
                              key={index}
                              className="whitespace-nowrap px-6 py-4"
                            >
                              ${Number(row[cell.accessor] / 100).toFixed(2)}
                            </td>
                          );
                        }
                        return (
                          <td
                            key={index}
                            className="whitespace-nowrap px-6 py-4"
                          >
                            {row[cell.accessor]}
                          </td>
                        );
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>
        </div>
        {data?.data?.length === 0 ? (
          <div className="mb-[20px] mt-24 flex flex-col items-center">
            <ClipboardDocumentIcon
              className="h-8 w-8 text-gray-700"
              strokeWidth={2}
            />
            <p className="mt-4 text-center text-base font-medium">
              No Invoices
            </p>
          </div>
        ) : null}
        {/* {data?.data?.length > 0 && (
          <div className="p-5 bg-brown-main-bg">
            <PaginationBar
              pageSize={pageSize}
              canPreviousPage={canPreviousPage}
              canNextPage={canNextPage}
              updatePageSize={updatePageSize}
              previousPage={previousPage}
              nextPage={nextPage}
              currentPage={age}
              setCurrentPage={setCurrentPage}
            />
          </div>
        )} */}
      </div>
    </div>
  );
};

const PlansTab = ({
  currentSubscription,
  products,
  handleSubscribe,
  isProcessing,
  isModalOpen,
  setIsModalOpen,
  handleCardSubmit,
  selectedProjectRange,
  setSelectedProjectRange,
  selectedInterval,
  setSelectedInterval,
  isLoading,
  isOnboarding,
}) => {
  console.log(currentSubscription);
  const projectRanges = {
    "1-50": {
      portal: { monthly: 150, annual: 1500 },
      studio: { monthly: 150, annual: 1500 },
      complete: { monthly: 250, annual: 2500 },
    },
    "51-100": {
      portal: { monthly: 175, annual: 1750 },
      studio: { monthly: 175, annual: 1750 },
      complete: { monthly: 275, annual: 2750 },
    },
    "101-150": {
      portal: { monthly: 200, annual: 2000 },
      studio: { monthly: 200, annual: 2000 },
      complete: { monthly: 300, annual: 3000 },
    },
    "151-200": {
      portal: { monthly: 225, annual: 2250 },
      studio: { monthly: 225, annual: 2250 },
      complete: { monthly: 325, annual: 3250 },
    },
    "201+": {
      portal: { monthly: 250, annual: 2500 },
      studio: { monthly: 250, annual: 2500 },
      complete: { monthly: 350, annual: 3500 },
    },
  };

  const planFeatures = {
    "The Portal": [
      "Project Management",
      "Project Calendar",
      "Client Login Portal",
      "Digital 8-count sheets",
      "Automated Music Licenses",
      "Automated Reminder Emails",
      "Automated Music Surveys",
      "Project Edit Management",
      "8-Count Track Management",
      "Custom Email Domain",
    ],
    "The Studio": [
      "Automated Music Surveys",
      "Project Management",
      "Project Calendar",
      "Project Budget Review",
      "Automated Vocal Orders",
      "Excel Style Order View",
      "Automated Reminder Emails",
      "Company Logo Customization",
      "Custom Email Domain",
    ],
    "Complete Suite": [
      "Everything in The Portal",
      "Everything in The Studio",
      "Priority Support",
      "Dedicated Account Manager",
    ],
  };

  const planKeys = {
    "The Portal": "portal",
    "The Studio": "studio",
    "Complete Suite": "complete",
  };

  const getButtonText = (productId, currentPlanId) => {
    if (currentPlanId === productId) {
      return "Current Plan";
    }

    // The Portal is ID 2, The Studio is ID 3, Complete Suite is ID 4
    if (
      (currentPlanId === 2 && (productId === 3 || productId === 4)) || // From Portal to Studio or Complete
      (currentPlanId === 3 && productId === 4) // From Studio to Complete
    ) {
      return "Upgrade Now";
    }

    return "Subscribe Now";
  };

  if (isLoading) {
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="h-16 w-16 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
      </div>
    );
  }

  return (
    <div className="mx-auto h-full">
      {currentSubscription && (
        <div className="mb-8 rounded-lg bg-boxdark p-6">
          <h2 className="mb-4 text-2xl font-bold text-white">
            Current Subscription
          </h2>
          <div className="space-y-2 text-lg font-bold text-white">
            <p>Plan: {currentSubscription.plan_name ?? "None"}</p>
            <p>
              Amount: ${currentSubscription.amount}/
              {currentSubscription.interval}
            </p>
            <p>Status: {currentSubscription.status ? "Active" : "Inactive"}</p>
            {currentSubscription.currentPeriodEnd && (
              <p>
                Next billing date:{" "}
                {new Date(
                  currentSubscription.currentPeriodEnd * 1000
                ).toLocaleDateString()}
              </p>
            )}
          </div>
        </div>
      )}

      <div className="mb-8">
        <h1 className="mb-6 text-3xl font-bold text-white">Choose Your Plan</h1>
        <div className="mb-8 flex items-center justify-center gap-4">
          <span className="whitespace-nowrap font-medium text-white">
            Show pricing for
          </span>
          <div className="w-[200px]">
            <CustomSelect2
              value={selectedProjectRange}
              onChange={(value) => setSelectedProjectRange(value)}
              className="rounded-lg border border-stroke bg-transparent px-4 py-2 text-white outline-none focus:border-primary"
            >
              <option value="1-50">1-50 Mix Projects</option>
              <option value="51-100">51-100 Mix Projects</option>
              <option value="101-150">101-150 Mix Projects</option>
              <option value="151-200">151-200 Mix Projects</option>
              <option value="201+">201+ Mix Projects</option>
            </CustomSelect2>
          </div>
          <div className="flex items-center gap-4">
            <label className="relative inline-flex cursor-pointer items-center">
              <input
                type="checkbox"
                className="peer sr-only"
                checked={selectedInterval === "year"}
                onChange={(e) =>
                  setSelectedInterval(e.target.checked ? "year" : "month")
                }
              />
              <div className="peer h-6 w-11 rounded-full bg-stroke after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:bg-white after:transition-all after:content-[''] peer-checked:bg-primary peer-checked:after:translate-x-full"></div>
            </label>
            <span className="text-white">Bill Annually (Save 15-20%)</span>
          </div>
        </div>

        <Elements stripe={stripePromise}>
          <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
            {products.map((product) => {
              const planKey = planKeys[product.name];
              const pricing =
                projectRanges[selectedProjectRange]?.[planKey]?.[
                  selectedInterval === "year" ? "annual" : "monthly"
                ];

              return (
                <div
                  key={product.id}
                  className="flex flex-col rounded-lg border border-form-strokedark bg-boxdark-2 p-6 shadow-lg"
                >
                  <h3 className="mb-4 text-2xl font-bold text-white">
                    {product.name}
                  </h3>
                  <div className="mb-6">
                    <span className="text-4xl font-bold text-primary">
                      ${pricing}
                    </span>
                    <span className="text-bodydark">
                      /{selectedInterval === "year" ? "year" : "month"}
                    </span>
                  </div>
                  <div className="mb-6 flex-grow">
                    <h4 className="mb-2 font-semibold text-white">Features:</h4>
                    <ul className="space-y-2">
                      {planFeatures[product.name].map((feature, index) => (
                        <li
                          key={index}
                          className="flex items-center text-bodydark"
                        >
                          <svg
                            className="mr-2 h-5 w-5 text-primary"
                            fill="none"
                            stroke="currentColor"
                            viewBox="0 0 24 24"
                          >
                            <path
                              strokeLinecap="round"
                              strokeLinejoin="round"
                              strokeWidth="2"
                              d="M5 13l4 4L19 7"
                            />
                          </svg>
                          {feature}
                        </li>
                      ))}
                    </ul>
                  </div>
                  <LazyLoad>
                    <button
                      onClick={() => handleSubscribe(product.id)}
                      disabled={currentSubscription?.planId === product.id}
                      className={`w-full rounded-full border border-primary  px-8 py-3 font-semibold  transition-all hover:bg-primary/80  disabled:cursor-not-allowed ${
                        currentSubscription?.planId === product.id
                          ? "bg-primary text-white"
                          : "bg-transparent text-primary hover:text-white"
                      }`}
                    >
                      {getButtonText(product.id, currentSubscription?.planId)}
                    </button>
                  </LazyLoad>
                </div>
              );
            })}
          </div>

          <CardDetailsModal
            isOpen={isModalOpen}
            closeModal={() => setIsModalOpen(false)}
            onSubmit={handleCardSubmit}
            loading={isProcessing}
          />
        </Elements>
      </div>
    </div>
  );
};

const MemberSubscriptionPage = ({ isOnboarding = false }) => {
  const { dispatch } = React.useContext(AuthContext);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);
  const [activeTab, setActiveTab] = useState("plans");
  const [isLoading, setIsLoading] = useState(true);
  const [products, setProducts] = useState([]);
  const [currentSubscription, setCurrentSubscription] = useState(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedPlan, setSelectedPlan] = useState(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [selectedProjectRange, setSelectedProjectRange] = useState("1-50");
  const [selectedInterval, setSelectedInterval] = useState("month");
  const navigate = useNavigate();

  const handleSubscribe = async (productId) => {
    setSelectedPlan(productId);
    setIsModalOpen(true);
  };

  const handleCardSubmit = async (result) => {
    if (result?.error) {
      showToast(globalDispatch, result?.error?.message, 4000, "error");
      return;
    }

    setIsProcessing(true);
    const sdk = new MkdSDK();

    try {
      // Create or update Stripe customer
      const customerParams = {
        cardToken: result.token.id,
      };

      console.log(currentSubscription);
      let subscriptionResult = null;
      if (!currentSubscription?.subId) {
        const result = await sdk.createStripeCustomer(customerParams);
        subscriptionResult = await sdk.createStripeSubscription({
          planId: selectedPlan,
        });
        console.log(result);

        return;
      }

      // Create subscription
      subscriptionResult = await sdk.changeStripeSubscription({
        userId: localStorage.getItem("user"),
        newPlanId: selectedPlan,
        activeSubscriptionId: currentSubscription?.subId,
      });

      if (!subscriptionResult.error) {
        showToast(
          globalDispatch,
          "Successfully subscribed to plan",
          4000,
          "success"
        );

        // Refresh subscription data
        const newSubData = await sdk.getCustomerStripeSubscription();
        console.log(newSubData);
        setIsModalOpen(false);
        if (!newSubData?.error) {
          setCurrentSubscription(newSubData?.customer);
          if (isOnboarding) {
            navigate("/member/dashboard");
          }
        }
      } else {
        showToast(
          globalDispatch,
          "Failed to create subscription",
          4000,
          "error"
        );
      }
    } catch (error) {
      showToast(globalDispatch, error.message, 4000, "error");
      tokenExpireError(dispatch, error.message);
    } finally {
      setIsProcessing(false);
    }
  };

  useEffect(() => {
    const fetchData = async () => {
      const sdk = new MkdSDK();
      setIsLoading(true);
      try {
        // Fetch products
        const productsResult = await sdk.callRawAPI(
          `/v4/api/records/stripe_product?page=${1}&limit=${100}`,
          [],
          "GET"
        );

        const pricesResult = await sdk.callRawAPI(
          `/v4/api/records/stripe_price?page=${1}&limit=${100}`,
          [],
          "GET"
        );

        if (!productsResult.error) {
          // Filter out the test product (plan A) and sort by ID
          const filteredProducts = productsResult.list
            .filter((product) => product.name !== "plan A")
            .sort((a, b) => a.id - b.id);
          setProducts(filteredProducts);
        }

        if (!isOnboarding) {
          // Fetch current subscription only if not in onboarding mode
          const subscriptionResult = await sdk.getCustomerStripeSubscription();
          if (!subscriptionResult.error) {
            // Find the price details for the current subscription
            const currentPrice = pricesResult.list.find(
              (price) =>
                price.product_id === subscriptionResult?.customer?.planId
            );

            // Enhance subscription data with price details
            setCurrentSubscription({
              ...subscriptionResult?.customer,
              plan_name:
                currentPrice?.name || subscriptionResult?.customer?.plan_name,
              amount:
                currentPrice?.amount || subscriptionResult?.customer?.amount,
              interval: currentPrice?.object
                ? JSON.parse(currentPrice.object)?.recurring?.interval
                : "month",
            });
          }
        }
      } catch (error) {
        showToast(globalDispatch, error.message, 4000, "error");
        tokenExpireError(dispatch, error.message);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
    globalDispatch({
      type: "SETPATH",
      payload: {
        path: "subscription",
      },
    });
  }, []);

  return (
    <div
      className={`${
        isOnboarding ? "w-full" : "mx-auto w-full p-4 md:p-6 2xl:p-10"
      } `}
    >
      {!isOnboarding && (
        <div className="mb-6">
          <h2 className="text-title-md2 font-semibold text-white">
            Subscription Management
          </h2>
        </div>
      )}

      <div className="rounded border border-strokedark bg-boxdark">
        {!isOnboarding && (
          <div className="flex flex-wrap border-b border-strokedark">
            <button
              onClick={() => setActiveTab("plans")}
              className={`border-r border-strokedark px-6 py-3 text-sm font-medium transition-colors ${
                activeTab === "plans"
                  ? "bg-primary text-white"
                  : "text-white hover:bg-meta-4"
              }`}
            >
              Plans
            </button>
            {/* <button
              onClick={() => setActiveTab("invoices")}
              className={`border-r border-strokedark px-6 py-3 text-sm font-medium transition-colors ${
                activeTab === "invoices"
                  ? "bg-primary text-white"
                  : "text-white hover:bg-meta-4"
              }`}
            >
              Invoices
            </button> */}
          </div>
        )}

        <div className="p-6">
          {activeTab === "plans" && (
            <PlansTab
              currentSubscription={currentSubscription}
              products={products}
              handleSubscribe={handleSubscribe}
              isProcessing={isProcessing}
              isModalOpen={isModalOpen}
              setIsModalOpen={setIsModalOpen}
              handleCardSubmit={handleCardSubmit}
              selectedProjectRange={selectedProjectRange}
              setSelectedProjectRange={setSelectedProjectRange}
              selectedInterval={selectedInterval}
              setSelectedInterval={setSelectedInterval}
              isLoading={isLoading}
              isOnboarding={isOnboarding}
            />
          )}
          {activeTab === "invoices" && !isOnboarding && <InvoicesTab />}
        </div>
      </div>
    </div>
  );
};

export default MemberSubscriptionPage;
