import { json } from "@remix-run/node";
import { useLoaderData, Form, useActionData, useNavigate } from "@remix-run/react";
import {
  Page,
  Layout,
  Card,
  TextField,
  Checkbox,
  Button,
  Thumbnail,
  Spinner,
  Toast,
  Frame,
  Text,
  Banner,
  InlineStack,
} from "@shopify/polaris";
import { useEffect, useMemo, useState } from "react";
import { TitleBar } from "@shopify/app-bridge-react";
import { getTurn14AccessTokenFromMetafield } from "../utils/turn14Token.server";
import { authenticate } from "../shopify.server";

const PLAN_NAME = "Starter Sync";
const ALLOWED_STATUSES = ["ACTIVE", "TRIAL"];

async function checkShopExists(shop) {
  try {
    const resp = await fetch(
      `https://backend.data4autos.com/checkisshopdataexists/${shop}`
    );
    const data = await resp.json();
    return data.status === 1;
  } catch (err) {
    console.error("Error checking shop:", err);
    return false;
  }
}

function getIntervalLabel(interval) {
  switch (interval) {
    case "ANNUAL":
      return "Every 12 months";
    case "EVERY_30_DAYS":
      return "Every 30 days";
    default:
      return interval || "N/A";
  }
}

function formatMoney(amount, currencyCode = "USD") {
  if (amount == null) return "N/A";
  return `${currencyCode} ${Number(amount).toFixed(2)}`;
}

function formatDate(date) {
  if (!date) return "N/A";
  return new Date(date).toLocaleDateString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });
}

async function getSubscriptionDetails(request) {
  const { admin, session } = await authenticate.admin(request);
  const shop = session.shop;

  const resp = await admin.graphql(`
    query CurrentSubscriptionDetails {
      currentAppInstallation {
        activeSubscriptions {
          id
          name
          status
          test
          createdAt
          trialDays
          currentPeriodEnd
          lineItems {
            id
            plan {
              pricingDetails {
                __typename
                ... on AppRecurringPricing {
                  interval
                  price {
                    amount
                    currencyCode
                  }
                }
              }
            }
          }
        }
      }
    }
  `);

  const result = await resp.json();

  const subscriptions =
    result?.data?.currentAppInstallation?.activeSubscriptions || [];

  const subscription =
    subscriptions.find((sub) => ALLOWED_STATUSES.includes(sub.status)) ||
    subscriptions[0] ||
    null;

  const recurringPricing =
    subscription?.lineItems?.find(
      (item) =>
        item?.plan?.pricingDetails?.__typename === "AppRecurringPricing"
    )?.plan?.pricingDetails || null;

  const isSubscribed =
    !!subscription && ALLOWED_STATUSES.includes(subscription.status);

  return {
    shop,
    isSubscribed,
    subscription: subscription
      ? {
          id: subscription.id,
          name: subscription.name || PLAN_NAME,
          status: subscription.status,
          test: subscription.test ?? false,
          createdAt: subscription.createdAt,
          trialDays: subscription.trialDays ?? 0,
          currentPeriodEnd: subscription.currentPeriodEnd,
          interval: recurringPricing?.interval || null,
          priceAmount: recurringPricing?.price?.amount || null,
          currencyCode: recurringPricing?.price?.currencyCode || "USD",
        }
      : null,
  };
}

export const loader = async ({ request }) => {
  console.log("🚀 Loader started");

  let admin, session, shop;

  try {
    const authResult = await authenticate.admin(request);
    admin = authResult.admin;
    session = authResult.session;
    shop = session?.shop;

    console.log("✅ Shopify auth success");
    console.log("🏪 Shop:", shop);
  } catch (err) {
    console.error("❌ Shopify authentication failed:", err);
    return json({
      brands: [],
      collections: [],
      selectedBrandsFromShopify: [],
      shop: "",
      error: "Shopify authentication failed",
      isSubscribed: false,
      subscription: null,
    });
  }

  const { isSubscribed, subscription } = await getSubscriptionDetails(request);

  let accessToken = "";

  try {
    console.log("🔑 Fetching Turn14 access token from metafield...");
    accessToken = await getTurn14AccessTokenFromMetafield(request);
    console.log("✅ Turn14 access token received:", accessToken ? "YES" : "EMPTY");
  } catch (err) {
    console.error("❌ Error getting Turn14 access token:", err);
    return json({
      brands: [],
      collections: [],
      selectedBrandsFromShopify: [],
      shop,
      error: "Failed to fetch Turn14 access token",
      isSubscribed,
      subscription,
    });
  }

  let brandJson;
  try {
    const brandRes = await fetch("https://turn14.data4autos.com/v1/brands", {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      },
    });

    brandJson = await brandRes.json();

    if (!brandRes.ok) {
      return json({
        brands: [],
        collections: [],
        selectedBrandsFromShopify: [],
        shop,
        error: brandJson?.error || "Failed to fetch brands",
        isSubscribed,
        subscription,
      });
    }
  } catch (err) {
    console.error("❌ Exception while fetching Turn14 brands:", err);
    return json({
      brands: [],
      collections: [],
      selectedBrandsFromShopify: [],
      shop,
      error: "Turn14 brands fetch crashed",
      isSubscribed,
      subscription,
    });
  }

  let collections = [];
  try {
    const gqlRaw = await admin.graphql(`
      {
        collections(first: 100) {
          edges {
            node {
              id
              title
            }
          }
        }
      }
    `);

    const gql = await gqlRaw.json();
    collections = gql?.data?.collections?.edges?.map((e) => e.node) || [];
  } catch (err) {
    console.error("❌ Error fetching Shopify collections:", err);
  }

  let selectedBrands = [];

  try {
    const res = await admin.graphql(`
      {
        shop {
          metafield(namespace: "turn14", key: "selected_brands") {
            value
          }
        }
      }
    `);

    const data = await res.json();
    const rawValue = data?.data?.shop?.metafield?.value;

    if (rawValue) {
      selectedBrands = JSON.parse(rawValue);
    }
  } catch (err) {
    console.error("❌ Failed parsing selected_brands metafield:", err);
  }

  return json({
    brands: brandJson?.data || [],
    collections,
    selectedBrandsFromShopify: selectedBrands,
    shop,
    isSubscribed,
    subscription,
  });
};

export const action = async ({ request }) => {
  const { isSubscribed } = await getSubscriptionDetails(request);

  if (!isSubscribed) {
    return json(
      {
        error:
          "An active subscription or free trial is required to save brand collections.",
      },
      { status: 403 }
    );
  }

  const formData = await request.formData();
  const selectedBrands = JSON.parse(formData.get("selectedBrands") || "[]");
  const selectedOldBrands = JSON.parse(formData.get("selectedOldBrands") || "[]");

  const { session } = await authenticate.admin(request);
  const shop = session.shop;

  selectedBrands.forEach((brand) => {
    delete brand.pricegroups;
  });

  selectedOldBrands.forEach((brand) => {
    delete brand.pricegroups;
  });

  const resp = await fetch("https://backend.data4autos.com/managebrands", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "shop-domain": shop,
    },
    body: JSON.stringify({ shop, selectedBrands, selectedOldBrands }),
  });

  if (!resp.ok) {
    const err = await resp.text();
    return json({ error: err }, { status: resp.status });
  }

  const { processId, status } = await resp.json();
  return json({ processId, status });
};

export default function BrandsPage() {
  const navigate = useNavigate();
  const {
    brands = [],
    selectedBrandsFromShopify = [],
    shop = "",
    error,
    isSubscribed = false,
    subscription = null,
  } = useLoaderData() || {};

  const actionData = useActionData() || {};

  const [selectedIdsold, setSelectedIdsold] = useState([]);
  const [selectedIds, setSelectedIds] = useState(() =>
    (selectedBrandsFromShopify ?? []).map((b) => b.id)
  );
  const [search, setSearch] = useState("");
  const [filteredBrands, setFilteredBrands] = useState(brands);
  const [toastActive, setToastActive] = useState(false);
  const [polling, setPolling] = useState(false);
  const [status, setStatus] = useState(actionData.status || "");
  const [Turn14Enabled, setTurn14Enabled] = useState(null);

  useEffect(() => {
    if (!shop) return;

    (async () => {
      const result = await checkShopExists(shop);
      setTurn14Enabled(result);
    })();
  }, [shop]);

  useEffect(() => {
    setSelectedIdsold(selectedIds);
  }, [toastActive]);

  useEffect(() => {
    const term = search.toLowerCase();
    setFilteredBrands(brands.filter((b) => b.name.toLowerCase().includes(term)));
  }, [search, brands]);

  useEffect(() => {
    if (actionData.status) {
      setStatus(actionData.status);
      setToastActive(true);
    }
  }, [actionData.status]);

  const checkStatus = async () => {
    if (!actionData.processId) return;
    setPolling(true);
    const resp = await fetch(
      `https://backend.data4autos.com/managebrands/status/${actionData.processId}`,
      { headers: { "shop-domain": window.shopify.shop || "" } }
    );
    const jsonBody = await resp.json();
    setStatus(
      jsonBody.status + (jsonBody.detail ? ` (${jsonBody.detail})` : "")
    );
    setPolling(false);
  };

  const toggleSelect = (id) => {
    if (!isSubscribed) return;

    setSelectedIds((prev) =>
      prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]
    );
  };

  const allFilteredSelected =
    filteredBrands.length > 0 &&
    filteredBrands.every((b) => selectedIds.includes(b.id));

  const toggleSelectAll = () => {
    if (!isSubscribed) return;

    const ids = filteredBrands.map((b) => b.id);
    if (allFilteredSelected) {
      setSelectedIds((prev) => prev.filter((id) => !ids.includes(id)));
    } else {
      setSelectedIds((prev) => Array.from(new Set([...prev, ...ids])));
    }
  };

  let isSubmitting = false;
  if (actionData.status) {
    isSubmitting = !actionData.status && !actionData.error && !actionData.processId;
  }

  const toastMarkup = toastActive ? (
    <Toast
      content="Collections updated successfully!"
      onDismiss={() => setToastActive(false)}
    />
  ) : null;

  const selectedBrands = brands.filter((b) => selectedIds.includes(b.id));
  const selectedOldBrands = brands.filter((b) => selectedIdsold.includes(b.id));

  const shopDomain = (shop || "").split(".")[0];

  const items = [
    {
      icon: "⚙️",
      text: "Manage API settings",
      link: `https://admin.shopify.com/store/${shopDomain}/apps/d4a-turn14/app/settings`,
    },
    {
      icon: "🏷️",
      text: "Browse and import available brands",
      link: `https://admin.shopify.com/store/${shopDomain}/apps/d4a-turn14/app/brands`,
    },
    {
      icon: "📦",
      text: "Sync brand collections to Shopify",
      link: `https://admin.shopify.com/store/${shopDomain}/apps/d4a-turn14/app/managebrand`,
    },
    {
      icon: "🔐",
      text: "Handle secure Turn14 login credentials",
      link: `https://admin.shopify.com/store/${shopDomain}/apps/d4a-turn14/app/help`,
    },
  ];

  const trialDaysLeft = useMemo(() => {
    if (!subscription?.trialDays || !subscription?.createdAt) return null;
    if (subscription.status !== "TRIAL") return null;

    const created = new Date(subscription.createdAt);
    const trialEnd = new Date(created);
    trialEnd.setDate(trialEnd.getDate() + subscription.trialDays);

    const now = new Date();
    const msLeft = trialEnd.getTime() - now.getTime();
    const daysLeft = Math.ceil(msLeft / (1000 * 60 * 60 * 24));

    return Math.max(0, daysLeft);
  }, [subscription]);

  if (Turn14Enabled === false) {
    return (
      <Frame>
        <Page fullWidth>
          <TitleBar title="Data4Autos Turn14 Integration" background="critical" />
          <Layout>
            <Layout.Section>
              <Card>
                <div style={{ padding: 24, textAlign: "center" }}>
                  <Text as="h1" variant="headingLg">
                    Turn14 isn’t connected yet
                  </Text>
                  <div style={{ marginTop: 8 }}>
                    <Text as="p" variant="bodyMd">
                      This shop hasn’t been configured with Turn14 / Data4Autos. To get started, open Settings and complete the connection.
                    </Text>
                  </div>

                  <div style={{ marginTop: 24, display: "flex", gap: 16, justifyContent: "center", flexWrap: "wrap" }}>
                    <a href={items[0].link} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none" }}>
                      <Text as="h6" variant="headingMd" fontWeight="bold">
                        {items[0].icon} {items[0].text}
                      </Text>
                    </a>
                    <a href={items[3].link} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none" }}>
                      <Text as="h6" variant="headingMd" fontWeight="bold">
                        {items[3].icon} {items[3].text}
                      </Text>
                    </a>
                  </div>

                  <div style={{ marginTop: 28 }}>
                    <Text as="p" variant="bodySm" tone="subdued">
                      Once connected, you’ll be able to browse brands and sync collections.
                    </Text>
                  </div>

                  <div style={{ marginTop: 20, display: "flex", gap: 16, justifyContent: "center", flexWrap: "wrap" }}>
                    <a href={items[1].link} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none" }}>
                      <Text as="p" variant="bodyMd">
                        {items[1].icon} {items[1].text}
                      </Text>
                    </a>
                    <a href={items[2].link} target="_blank" rel="noopener noreferrer" style={{ textDecoration: "none" }}>
                      <Text as="p" variant="bodyMd">
                        {items[2].icon} {items[2].text}
                      </Text>
                    </a>
                  </div>
                </div>
              </Card>
            </Layout.Section>
          </Layout>
        </Page>
      </Frame>
    );
  }

  return (
    <Frame>
      <Page fullWidth>
        <TitleBar title="Data4Autos Turn14 Integration" background="primary" />

        <div style={{ marginBottom: 16 }}>
          <Text as="h1" variant="headingLg">
            Data4Autos Turn14 Brands List
          </Text>
        </div>

        <Layout>
          {!isSubscribed && (
            <Layout.Section>
              <Banner title="Subscription required" tone="warning">
                <p>
                  This feature is available only for merchants with an active
                  subscription or during the free trial period.
                </p>
                <div style={{ marginTop: 12 }}>
                  <p>
                    <strong>Current status:</strong>{" "}
                    {subscription?.status || "Not subscribed"}
                  </p>
                  <p>
                    <strong>Plan:</strong> {subscription?.name || PLAN_NAME}
                  </p>
                  <p>
                    <strong>Billing:</strong> {getIntervalLabel(subscription?.interval)}
                  </p>
                  <p>
                    <strong>Price:</strong>{" "}
                    {formatMoney(
                      subscription?.priceAmount,
                      subscription?.currencyCode
                    )}
                  </p>
                  <p>
                    <strong>Next renewal / period end:</strong>{" "}
                    {formatDate(subscription?.currentPeriodEnd)}
                  </p>
                  <p>
                    <strong>Trial days left:</strong>{" "}
                    {trialDaysLeft != null ? `${trialDaysLeft} day(s)` : "N/A"}
                  </p>
                </div>
                <div style={{ marginTop: 16 }}>
                  <InlineStack gap="300">
                    <Button variant="primary" onClick={() => navigate("/app")}>
                      Go to Home Page
                    </Button>
                  </InlineStack>
                </div>
              </Banner>
            </Layout.Section>
          )}

          {error && (
            <Layout.Section>
              <Banner title="Error" tone="critical">
                <p>{error}</p>
              </Banner>
            </Layout.Section>
          )}

          {actionData?.error && (
            <Layout.Section>
              <Banner title="Action blocked" tone="critical">
                <p>{actionData.error}</p>
              </Banner>
            </Layout.Section>
          )}

          <Layout.Section>
            <div
              style={{
                position: "sticky",
                top: 0,
                zIndex: 10,
                background: "#ffffff",
                padding: "12px 16px",
                borderRadius: 12,
                boxShadow: "0 1px 6px rgba(0,0,0,0.08)",
                marginBottom: 20,
              }}
            >
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  gap: 16,
                  flexWrap: "wrap",
                }}
              >
                <div style={{ display: "flex", gap: 16, alignItems: "center", flexWrap: "wrap" }}>
                  {(actionData?.processId || false) && (
                    <div>
                      <p>
                        <strong>Process ID:</strong> {actionData.processId}
                      </p>
                      <p>
                        <strong>Status:</strong> {status || "—"}
                      </p>
                      <Button onClick={checkStatus} loading={polling}>
                        Check Status
                      </Button>
                    </div>
                  )}

                  <div style={{ minWidth: 260 }}>
                    <TextField
                      labelHidden
                      label="Search brands"
                      value={search}
                      onChange={setSearch}
                      placeholder="Type brand name…"
                      autoComplete="off"
                      disabled={!isSubscribed}
                    />
                  </div>

                  <Checkbox
                    label="Select All"
                    checked={allFilteredSelected}
                    onChange={toggleSelectAll}
                    disabled={!isSubscribed}
                  />
                </div>

                <Form
                  method="post"
                  style={{ display: "flex", alignItems: "center", gap: 8 }}
                >
                  <input
                    type="hidden"
                    name="selectedBrands"
                    value={JSON.stringify(selectedBrands)}
                  />
                  <input
                    type="hidden"
                    name="selectedOldBrands"
                    value={JSON.stringify(selectedOldBrands)}
                  />
                  <Button
                    primary
                    submit
                    disabled={isSubmitting || !isSubscribed}
                    size="large"
                    variant="primary"
                  >
                    {isSubmitting ? <Spinner size="small" /> : "Save Collections"}
                  </Button>
                </Form>
              </div>
            </div>
          </Layout.Section>

          <Layout.Section>
            <div
              style={{
                display: "grid",
                gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
                gap: 16,
              }}
            >
              {filteredBrands.map((brand) => (
                <Card key={brand.id} sectioned>
                  <div style={{ position: "relative", textAlign: "center" }}>
                    <div style={{ position: "absolute", top: 0, right: 0 }}>
                      <Checkbox
                        label=""
                        checked={selectedIds.includes(brand.id)}
                        onChange={() => toggleSelect(brand.id)}
                        disabled={!isSubscribed}
                      />
                    </div>

                    <div style={{ display: "flex", justifyContent: "center" }}>
                      <Thumbnail
                        source={
                          brand.logo ||
                          "https://cdn.shopify.com/s/files/1/0757/9955/files/no-image_280x@2x.png"
                        }
                        alt={brand.name}
                        size="large"
                      />
                    </div>

                    <div
                      style={{
                        marginTop: "15px",
                        fontWeight: "600",
                        fontSize: "16px",
                        lineHeight: "26px",
                      }}
                    >
                      {brand.name}
                    </div>
                  </div>
                </Card>
              ))}
            </div>
          </Layout.Section>
        </Layout>

        {toastMarkup}
      </Page>
    </Frame>
  );
}