import React, { useState } from "react";
import { json } from "@remix-run/node";
import { useLoaderData, Form, useActionData } from "@remix-run/react";
import {
  Page,
  Layout,
  Card,
  Thumbnail,
  TextContainer,
  Spinner,
  Button,
  TextField,
  Banner,
  InlineError,
} from "@shopify/polaris";
import { authenticate } from "../shopify.server";

// Load selected brands and access token from Shopify metafield
export const loader = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const { getTurn14AccessTokenFromMetafield } = await import(
    "../utils/turn14Token.server"
  );
  const accessToken = await getTurn14AccessTokenFromMetafield(request);

  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;

  let brands = [];
  try {
    brands = JSON.parse(rawValue);
  } catch (err) {
    console.error("❌ Failed to parse metafield value:", err);
  }

  return json({ brands, accessToken });
};

// Handle adding products for a specific brand
export const action = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const formData = await request.formData();
  const brandId = formData.get("brandId");
  const rawCount = formData.get("productCount");
  const productCount = parseInt(rawCount, 10) || 10;

  const { getTurn14AccessTokenFromMetafield } = await import(
    "../utils/turn14Token.server"
  );
  const accessToken = await getTurn14AccessTokenFromMetafield(request);

  // Fetch items from Turn14 API
  const itemsRes = await fetch(
    `https://turn14.data4autos.com/v1/items/brandallitems/${brandId}`,
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      },
    }
  );
  const itemsData = await itemsRes.json();

  function slugify(str) {
    return str
      .toString()
      .trim()
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-+|-+$/g, '');
  }

  const items1 = Array.isArray(itemsData) ? itemsData.slice(0, productCount) : [];
  const results = [];
  for (const item of items1) {
    const attrs = item.attributes;

    // 0️⃣ Build and normalize collection titles
    const category = attrs.category;
    const subcategory = attrs.subcategory || "";
    const brand = attrs.brand;
    const subcats = subcategory
      .split(/[,\/]/)
      .map((s) => s.trim())
      .filter(Boolean);
    const collectionTitles = Array.from(
      new Set([category, ...subcats, brand].filter(Boolean))
    );

    // 1️⃣ Find or create collections, collect their IDs
    const collectionIds = [];
    for (const title of collectionTitles) {
      // lookup
      const lookupRes = await admin.graphql(`
      {
        collections(first: 1, query: "title:\\"${title}\\" AND collection_type:manual") {
          nodes { id }
        }
      }
    `);
      const lookupJson = await lookupRes.json();
      const existing = lookupJson.data.collections.nodes;
      if (existing.length) {
        collectionIds.push(existing[0].id);
      } else {
        // create
        const createColRes = await admin.graphql(`
        mutation($input: CollectionInput!) {
          collectionCreate(input: $input) {
            collection { id }
            userErrors { field message }
          }
        }
      `, { variables: { input: { title } } });
        const createColJson = await createColRes.json();
        const errs = createColJson.data.collectionCreate.userErrors;
        if (errs.length) {
          throw new Error(`Could not create collection "${title}": ${errs.map(e => e.message).join(", ")}`);
        }
        collectionIds.push(createColJson.data.collectionCreate.collection.id);
      }
    }

    // 2️⃣ Build tags
    const tags = [
      attrs.category,
      ...subcats,
      attrs.brand,
      attrs.part_number,
      attrs.mfr_part_number,
      attrs.price_group,
      attrs.units_per_sku && `${attrs.units_per_sku} per SKU`,
      attrs.barcode
    ].filter(Boolean).map((t) => t.trim());

    // 3️⃣ Prepare media inputs
    const mediaInputs = (attrs.files || [])
      .filter((f) => f.type === "Image" && f.url)
      .map((file) => ({
        originalSource: file.url,
        mediaContentType: "IMAGE",
        alt: `${attrs.product_name} — ${file.media_content}`,
      }));


    // 2️⃣ Pick the longest “Market Description” or fallback to part_description
    const marketDescs = (attrs.descriptions || [])
      .filter((d) => d.type === "Market Description")
      .map((d) => d.description);
    const descriptionHtml = marketDescs.length
      ? marketDescs.reduce((a, b) => (b.length > a.length ? b : a))
      : attrs.part_description;

    // 4️⃣ Create product + attach to collections + add media
    const createProdRes = await admin.graphql(`
    mutation($prod: ProductCreateInput!, $media: [CreateMediaInput!]) {
      productCreate(product: $prod, media: $media) {
        product {
          id
          variants(first: 1) {
            nodes { id inventoryItem { id } }
          }
        }
        userErrors { field message }
      }
    }
  `, {
      variables: {
        prod: {
          title: attrs.product_name,
          descriptionHtml: descriptionHtml,
          vendor: attrs.brand,
          productType: attrs.category,
          handle: slugify(attrs.part_number || attrs.product_name),
          tags,
          collectionsToJoin: collectionIds,
          status: "ACTIVE",
        },
        media: mediaInputs,
      },
    });
    const createProdJson = await createProdRes.json();
    const prodErrs = createProdJson.data.productCreate.userErrors;
    if (prodErrs.length) {
      const taken = prodErrs.some((e) => /already in use/i.test(e.message));
      if (taken) {
        results.push({ skippedHandle: attrs.part_number, reason: "handle in use" });
        continue;
      }
      throw new Error(`ProductCreate errors: ${prodErrs.map(e => e.message).join(", ")}`);
    }

    const product = createProdJson.data.productCreate.product;
    const variantNode = product.variants.nodes[0];
    const variantId = variantNode.id;
    const inventoryItemId = variantNode.inventoryItem.id;

    // 5️⃣ Bulk-update variant (price, compare-at, barcode)
    const price = parseFloat(attrs.price) || 1000;
    const comparePrice = parseFloat(attrs.compare_price) || null;
    const barcode = attrs.barcode || "";

    const bulkRes = await admin.graphql(`
    mutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
      productVariantsBulkUpdate(productId: $productId, variants: $variants) {
        productVariants { id price compareAtPrice barcode }
        userErrors { field message }
      }
    }
  `, {
      variables: {
        productId: product.id,
        variants: [{
          id: variantId,
          price,
          ...(comparePrice !== null && { compareAtPrice: comparePrice }),
          ...(barcode && { barcode }),
        }],
      },
    });
    const bulkJson = await bulkRes.json();
    const bulkErrs = bulkJson.data.productVariantsBulkUpdate.userErrors;
    if (bulkErrs.length) {
      throw new Error(`Bulk update errors: ${bulkErrs.map(e => e.message).join(", ")}`);
    }
    const updatedVariant = bulkJson.data.productVariantsBulkUpdate.productVariants[0];

    // 6️⃣ Update inventory item (SKU, cost & weight)
    const costPerItem = parseFloat(attrs.purchase_cost) || 0;
    const weightValue = parseFloat(attrs.dimensions?.[0]?.weight) || 0;

    const invRes = await admin.graphql(`
    mutation($id: ID!, $input: InventoryItemInput!) {
      inventoryItemUpdate(id: $id, input: $input) {
        inventoryItem {
          id
          sku
          measurement {
            weight { value unit }
          }
        }
        userErrors { field message }
      }
    }
  `, {
      variables: {
        id: inventoryItemId,
        input: {
          sku: attrs.part_number,
          cost: costPerItem,
          measurement: {
            weight: { value: weightValue, unit: "POUNDS" }
          },
        },
      },
    });
    const invJson = await invRes.json();
    const invErrs = invJson.data.inventoryItemUpdate.userErrors;
    if (invErrs.length) {
      throw new Error(`Inventory update errors: ${invErrs.map(e => e.message).join(", ")}`);
    }
    const inventoryItem = invJson.data.inventoryItemUpdate.inventoryItem;

    // 7️⃣ Collect results
    results.push({
      productId: product.id,
      variant: {
        id: updatedVariant.id,
        price: updatedVariant.price,
        compareAtPrice: updatedVariant.compareAtPrice,
        sku: inventoryItem.sku,
        barcode: updatedVariant.barcode,
        weight: inventoryItem.measurement.weight.value,
        weightUnit: inventoryItem.measurement.weight.unit,
      },
      collections: collectionTitles,
      tags,
    });
  }




  return json({ success: true, results });
};

// Main React component for managing brand products
export default function ManageBrandProducts() {
  const actionData = useActionData();
  const { brands, accessToken } = useLoaderData();
  const [expandedBrand, setExpandedBrand] = useState(null);
  const [itemsMap, setItemsMap] = useState({});
  const [loadingMap, setLoadingMap] = useState({});
  const [productCount, setProductCount] = useState("10");

  const toggleBrandItems = async (brandId) => {
    const isExpanded = expandedBrand === brandId;
    if (isExpanded) {
      setExpandedBrand(null);
    } else {
      setExpandedBrand(brandId);
      if (!itemsMap[brandId]) {
        setLoadingMap((prev) => ({ ...prev, [brandId]: true }));
        try {
          const res = await fetch(`https://turn14.data4autos.com/v1/items/brand/${brandId}?page=1`, {
            headers: {
              Authorization: `Bearer ${accessToken}`,
              "Content-Type": "application/json",
            },
          });
          const data = await res.json();
          setItemsMap((prev) => ({ ...prev, [brandId]: data }));
        } catch (err) {
          console.error("Error fetching items:", err);
        }
        setLoadingMap((prev) => ({ ...prev, [brandId]: false }));
      }
    }
  };

  return (
    <Page title="Manage Brand Products">
      <Layout>
        {brands.length === 0 && (
          <Layout.Section>
            <Card sectioned>
              <p>No brands selected yet.</p>
            </Card>
          </Layout.Section>
        )}

        {brands.map((brand) => (
          <React.Fragment key={brand.id}>
            <Layout.Section oneThird>
              <Card title={brand.name} sectioned>
                <Thumbnail
                  source={
                    brand.logo ||
                    "https://cdn.shopify.com/s/files/1/0757/9955/files/no-image_280x@2x.png"
                  }
                  alt={brand.name}
                  size="large"
                />
                <TextContainer spacing="tight">
                  <p><strong>ID:</strong> {brand.id}</p>
                </TextContainer>
                <Button fullWidth onClick={() => toggleBrandItems(brand.id)}>
                  {expandedBrand === brand.id ? "Hide Products" : "Show Products"}
                </Button>
              </Card>
            </Layout.Section>

            {expandedBrand === brand.id && (
              <Layout.Section fullWidth>
                <Card sectioned>
                  {actionData?.success && (
                    <Banner title="✅ Product created!" status="success">
                      <p>
                        {actionData.results.map((r) => (
                          <span key={r.variant.id}>
                            Product {r.productId} – Variant {r.variant.id} @ ${r.variant.price} (SKU: {r.variant.sku})<br />
                          </span>
                        ))}
                      </p>
                    </Banner>
                  )}
                  <Form method="post">
                    <input type="hidden" name="brandId" value={brand.id} />
                    <TextField
                      label="Number of products to add"
                      type="number"
                      name="productCount"
                      value={productCount}
                      onChange={setProductCount}
                      autoComplete="off"
                    />
                    <Button submit primary style={{ marginTop: '1rem' }}>
                      Add First {productCount} Products to Store
                    </Button>
                  </Form>
                </Card>

                <Card title={`Items from ${brand.name}`} sectioned>
                  {loadingMap[brand.id] ? (
                    <Spinner accessibilityLabel="Loading items" size="small" />
                  ) : (
                    <div style={{ paddingTop: "1rem" }}>
                      {(itemsMap[brand.id] || []).map((item) => (
                        <Card key={item.id} title={item.attributes.product_name} sectioned>
                          <Layout>
                            <Layout.Section oneThird>
                              <Thumbnail
                                source={
                                  item.attributes.thumbnail ||
                                  "https://cdn.shopify.com/s/files/1/0757/9955/files/no-image_280x@2x.png"
                                }
                                alt={item.attributes.product_name}
                                size="large"
                              />
                            </Layout.Section>
                            <Layout.Section>
                              <TextContainer spacing="tight">
                                <p><strong>Part Number:</strong> {item.attributes.part_number}</p>
                                <p><strong>Category:</strong> {item.attributes.category} &gt; {item.attributes.subcategory}</p>
                              </TextContainer>
                            </Layout.Section>
                          </Layout>
                        </Card>
                      ))}
                    </div>
                  )}
                </Card>
              </Layout.Section>
            )}
          </React.Fragment>
        ))}
      </Layout>
    </Page>
  );
}
