import { useState, useContext, useMemo } from "react";
import { apiFetch } from '@/utils/api';
import { ReactSpreadsheetImport, StepType } from "@/components/product-import";
import type { StepState } from "@/components/product-import/steps/UploadFlow";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Code } from "@/components/ui/code";
import { toast } from "sonner";
import { motion } from "framer-motion";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import config from "@/config";
import { Loader2, AlertCircle, AlertTriangle, Info, CheckCircle, ExternalLink, BookmarkPlus } from "lucide-react";
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
import { Separator } from "@/components/ui/separator";
import type { Data, DataValue, FieldType, Result, SubmitOptions } from "@/components/product-import/types";
import { BASE_IMPORT_FIELDS, type ImportFieldKey } from "@/components/product-import/config";
import { submitNewProducts, type SubmitNewProductsResponse } from "@/services/apiv2";
import { createImportAuditLog } from "@/services/importAuditLogApi";
import { AuthContext } from "@/contexts/AuthContext";
import { TemplateForm } from "@/components/templates/TemplateForm";

type NormalizedProduct = Record<ImportFieldKey | "product_images" | "show_new_product", string | string[] | boolean | null>;
type ImportResult = Result<string> & { all?: Result<string>["validData"] };

interface BackendProductResult {
  pid?: number | string;
  upc?: string | number;
  UPC?: string | number;
  itemnumber?: string | number;
  item_number?: string | number;
  itemNumber?: string | number;
  error?: unknown;
  error_msg?: unknown;
  errors?: unknown;
  message?: unknown;
  reason?: unknown;
  [key: string]: unknown;
}

interface ImportOutcome {
  submittedProducts: NormalizedProduct[];
  submittedRows: Data<string>[];
  response: SubmitNewProductsResponse;
}

const isRecord = (value: unknown): value is Record<string, unknown> =>
  typeof value === "object" && value !== null;

const extractBackendPayload = (
  data: SubmitNewProductsResponse["data"],
): { created: BackendProductResult[]; errored: BackendProductResult[]; queryId: string | null } => {
  if (!isRecord(data)) {
    return { created: [], errored: [], queryId: null };
  }

  const payloadRecord = data as Record<string, unknown>;
  const toList = (value: unknown): BackendProductResult[] =>
    Array.isArray(value) ? (value.filter(isRecord) as BackendProductResult[]) : [];
  const queryIdSource = payloadRecord.query_id ?? payloadRecord.queryId ?? payloadRecord.queryID;
  let queryId: string | null = null;

  if (typeof queryIdSource === "string") {
    const trimmed = queryIdSource.trim();
    queryId = trimmed.length ? trimmed : null;
  } else if (typeof queryIdSource === "number") {
    queryId = queryIdSource.toString();
  }

  return {
    created: toList(payloadRecord.created),
    errored: toList(payloadRecord.errored),
    queryId,
  };
};

const extractStringFromRecord = (record: Record<string, unknown>): string | null => {
  const candidateKeys = ["error_msg", "message", "reason", "error", "detail"];

  for (const key of candidateKeys) {
    const value = record[key];
    if (typeof value === "string") {
      const trimmed = value.trim();
      if (trimmed.length > 0) {
        return trimmed;
      }
    }
  }

  return null;
};

const extractFailureMessageFromResponse = (response: SubmitNewProductsResponse): string | null => {
  if (typeof response.message === "string") {
    const trimmed = response.message.trim();
    if (trimmed.length > 0) {
      return trimmed;
    }
  }

  const { error } = response;

  if (!error) {
    return null;
  }

  if (typeof error === "string") {
    const trimmed = error.trim();
    return trimmed.length > 0 ? trimmed : null;
  }

  if (Array.isArray(error)) {
    for (const entry of error) {
      if (typeof entry === "string") {
        const trimmed = entry.trim();
        if (trimmed.length > 0) {
          return trimmed;
        }
      } else if (isRecord(entry)) {
        const extracted = extractStringFromRecord(entry);
        if (extracted) {
          return extracted;
        }
      }
    }
    return null;
  }

  if (isRecord(error)) {
    return extractStringFromRecord(error);
  }

  return null;
};

const extractErroredEntriesFromResponse = (
  response: SubmitNewProductsResponse,
): BackendProductResult[] => {
  const { error } = response;

  if (!error) {
    return [];
  }

  if (Array.isArray(error)) {
    return error.filter(isRecord) as BackendProductResult[];
  }

  if (isRecord(error)) {
    return [error as BackendProductResult];
  }

  return [];
};

const getFirstStringValue = (value: string | string[] | boolean | null | undefined): string | null => {
  if (Array.isArray(value)) {
    for (const entry of value) {
      if (typeof entry === "string" && entry.trim().length > 0) {
        return entry.trim();
      }
    }
    return null;
  }

  if (typeof value === "string") {
    const trimmed = value.trim();
    return trimmed.length ? trimmed : null;
  }

  return null;
};

const getImageUrlFromValue = (value: string | string[] | boolean | null | undefined): string | null => {
  if (Array.isArray(value)) {
    const first = value.find((entry) => typeof entry === "string" && entry.trim().length > 0);
    return first ? first.trim() : null;
  }

  if (typeof value === "string") {
    const [first] = value
      .split(",")
      .map((part) => part.trim())
      .filter(Boolean);
    return first ?? null;
  }

  return null;
};

const normalizeIdentifierValue = (value: unknown): string | null => {
  if (typeof value === "number") {
    return value.toString();
  }

  if (typeof value === "string") {
    const trimmed = value.trim();
    return trimmed.length ? trimmed : null;
  }

  return null;
};

const findSubmittedProductIndex = (
  submittedProducts: NormalizedProduct[],
  entry: BackendProductResult,
): number => {
  const upcCandidate = normalizeIdentifierValue(entry.upc ?? entry.UPC);
  const itemNumberCandidate = normalizeIdentifierValue(entry.itemnumber ?? entry.item_number ?? entry.itemNumber);

  return submittedProducts.findIndex((product) => {
    const productUpc = normalizeIdentifierValue(getFirstStringValue(product["upc"]));
    const productItemNumber = normalizeIdentifierValue(getFirstStringValue(product["item_number"]));
    return (upcCandidate && productUpc === upcCandidate) || (itemNumberCandidate && productItemNumber === itemNumberCandidate);
  });
};

const formatErrorDetails = (entry: BackendProductResult): string | null => {
  if (typeof entry.error_msg === "string") {
    return entry.error_msg;
  }

  if (typeof entry.error === "string") {
    return entry.error;
  }

  if (Array.isArray(entry.errors)) {
    const details = entry.errors.filter((item): item is string => typeof item === "string");
    if (details.length) {
      return details.join(", ");
    }
  } else if (isRecord(entry.errors)) {
    const segments = Object.entries(entry.errors as Record<string, unknown>).map(([field, issue]) => {
      if (Array.isArray(issue)) {
        const messages = issue.filter((item): item is string => typeof item === "string");
        return `${field}: ${messages.join(", ")}`;
      }

      if (typeof issue === "string") {
        return `${field}: ${issue}`;
      }

      return `${field}: ${JSON.stringify(issue)}`;
    });

    if (segments.length) {
      return segments.join("; ");
    }
  }

  if (typeof entry.message === "string") {
    return entry.message;
  }

  if (typeof entry.reason === "string") {
    return entry.reason;
  }

  return null;
};

export function Import() {
  const [isOpen, setIsOpen] = useState(false);
  const [importOutcome, setImportOutcome] = useState<ImportOutcome | null>(null);
  const [isDebugDataVisible, setIsDebugDataVisible] = useState(false);
  const [resumeStepState, setResumeStepState] = useState<StepState | undefined>();
  const [selectedCompany, setSelectedCompany] = useState<string | null>(null);
  const [selectedLine, setSelectedLine] = useState<string | null>(null);
  const [startFromScratch, setStartFromScratch] = useState(false);
  const [templateSaveDialogOpen, setTemplateSaveDialogOpen] = useState(false);
  const [selectedProductForTemplate, setSelectedProductForTemplate] = useState<NormalizedProduct | null>(null);
  const { user } = useContext(AuthContext);
  const hasDebugPermission = Boolean(user?.is_admin || user?.permissions?.includes("admin:debug"));
  const queryClient = useQueryClient();

  // Fetch initial field options from the API
  const { data: fieldOptions, isLoading: isLoadingOptions } = useQuery({
    queryKey: ["import-field-options"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/import/field-options`);
      if (!response.ok) {
        throw new Error("Failed to fetch field options");
      }
      return response.json();
    },
  });

  // Fetch product lines when company is selected
  const { data: productLines } = useQuery({
    queryKey: ["product-lines", selectedCompany],
    queryFn: async () => {
      if (!selectedCompany) return [];
      const response = await apiFetch(`${config.apiUrl}/import/product-lines/${selectedCompany}`);
      if (!response.ok) {
        throw new Error("Failed to fetch product lines");
      }
      return response.json();
    },
    enabled: !!selectedCompany,
  });

  // Fetch sublines when line is selected
  const { data: sublines } = useQuery({
    queryKey: ["sublines", selectedLine],
    queryFn: async () => {
      if (!selectedLine) return [];
      const response = await apiFetch(`${config.apiUrl}/import/sublines/${selectedLine}`);
      if (!response.ok) {
        throw new Error("Failed to fetch sublines");
      }
      return response.json();
    },
    enabled: !!selectedLine,
  });

  // Handle field value changes
  const handleFieldChange = (field: string, value: any) => {
    if (field === "company") {
      setSelectedCompany(value);
      setSelectedLine(null); // Reset line when company changes
    } else if (field === "line") {
      setSelectedLine(value);
    }
  };

  // Merge base fields with dynamic options
  const importFields = BASE_IMPORT_FIELDS.map(field => {
    if (!fieldOptions) return field;

    switch (field.key) {
      case "company":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.companies || [],
          },
          onChange: (value: string) => {
            handleFieldChange("company", value);
          },
        };
      case "line":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: productLines || [],
          },
          onChange: (value: string) => {
            handleFieldChange("line", value);
          },
          disabled: !selectedCompany,
        };
      case "subline":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: sublines || [],
          },
          disabled: !selectedLine,
        };
      case "colors":
        return {
          ...field,
          fieldType: {
            type: "multi-select" as const,
            options: fieldOptions.colors || [],
          },
        };
      case "tax_cat":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.taxCategories || [],
          },
        };
      case "ship_restrictions":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.shippingRestrictions || [],
          },
        };
      case "supplier":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.suppliers || [],
          },
        };
      case "artist":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.artists || [],
          },
        };
      case "categories":
        return {
          ...field,
          fieldType: {
            type: "multi-select" as const,
            options: fieldOptions.categories || [],
          },
        };
      case "themes":
        return {
          ...field,
          fieldType: {
            type: "multi-select" as const,
            options: fieldOptions.themes || [],
          },
        };
      case "size_cat":
        return {
          ...field,
          fieldType: {
            type: "select" as const,
            options: fieldOptions.sizes || [],
          },
        };
      default:
        return field;
    }
  });

  const getDefaultValue = (fieldType: FieldType): string | string[] | boolean | null => {
    switch (fieldType.type) {
      case "multi-select":
      case "multi-input":
        return [];
      case "checkbox":
        return false;
      default:
        return null;
    }
  };

  const expandScientificNotation = (input: string): string => {
    const trimmed = input.trim();
    const match = trimmed.match(/^(-?\d+)(?:\.(\d+))?[eE]\+?(\d+)$/);

    if (!match) {
      return trimmed;
    }

    const [, integerPart, fractionPart = "", exponentRaw] = match;
    const exponent = Number.parseInt(exponentRaw, 10);
    const digits = `${integerPart}${fractionPart}`;
    const decimalShift = exponent - fractionPart.length;

    if (decimalShift >= 0) {
      return `${digits}${"0".repeat(decimalShift)}`;
    }

    const splitIndex = digits.length + decimalShift;
    if (splitIndex <= 0) {
      const sign = digits.startsWith("-") ? "-" : "";
      const unsignedDigits = sign ? digits.slice(1) : digits;
      return `${sign}0.${"0".repeat(Math.abs(splitIndex))}${unsignedDigits}`;
    }

    const sign = digits.startsWith("-") ? "-" : "";
    const unsignedDigits = sign ? digits.slice(1) : digits;
    return `${sign}${unsignedDigits.slice(0, splitIndex)}.${unsignedDigits.slice(splitIndex)}`;
  };

  const normalizeUpcValue = (value: string): string => {
    // First strip quotes (single, double, smart quotes) and whitespace
    const cleaned = value.replace(/['"'"\s]/g, "");
    // Then handle scientific notation
    const expanded = expandScientificNotation(cleaned);
    // Extract only digits
    const digitsOnly = expanded.replace(/[^0-9]/g, "");
    return digitsOnly || expanded;
  };

  const normalizeValue = (
    key: ImportFieldKey,
    value: DataValue,
    fieldType: FieldType
  ): string | string[] | boolean | null => {
    if (value === undefined || value === null || value === "") {
      return getDefaultValue(fieldType);
    }

    if (fieldType.type === "multi-select" || fieldType.type === "multi-input") {
      if (Array.isArray(value)) {
        return value.length ? value : [];
      }

      if (typeof value === "string") {
        const separator = fieldType.separator ?? ",";
        return value
          .split(separator)
          .map((part) => part.trim())
          .filter(Boolean);
      }

      return [];
    }

    if (Array.isArray(value)) {
      return value.length ? value : [];
    }

    if (typeof value === "boolean") {
      return value;
    }

    const stringValue = String(value);

    if (key === "upc") {
      return normalizeUpcValue(stringValue);
    }

    return stringValue;
  };

  const handleData = async (data: ImportResult, _file: File, submitOptions: SubmitOptions): Promise<boolean> => {
    // Hoist for audit logging in catch block
    const targetEnvironment = submitOptions?.targetEnvironment ?? "prod";
    const useTestDataSource = Boolean(submitOptions?.useTestDataSource);
    const targetEndpoint = targetEnvironment === "dev"
      ? "/apiv2-test/product/setup_new"
      : "/apiv2/product/setup_new";
    let formattedRows: NormalizedProduct[] = [];
    let startTime = performance.now();

    try {
      const rows = ((data.all?.length ? data.all : data.validData) ?? []) as Data<string>[];
      formattedRows = rows.map((row) => {
        const baseValues = importFields.reduce((acc, field) => {
          const rawRow = row as Record<string, DataValue>;
          const fieldKey = field.key as ImportFieldKey;
          acc[fieldKey] = normalizeValue(fieldKey, rawRow[field.key], field.fieldType);
          return acc;
        }, {} as Record<ImportFieldKey, string | string[] | boolean | null>);

        const rawProductImages = (row as Record<string, unknown>).product_images;
        let normalizedProductImages: string | string[] | boolean | null = null;

        if (Array.isArray(rawProductImages)) {
          normalizedProductImages = rawProductImages;
        } else if (typeof rawProductImages === "string" && rawProductImages.trim().length > 0) {
          normalizedProductImages = rawProductImages;
        }

        // Preserve show_new_product flag if it was set
        const showNewProduct = (row as Record<string, unknown>).show_new_product;

        return {
          ...baseValues,
          product_images: normalizedProductImages,
          ...(showNewProduct === true && { show_new_product: true }),
        } as NormalizedProduct;
      });

      // Handle debug mode: skip API submission entirely
      if (submitOptions?.skipApiSubmission) {
        // Generate mock response simulating successful creation
        const mockCreated = formattedRows.map((product, index) => ({
          upc: product.upc,
          item_number: product.item_number,
          pid: `mock-${Date.now()}-${index}`,
        }));

        const mockResponse: SubmitNewProductsResponse = {
          success: true,
          message: `[DEBUG] Skipped API - ${formattedRows.length} product(s) would have been submitted`,
          data: {
            created: mockCreated,
            errored: [],
          },
        };

        setResumeStepState(undefined);
        setImportOutcome({
          submittedProducts: formattedRows.map((product) => ({ ...product })),
          submittedRows: rows.map((row) => ({ ...row })),
          response: mockResponse,
        });
        setIsDebugDataVisible(false);
        setIsOpen(false);
        setStartFromScratch(false);

        toast.success(`[DEBUG] Skipped API submission for ${formattedRows.length} product(s)`);
        return true;
      }

      startTime = performance.now();
      const response = await submitNewProducts({
        products: formattedRows,
        environment: targetEnvironment,
        useTestDataSource,
        employeeId: user?.id ?? undefined,
      });
      const durationMs = Math.round(performance.now() - startTime);

      const isSuccess = response.success;
      const defaultFailureMessage = "Failed to submit products. Please review and try again.";
      const failureEntries = isSuccess ? [] : extractErroredEntriesFromResponse(response);
      const resolvedFailureMessage = isSuccess
        ? null
        : extractFailureMessageFromResponse(response) ?? defaultFailureMessage;

      let normalizedResponse: SubmitNewProductsResponse = response;

      if (!isSuccess) {
        const baseData: Record<string, unknown> = isRecord(response.data)
          ? { ...(response.data as Record<string, unknown>) }
          : {};

        if (failureEntries.length) {
          const existingErrored = baseData["errored"];
          if (!Array.isArray(existingErrored) || existingErrored.length === 0) {
            baseData["errored"] = failureEntries;
          }
        }

        const hasDataOverrides = Object.keys(baseData).length > 0;

        normalizedResponse = {
          ...response,
          success: false,
          message: resolvedFailureMessage ?? defaultFailureMessage,
          data: hasDataOverrides ? baseData : response.data,
        };
      }

      // Audit log — fire-and-forget, never blocks the UI
      const auditPayload = extractBackendPayload(normalizedResponse.data);
      createImportAuditLog({
        user_id: user?.id ?? 0,
        username: user?.username,
        product_count: formattedRows.length,
        request_payload: formattedRows,
        environment: targetEnvironment,
        target_endpoint: targetEndpoint,
        use_test_data_source: useTestDataSource,
        success: isSuccess,
        response_payload: normalizedResponse,
        error_message: isSuccess ? undefined : (resolvedFailureMessage ?? defaultFailureMessage),
        created_count: auditPayload.created.length,
        errored_count: auditPayload.errored.length,
        duration_ms: durationMs,
      });

      setResumeStepState(undefined);
      setImportOutcome({
        submittedProducts: formattedRows.map((product) => ({ ...product })),
        submittedRows: rows.map((row) => ({ ...row })),
        response: normalizedResponse,
      });
      setIsDebugDataVisible(false);
      setIsOpen(false);
      setStartFromScratch(false);

      if (isSuccess) {
        const successMessage =
          normalizedResponse.message ||
          `Submitted ${formattedRows.length} product${formattedRows.length === 1 ? "" : "s"} successfully.`;
        toast.success(successMessage);
      } else {
        toast.error(resolvedFailureMessage ?? defaultFailureMessage);
      }

      return isSuccess;
    } catch (error) {
      // Audit log for thrown errors (network failures, parse errors, etc.)
      createImportAuditLog({
        user_id: user?.id ?? 0,
        username: user?.username,
        product_count: formattedRows.length,
        request_payload: formattedRows,
        environment: targetEnvironment,
        target_endpoint: targetEndpoint,
        use_test_data_source: useTestDataSource,
        success: false,
        error_message: error instanceof Error ? error.message : "Unknown error",
        duration_ms: Math.round(performance.now() - startTime),
      });

      console.error("Import error:", error);
      const errorMessage =
        error instanceof Error ? error.message : "Failed to import data. Please try again.";
      toast.error(errorMessage);
      return false;
    }
  };

  const backendPayload = importOutcome
    ? extractBackendPayload(importOutcome.response.data)
    : { created: [] as BackendProductResult[], errored: [] as BackendProductResult[], queryId: null };
  const productToolUrl = backendPayload.queryId
    ? `https://backend.acherryontop.com/product_tool/${backendPayload.queryId}`
    : null;

  const createdProducts = importOutcome
    ? backendPayload.created.map((entry) => {
        const productIndex = findSubmittedProductIndex(importOutcome.submittedProducts, entry);
        const matchedProduct =
          productIndex >= 0 ? importOutcome.submittedProducts[productIndex] : undefined;
        const responseUpc = normalizeIdentifierValue(entry.upc ?? entry.UPC);
        const responseItemNumber = normalizeIdentifierValue(entry.itemnumber ?? entry.item_number ?? entry.itemNumber);
        const productUpc = normalizeIdentifierValue(getFirstStringValue(matchedProduct ? matchedProduct["upc"] : null));
        const productItemNumber = normalizeIdentifierValue(getFirstStringValue(matchedProduct ? matchedProduct["item_number"] : null));
        const productName = getFirstStringValue(matchedProduct ? matchedProduct["name"] : null);
        const imageUrl = matchedProduct ? getImageUrlFromValue(matchedProduct["product_images"]) : null;
        const pidValue = normalizeIdentifierValue(entry.pid);
        const fallbackLabel = responseItemNumber ?? responseUpc ?? (pidValue ? `PID ${pidValue}` : null);

        return {
          name: productName ?? fallbackLabel ?? "Imported product",
          imageUrl,
          upc: productUpc ?? responseUpc ?? "—",
          itemNumber: productItemNumber ?? responseItemNumber ?? "—",
          url: pidValue ? `https://backend.acherryontop.com/product/${pidValue}` : null,
          pid: pidValue,
          // Store index to access full product data for template saving
          submittedProductIndex: productIndex,
        };
      })
    : [];

  const erroredProducts = importOutcome
    ? backendPayload.errored.map((entry) => {
        const productIndex = findSubmittedProductIndex(importOutcome.submittedProducts, entry);
        const matchedProduct =
          productIndex >= 0 ? importOutcome.submittedProducts[productIndex] : undefined;
        const responseUpc = normalizeIdentifierValue(entry.upc ?? entry.UPC);
        const responseItemNumber = normalizeIdentifierValue(entry.itemnumber ?? entry.item_number ?? entry.itemNumber);
        const productUpc = normalizeIdentifierValue(getFirstStringValue(matchedProduct ? matchedProduct["upc"] : null));
        const productItemNumber = normalizeIdentifierValue(getFirstStringValue(matchedProduct ? matchedProduct["item_number"] : null));
        const productName = getFirstStringValue(matchedProduct ? matchedProduct["name"] : null);
        const imageUrl = matchedProduct ? getImageUrlFromValue(matchedProduct["product_images"]) : null;
        const fallbackLabel = responseItemNumber ?? responseUpc ?? "Imported product";

        return {
          name: productName ?? fallbackLabel,
          imageUrl,
          upc: productUpc ?? responseUpc ?? "—",
          itemNumber: productItemNumber ?? responseItemNumber ?? "—",
          errorDetails: formatErrorDetails(entry),
        };
      })
    : [];

  const erroredRowsForEditing = importOutcome
    ? backendPayload.errored
        .map((entry) => {
          const productIndex = findSubmittedProductIndex(importOutcome.submittedProducts, entry);
          if (productIndex >= 0) {
            const matchedRow = importOutcome.submittedRows[productIndex];
            if (matchedRow) {
              return { ...matchedRow } as Data<string>;
            }
          }

          const matchedProduct =
            productIndex >= 0 ? importOutcome.submittedProducts[productIndex] : undefined;
          const fallbackData: Record<string, DataValue> = {};
          const fallbackUpc = normalizeIdentifierValue(entry.upc ?? entry.UPC);
          const fallbackItemNumber = normalizeIdentifierValue(entry.itemnumber ?? entry.item_number ?? entry.itemNumber);

          if (fallbackUpc) {
            fallbackData["upc"] = fallbackUpc;
          }

          if (fallbackItemNumber) {
            fallbackData["item_number"] = fallbackItemNumber;
          }

          if (matchedProduct) {
            const fallbackName = getFirstStringValue(matchedProduct["name"]);
            if (fallbackName) {
              fallbackData["name"] = fallbackName;
            }

            const productImages = matchedProduct["product_images"];
            if (Array.isArray(productImages) && productImages.length) {
              fallbackData["product_images"] = productImages;
            } else if (typeof productImages === "string" && productImages.trim().length) {
              fallbackData["product_images"] = productImages;
            }
          }

          return Object.keys(fallbackData).length ? (fallbackData as Data<string>) : null;
        })
        .filter((row): row is Data<string> => row !== null)
    : [];

  const hasErroredRowsForEditing = erroredRowsForEditing.length > 0;

  const totalSubmitted = importOutcome?.submittedProducts.length ?? 0;
  const defaultSummary =
    totalSubmitted > 0
      ? `Submitted ${totalSubmitted} product${totalSubmitted === 1 ? "" : "s"} successfully`
      : undefined;
  const summaryMessage = importOutcome?.response.message ?? defaultSummary;

  const handleResumeErroredProducts = () => {
    if (!importOutcome || !hasErroredRowsForEditing) {
      return;
    }

    setResumeStepState({
      type: StepType.validateData,
      data: erroredRowsForEditing.map((row) => ({ ...row })),
    });
    setIsDebugDataVisible(false);
    setStartFromScratch(false);
    setIsOpen(true);
  };

  // Handle opening save template dialog for a created product
  const handleSaveAsTemplate = (product: NormalizedProduct) => {
    setSelectedProductForTemplate(product);
    setTemplateSaveDialogOpen(true);
  };

  // Convert NormalizedProduct to TemplateForm format
  const templateFormData = useMemo(() => {
    if (!selectedProductForTemplate) return null;

    const product = selectedProductForTemplate;

    // Helper to parse numeric values
    const parseNumeric = (val: string | string[] | boolean | null): number | undefined => {
      if (typeof val === 'string') {
        const parsed = parseFloat(val.replace(/[$,]/g, ''));
        return isNaN(parsed) ? undefined : parsed;
      }
      return undefined;
    };

    // Helper to extract string value
    const getString = (val: string | string[] | boolean | null): string | undefined => {
      if (typeof val === 'string') return val || undefined;
      if (Array.isArray(val) && val.length > 0) return val[0];
      return undefined;
    };

    // Helper to extract string array
    const getStringArray = (val: string | string[] | boolean | null): string[] | undefined => {
      if (Array.isArray(val)) return val.length > 0 ? val : undefined;
      if (typeof val === 'string' && val) return [val];
      return undefined;
    };

    return {
      company: getString(product.company) || '',
      product_type: getString(product.name) || '', // Use product name as default type
      supplier: getString(product.supplier),
      msrp: parseNumeric(product.msrp),
      cost_each: parseNumeric(product.cost_each),
      qty_per_unit: parseNumeric(product.qty_per_unit),
      case_qty: parseNumeric(product.case_qty),
      hts_code: getString(product.hts_code),
      description: getString(product.description),
      weight: parseNumeric(product.weight),
      length: parseNumeric(product.length),
      width: parseNumeric(product.width),
      height: parseNumeric(product.height),
      tax_cat: getString(product.tax_cat),
      size_cat: getString(product.size_cat),
      categories: getStringArray(product.categories),
      ship_restrictions: getStringArray(product.ship_restrictions),
    };
  }, [selectedProductForTemplate]);

  // Convert fieldOptions to TemplateForm format
  const templateFieldOptions = useMemo(() => {
    if (!fieldOptions) return null;
    return {
      companies: fieldOptions.companies || [],
      artists: fieldOptions.artists || [],
      sizes: fieldOptions.sizeCategories || [],
      themes: fieldOptions.themes || [],
      categories: fieldOptions.categories || [],
      colors: fieldOptions.colors || [],
      suppliers: fieldOptions.suppliers || [],
      taxCategories: fieldOptions.taxCategories || [],
      shippingRestrictions: fieldOptions.shippingRestrictions || [],
    };
  }, [fieldOptions]);

  // Handle successful template save
  const handleTemplateSaveSuccess = () => {
    setTemplateSaveDialogOpen(false);
    setSelectedProductForTemplate(null);
    // Invalidate templates query if it exists
    queryClient.invalidateQueries({ queryKey: ['templates'] });
  };

  if (isLoadingOptions) {
    return (
      <div className="container mx-auto py-6">
        <div className="flex items-center space-x-2">
          <Loader2 className="h-6 w-6 animate-spin text-primary" />
          <h1 className="text-3xl font-bold tracking-tight">Preparing import options...</h1>
        </div>
      </div>
    );
  }

  return (
    <motion.div 
      layout
      transition={{ 
        layout: { 
          duration: 0.15,
          ease: [0.4, 0, 0.2, 1]
        }
      }}
      className="container mx-auto py-6 space-y-4"
    >
      <motion.div 
        layout="position"
        transition={{ duration: 0.15 }}
        className="flex items-center justify-between"
      >
        <h1 className="text-3xl font-bold tracking-tight">Add New Products</h1>
      </motion.div>

      <Card className="max-w-[400px]">
        <CardHeader>
          <CardTitle>Import Data</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <Button
            onClick={() => {
              setResumeStepState(undefined);
              setIsOpen(true);
            }}
            className="w-full"
          >
            Begin Import
          </Button>
        </CardContent>
      </Card>

      {importOutcome && (
        <Card>
          <CardHeader className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
              <CardTitle>Import Results</CardTitle>
            {hasDebugPermission && (
              <Button
                variant="secondary"
                size="sm"
                onClick={() => setIsDebugDataVisible((prev) => !prev)}
              >
                {isDebugDataVisible ? "Hide Submitted JSON" : "Show Submitted JSON"}
              </Button>
            )}
          </CardHeader>
          <CardContent className="space-y-6">
            {importOutcome.response.success === false ? (
              <Alert className="border-destructive bg-destructive/10">
                <AlertCircle className="h-4 w-4" style={{ color: 'hsl(var(--destructive))' }} />
                <AlertTitle className="text-destructive">Error</AlertTitle>
                <AlertDescription className="text-destructive">
                  {summaryMessage ?? "Products not created - please review details and fix."}
                </AlertDescription>
              </Alert>
            ) : createdProducts.length === totalSubmitted && totalSubmitted > 0 ? (
              <Alert className="border-success bg-success/10">
                <CheckCircle className="h-4 w-4" style={{ color: 'hsl(var(--success))' }} />
                <AlertTitle className="text-success-foreground">Success</AlertTitle>
                <AlertDescription className="text-success-foreground">All products created successfully. Please note that images may take a few minutes to finish uploading before they'll be visible in backend.</AlertDescription>
              </Alert>
            ) : createdProducts.length > 0 && erroredProducts.length > 0 ? (
              <Alert className="border-warning bg-warning/10">
                <AlertTriangle className="h-4 w-4" style={{ color: 'hsl(var(--warning))' }} />
                <AlertTitle className="text-warning-foreground">Partial Success</AlertTitle>
                <AlertDescription className="text-warning-foreground">
                  {createdProducts.length} product{createdProducts.length === 1 ? "" : "s"} created successfully. {erroredProducts.length} product{erroredProducts.length === 1 ? "" : "s"} need attention.
                </AlertDescription>
              </Alert>
            ) : erroredProducts.length > 0 ? (
              <Alert className="border-destructive bg-destructive/10">
                <AlertCircle className="h-4 w-4" style={{ color: 'hsl(var(--destructive))' }} />
                <AlertTitle className="text-destructive-foreground">Error</AlertTitle>
                <AlertDescription className="text-destructive-foreground">
                  {summaryMessage ?? "Products not created - please review details and fix."}
                </AlertDescription>
              </Alert>
            ) : summaryMessage ? (
              <Alert>
                <Info className="h-4 w-4" />
                <AlertTitle>Notice</AlertTitle>
                <AlertDescription>{summaryMessage}</AlertDescription>
              </Alert>
            ) : null}

            {createdProducts.length > 0 && (
              <div className="space-y-3">
                <div className="flex items-center justify-between gap-3">
                  <h3 className="text-lg font-semibold">Created Products</h3>
                  {productToolUrl && (
                    <Button asChild size="sm" variant="default">
                      <a href={productToolUrl} target="_blank" rel="noreferrer">
                        View in Product Tool
                        <ExternalLink />
                      </a>
                    </Button>
                  )}
                </div>
                <div className="grid gap-3">
                  {createdProducts.map((product, index) => {
                    const key = product.pid ?? product.upc ?? product.itemNumber ?? index;
                    const imageContent = product.imageUrl ? (
                      <img src={product.imageUrl} alt={product.name} className="h-full w-full object-cover" />
                    ) : (
                      <div className="flex h-full w-full items-center justify-center text-xs text-muted-foreground">
                        No Image
                      </div>
                    );

                    return (
                      <div key={key} className="flex items-start gap-4 rounded-md p-1 transition-colors">
                        {product.url ? (
                          <a
                            href={product.url}
                            target="_blank"
                            rel="noreferrer"
                            className="block h-16 w-16 shrink-0 overflow-hidden rounded-md border bg-muted"
                          >
                            {imageContent}
                          </a>
                        ) : (
                          <div className="block h-16 w-16 shrink-0 overflow-hidden rounded-md border bg-muted">
                            {imageContent}
                          </div>
                        )}
                        <div className="flex flex-col gap-1 flex-1">
                          <div className="flex items-start justify-between gap-2">
                            <div className="flex items-center gap-2 flex-1">
                              {product.url ? (
                                <a
                                  href={product.url}
                                  target="_blank"
                                  rel="noreferrer"
                                  className="text-sm font-medium text-primary hover:underline flex items-center gap-1.5"
                                >
                                  {product.name}
                                  <Tooltip>
                                    <TooltipTrigger asChild>
                                      <span>
                                        <ExternalLink className="h-3.5 w-3.5 shrink-0" />
                                      </span>
                                    </TooltipTrigger>
                                    <TooltipContent>
                                      <p>View in Backend</p>
                                    </TooltipContent>
                                  </Tooltip>
                                </a>
                              ) : (
                                <span className="text-sm font-medium">{product.name}</span>
                              )}
                            </div>
                            {product.submittedProductIndex !== undefined && product.submittedProductIndex >= 0 && importOutcome && (
                              <Button
                                variant="ghost"
                                size="sm"
                                className="h-7 px-2 gap-1.5"
                                onClick={() => handleSaveAsTemplate(importOutcome.submittedProducts[product.submittedProductIndex])}
                              >
                                <BookmarkPlus className="h-4 w-4" />
                                <span className="text-xs">Save as Template</span>
                              </Button>
                            )}
                          </div>
                          <div className="flex items-start justify-between gap-2">
                            <div className="flex flex-col gap-0.5">
                              <span className="text-xs text-muted-foreground">
                                UPC: {product.upc}
                              </span>
                              <span className="text-xs text-muted-foreground">Item #: {product.itemNumber}</span>
                            </div>
                           
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}

            {erroredProducts.length > 0 && (
              <div className="space-y-3">
                <div className="flex items-center justify-between">
                  <h3 className="text-lg font-semibold text-destructive">Products with Errors</h3>
                  {hasErroredRowsForEditing && (
                    <Button size="sm" onClick={handleResumeErroredProducts} variant="default">
                      Fix products with errors
                    </Button>
                  )}
                </div>
                <div className="grid gap-3 border border-destructive rounded-md p-2">
                  {erroredProducts.map((product, index) => (
                    <div key={product.upc ?? product.itemNumber ?? index} className="flex items-start gap-4 p-1">
                      <div className="block h-16 w-16 shrink-0 overflow-hidden rounded-md border bg-muted">
                        {product.imageUrl ? (
                          <img src={product.imageUrl} alt={product.name} className="h-full w-full object-cover" />
                        ) : (
                          <div className="flex h-full w-full items-center justify-center text-xs text-muted-foreground">
                            No Image
                          </div>
                        )}
                      </div>
                      <div className="flex flex-col gap-1">
                        <span className="text-sm font-medium">{product.name}</span>
                        <div className="flex items-center gap-3">
                        <span className="text-xs text-muted-foreground">UPC: {product.upc}</span>
                        <Separator orientation="vertical" className="h-3" />
                        <span className="text-xs text-muted-foreground">Item #: {product.itemNumber}</span>
                        </div>
                        {product.errorDetails && (
                          <div className="px-2 pb-0.5 rounded-md bg-destructive/10 border border-destructive/20">
                            <span className="text-xs text-destructive">{product.errorDetails}</span>
                          </div>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {hasDebugPermission && isDebugDataVisible && (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold">Submitted Data</h3>
                <Code className="p-4 w-full rounded-md border whitespace-pre-wrap">
                  {JSON.stringify(importOutcome.submittedProducts, null, 2)}
                </Code>
              </div>
            )}
          </CardContent>
        </Card>
      )}

      <ReactSpreadsheetImport
        isOpen={isOpen}
        onClose={() => {
          setIsOpen(false);
          setStartFromScratch(false);
          setResumeStepState(undefined);
        }}
        onSubmit={handleData}
        fields={importFields}
        isNavigationEnabled={true}
        initialStepState={
          resumeStepState ??
          (startFromScratch
            ? { type: StepType.validateData, data: [{}], isFromScratch: true }
            : undefined)
        }
      />

      {/* Template Save Dialog */}
      <TemplateForm
        isOpen={templateSaveDialogOpen}
        onClose={() => {
          setTemplateSaveDialogOpen(false);
          setSelectedProductForTemplate(null);
        }}
        onSuccess={handleTemplateSaveSuccess}
        initialData={templateFormData}
        mode="create"
        fieldOptions={templateFieldOptions}
      />
    </motion.div>
  );
}
