import React, { useState, useCallback, useRef } from "react";
import { __ } from "@wordpress/i18n";
import {
  Download,
  Upload,
  Wand2,
  AlertTriangle,
  CheckCircle2,
  Info,
} from "lucide-react";
import DefaultPageLayout from "@/components/DefaultPageLayout";
import { ToastContainer, useToast } from "@libs/toast";
import Modal from "@libs/modal";
import useModal from "@libs/modal/useModal";
import { buildUrl } from "@libs/url";
import SetupWizard from "./wizard/SetupWizard";

const SECTION_LABELS = {
  subscription_settings: {
    label: __("Subscription & Others", "arraysubs"),
    description: __(
      "Billing, renewals, checkout, trials, plan switching, proration, refunds, and all core/pro subscription settings",
      "arraysubs",
    ),
  },
  retention_flow: {
    label: __("Retention Flow Builder", "arraysubs"),
    description: __(
      "Cancellation reasons, retention offers, and cancellation flow settings",
      "arraysubs",
    ),
  },
  store_credit: {
    label: __("Store Credit", "arraysubs"),
    description: __(
      "Store credit feature configuration and related settings",
      "arraysubs",
    ),
  },
  myaccount_builder: {
    label: __("My Account Builder", "arraysubs"),
    description: __(
      "My Account page menu items, labels, and positions",
      "arraysubs",
    ),
  },
  checkout_builder: {
    label: __("Checkout Builder", "arraysubs"),
    description: __(
      "Custom checkout field layout and configuration",
      "arraysubs",
    ),
  },
  members_access: {
    label: __("Member Access", "arraysubs"),
    description: __(
      "Content restriction rules, role mapping, and access control settings",
      "arraysubs",
    ),
  },
  emails: {
    label: __("Emails", "arraysubs"),
    description: __(
      "Email notification preferences and WooCommerce email template settings (subject, heading, content)",
      "arraysubs",
    ),
  },
  profile_fields: {
    label: __("Profile Fields", "arraysubs"),
    description: __(
      "Custom profile field definitions, validation rules, and avatar settings",
      "arraysubs",
    ),
  },
};

/**
 * Determine which virtual sections are available from parsed export data.
 *
 * @param {object} options - The parsed options object from the export JSON.
 * @return {string[]} Array of available section IDs in display order.
 */
const getAvailableSections = (options) => {
  if (!options) {
    return [];
  }

  const available = new Set();
  const settings = options.arraysubs_settings;

  if (settings && typeof settings === "object") {
    // Claimed sub-keys that belong to specific sections.
    const claimedKeys = [
      "cancellation",
      "store_credit",
      "checkout_builder",
      "members_access",
      "emails",
    ];

    if (settings.cancellation !== undefined) {
      available.add("retention_flow");
    }
    if (settings.store_credit !== undefined) {
      available.add("store_credit");
    }
    if (settings.checkout_builder !== undefined) {
      available.add("checkout_builder");
    }
    if (settings.members_access !== undefined) {
      available.add("members_access");
    }
    if (
      settings.emails !== undefined ||
      options.wc_email_settings !== undefined
    ) {
      available.add("emails");
    }

    // subscription_settings: any key NOT in claimedKeys.
    const hasOtherKeys = Object.keys(settings).some(
      (key) => !claimedKeys.includes(key),
    );
    if (hasOtherKeys) {
      available.add("subscription_settings");
    }
  } else if (options.wc_email_settings !== undefined) {
    available.add("emails");
  }

  if (options.arraysubs_myaccount_menu_config) {
    available.add("myaccount_builder");
  }
  if (
    options.arraysubs_profile_fields_config ||
    options.arraysubs_avatar_settings
  ) {
    available.add("profile_fields");
  }

  // Return in preferred display order.
  const displayOrder = [
    "retention_flow",
    "store_credit",
    "myaccount_builder",
    "checkout_builder",
    "members_access",
    "emails",
    "profile_fields",
    "subscription_settings",
  ];

  return displayOrder.filter((id) => available.has(id));
};

const EasySetup = () => {
  const { toasts, showToast, removeToast } = useToast();
  const { env } = window.arraySubs;

  const [exporting, setExporting] = useState(false);

  // Import flow states
  const [importStep, setImportStep] = useState("idle"); // idle | paste | select | confirming | importing
  const [jsonText, setJsonText] = useState("");
  const [parsedData, setParsedData] = useState(null);
  const [parseError, setParseError] = useState("");
  const [selectedSections, setSelectedSections] = useState({});
  const [importResult, setImportResult] = useState(null);
  const fileInputRef = useRef(null);
  const wizardModal = useModal();

  const handleExport = useCallback(async () => {
    setExporting(true);
    try {
      const url = buildUrl(`${env?.apiBaseUrl}arraysubs/v1/easy-setup/export`);
      const response = await fetch(url, {
        headers: {
          "X-WP-Nonce": env?.nonce,
        },
      });

      if (!response.ok) {
        const errBody = await response.json().catch(() => null);
        throw new Error(
          errBody?.message || __("Failed to export settings", "arraysubs"),
        );
      }

      const result = await response.json();
      const exportData = result?.content || result;

      const blob = new Blob([JSON.stringify(exportData, null, 2)], {
        type: "application/json",
      });
      const downloadUrl = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = downloadUrl;

      const date = new Date().toISOString().slice(0, 10);
      link.download = `arraysubs-settings-${date}.json`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(downloadUrl);

      showToast(__("Settings exported successfully!", "arraysubs"), "success");
    } catch (error) {
      showToast(error.message, "error");
    } finally {
      setExporting(false);
    }
  }, [env, showToast]);

  const handleStartImport = useCallback(() => {
    setImportStep("paste");
    setJsonText("");
    setParsedData(null);
    setParseError("");
    setSelectedSections({});
    setImportResult(null);
  }, []);

  const processJsonString = useCallback((raw) => {
    const trimmed = raw.trim();
    if (!trimmed) {
      setParseError(
        __(
          "Please paste your exported JSON data or select a file",
          "arraysubs",
        ),
      );
      return;
    }

    try {
      const data = JSON.parse(trimmed);

      if (!data.meta || !data.options) {
        setParseError(
          __(
            "Invalid export format — missing required structure (meta and options)",
            "arraysubs",
          ),
        );
        return;
      }

      if (typeof data.options !== "object" || Array.isArray(data.options)) {
        setParseError(
          __("Invalid export format — options must be an object", "arraysubs"),
        );
        return;
      }

      const availableKeys = getAvailableSections(data.options);

      if (availableKeys.length === 0) {
        setParseError(
          __("No recognized settings found in this export file", "arraysubs"),
        );
        return;
      }

      setParsedData(data);
      setParseError("");

      const initial = {};
      availableKeys.forEach((key) => {
        initial[key] = true;
      });
      setSelectedSections(initial);
      setImportStep("select");
    } catch {
      setParseError(
        __("Invalid JSON format — please check the pasted data", "arraysubs"),
      );
    }
  }, []);

  const handleContinueParse = useCallback(() => {
    processJsonString(jsonText);
  }, [jsonText, processJsonString]);

  const handleFileSelect = useCallback(
    (e) => {
      const file = e.target.files?.[0];
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
      if (!file) {
        return;
      }

      const reader = new FileReader();
      reader.onload = (event) => {
        const text = event.target?.result || "";
        setJsonText(text);
        processJsonString(text);
      };
      reader.onerror = () => {
        setParseError(__("Failed to read the selected file", "arraysubs"));
      };
      reader.readAsText(file);
    },
    [processJsonString],
  );

  const handleToggleSection = useCallback((key) => {
    setSelectedSections((prev) => ({
      ...prev,
      [key]: !prev[key],
    }));
  }, []);

  const handleToggleAll = useCallback(() => {
    setSelectedSections((prev) => {
      const allChecked = Object.values(prev).every((v) => v);
      const next = {};
      Object.keys(prev).forEach((key) => {
        next[key] = !allChecked;
      });
      return next;
    });
  }, []);

  const getSelectedKeys = useCallback(() => {
    return Object.entries(selectedSections)
      .filter(([, checked]) => checked)
      .map(([key]) => key);
  }, [selectedSections]);

  const handleConfirmImport = useCallback(() => {
    if (getSelectedKeys().length === 0) {
      showToast(
        __("Please select at least one section to import", "arraysubs"),
        "error",
      );
      return;
    }
    setImportStep("confirming");
  }, [getSelectedKeys, showToast]);

  const handleImport = useCallback(async () => {
    setImportStep("importing");
    try {
      const url = buildUrl(`${env?.apiBaseUrl}arraysubs/v1/easy-setup/import`);
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-WP-Nonce": env?.nonce,
        },
        body: JSON.stringify({
          data: parsedData,
          sections: getSelectedKeys(),
        }),
      });

      if (!response.ok) {
        const errBody = await response.json().catch(() => null);
        throw new Error(
          errBody?.message || __("Failed to import settings", "arraysubs"),
        );
      }

      const result = await response.json();
      const resultData = result?.content || result;

      setImportResult(resultData);
      setImportStep("idle");
      showToast(__("Settings imported successfully!", "arraysubs"), "success");
    } catch (error) {
      setImportStep("select");
      showToast(error.message, "error");
    }
  }, [env, parsedData, getSelectedKeys, showToast]);

  const handleCancelImport = useCallback(() => {
    setImportStep("idle");
    setJsonText("");
    setParsedData(null);
    setParseError("");
    setSelectedSections({});
    setImportResult(null);
  }, []);

  const availableSectionKeys = parsedData
    ? getAvailableSections(parsedData.options)
    : [];

  return (
    <DefaultPageLayout
      title={__("Easy Setup", "arraysubs")}
      subtitle={__(
        "Export or import your ArraySubs settings to quickly clone your configuration across sites",
        "arraysubs",
      )}
    >
      <div className="arraysubs-easy-setup">
        <div className="arraysubs-easy-setup__card">
          <div className="arraysubs-easy-setup__card-header">
            <Wand2 size={20} />
            <h3>{__("Setup Wizard", "arraysubs")}</h3>
          </div>
          <p className="arraysubs-easy-setup__card-description">
            {__(
              "Answer a guided set of questions about your subscription business and let the wizard configure the most important settings for you.",
              "arraysubs",
            )}
          </p>
          <button
            type="button"
            className="button button-primary"
            onClick={wizardModal.open}
          >
            {__("Launch Setup Wizard", "arraysubs")}
          </button>
        </div>

        {/* Export Section */}
        <div className="arraysubs-easy-setup__card">
          <div className="arraysubs-easy-setup__card-header">
            <Download size={20} />
            <h3>{__("Export Settings", "arraysubs")}</h3>
          </div>
          <p className="arraysubs-easy-setup__card-description">
            {__(
              "Download all your ArraySubs settings as a JSON file. This includes subscription settings, retention flow, emails, member access, profile fields, My Account menu layout, and more.",
              "arraysubs",
            )}
          </p>
          <button
            type="button"
            className="button button-primary"
            onClick={handleExport}
            disabled={exporting}
          >
            {exporting
              ? __("Exporting...", "arraysubs")
              : __("Export Settings", "arraysubs")}
          </button>
        </div>

        {/* Import Section */}
        <div className="arraysubs-easy-setup__card">
          <div className="arraysubs-easy-setup__card-header">
            <Upload size={20} />
            <h3>{__("Import Settings", "arraysubs")}</h3>
          </div>
          <p className="arraysubs-easy-setup__card-description">
            {__(
              "Select a previously exported JSON file or paste its contents to restore settings. You can selectively choose which sections to import — unchecked sections will remain untouched.",
              "arraysubs",
            )}
          </p>

          {importStep === "idle" && !importResult && (
            <button
              type="button"
              className="button button-secondary"
              onClick={handleStartImport}
            >
              {__("Import Settings", "arraysubs")}
            </button>
          )}

          {/* Step 1: Paste JSON or select file */}
          {importStep === "paste" && (
            <div className="arraysubs-easy-setup__import-paste">
              <div className="arraysubs-easy-setup__file-picker">
                <input
                  ref={fileInputRef}
                  type="file"
                  accept=".json,application/json"
                  onChange={handleFileSelect}
                  className="arraysubs-easy-setup__file-input"
                />
                <button
                  type="button"
                  className="button button-secondary"
                  onClick={() => fileInputRef.current?.click()}
                >
                  {__("Choose JSON File", "arraysubs")}
                </button>
                <span className="arraysubs-easy-setup__file-divider">
                  {__("or paste below", "arraysubs")}
                </span>
              </div>
              <textarea
                className="arraysubs-easy-setup__textarea"
                rows={10}
                placeholder={__(
                  "Paste your exported JSON data here...",
                  "arraysubs",
                )}
                value={jsonText}
                onChange={(e) => {
                  setJsonText(e.target.value);
                  setParseError("");
                }}
              />
              {parseError && (
                <div className="arraysubs-easy-setup__error">
                  <AlertTriangle size={16} />
                  <span>{parseError}</span>
                </div>
              )}
              <div className="arraysubs-easy-setup__actions">
                <button
                  type="button"
                  className="button button-primary"
                  onClick={handleContinueParse}
                >
                  {__("Continue", "arraysubs")}
                </button>
                <button
                  type="button"
                  className="button button-link"
                  onClick={handleCancelImport}
                >
                  {__("Cancel", "arraysubs")}
                </button>
              </div>
            </div>
          )}

          {/* Step 2: Select Sections */}
          {importStep === "select" && parsedData && (
            <div className="arraysubs-easy-setup__import-select">
              {parsedData.meta && (
                <div className="arraysubs-easy-setup__meta">
                  <Info size={16} />
                  <div>
                    <span>
                      {__("Source:", "arraysubs")}{" "}
                      <strong>{parsedData.meta.site_url}</strong>
                    </span>
                    {parsedData.meta.export_date && (
                      <span>
                        {" — "}
                        {__("Exported:", "arraysubs")}{" "}
                        {new Date(
                          parsedData.meta.export_date,
                        ).toLocaleDateString()}
                      </span>
                    )}
                    {parsedData.meta.plugin_version && (
                      <span>
                        {" — "}
                        {__("v", "arraysubs")}
                        {parsedData.meta.plugin_version}
                      </span>
                    )}
                  </div>
                </div>
              )}

              <div className="arraysubs-easy-setup__note">
                <AlertTriangle size={16} />
                <span>
                  {__(
                    "Settings that reference site-specific IDs (products, pages, categories) may need to be re-mapped manually after import.",
                    "arraysubs",
                  )}
                </span>
              </div>

              <div className="arraysubs-easy-setup__sections">
                <label className="arraysubs-easy-setup__section-toggle-all">
                  <input
                    type="checkbox"
                    checked={Object.values(selectedSections).every((v) => v)}
                    onChange={handleToggleAll}
                  />
                  <strong>{__("Select All", "arraysubs")}</strong>
                </label>

                {availableSectionKeys.map((key) => (
                  <label
                    key={key}
                    className="arraysubs-easy-setup__section-item"
                  >
                    <input
                      type="checkbox"
                      checked={!!selectedSections[key]}
                      onChange={() => handleToggleSection(key)}
                    />
                    <div>
                      <strong>{SECTION_LABELS[key]?.label}</strong>
                      {SECTION_LABELS[key]?.description && (
                        <span className="arraysubs-easy-setup__section-desc">
                          {SECTION_LABELS[key].description}
                        </span>
                      )}
                    </div>
                  </label>
                ))}
              </div>

              <div className="arraysubs-easy-setup__actions">
                <button
                  type="button"
                  className="button button-primary"
                  onClick={handleConfirmImport}
                  disabled={getSelectedKeys().length === 0}
                >
                  {__("Import Selected", "arraysubs")}
                </button>
                <button
                  type="button"
                  className="button button-link"
                  onClick={handleCancelImport}
                >
                  {__("Cancel", "arraysubs")}
                </button>
              </div>
            </div>
          )}

          {/* Importing Spinner */}
          {importStep === "importing" && (
            <div className="arraysubs-easy-setup__importing">
              <span className="spinner is-active" />
              <span>{__("Importing settings...", "arraysubs")}</span>
            </div>
          )}

          {/* Import Result */}
          {importResult && importStep === "idle" && (
            <div className="arraysubs-easy-setup__result">
              <div className="arraysubs-easy-setup__result-header">
                <CheckCircle2 size={20} />
                <strong>{__("Import Complete", "arraysubs")}</strong>
              </div>

              {importResult.imported?.length > 0 && (
                <div className="arraysubs-easy-setup__result-section">
                  <span>{__("Imported:", "arraysubs")}</span>
                  <ul>
                    {importResult.imported.map((key) => (
                      <li key={key}>{SECTION_LABELS[key]?.label || key}</li>
                    ))}
                  </ul>
                </div>
              )}

              {importResult.skipped?.length > 0 && (
                <div className="arraysubs-easy-setup__result-section">
                  <span>{__("Skipped:", "arraysubs")}</span>
                  <ul>
                    {importResult.skipped.map((key) => (
                      <li key={key}>{SECTION_LABELS[key]?.label || key}</li>
                    ))}
                  </ul>
                </div>
              )}

              {importResult.warnings?.length > 0 && (
                <div className="arraysubs-easy-setup__result-warnings">
                  <AlertTriangle size={16} />
                  <ul>
                    {importResult.warnings.map((warning, i) => (
                      <li key={i}>{warning}</li>
                    ))}
                  </ul>
                </div>
              )}

              <button
                type="button"
                className="button button-link"
                onClick={() => setImportResult(null)}
              >
                {__("Dismiss", "arraysubs")}
              </button>
            </div>
          )}
        </div>
      </div>

      {/* Confirmation Modal */}
      <Modal
        isOpen={importStep === "confirming"}
        onClose={() => setImportStep("select")}
        size="lg"
        title={__("Confirm Import", "arraysubs")}
      >
        <div className="arraysubs-easy-setup__confirm">
          <div className="arraysubs-easy-setup__confirm-warning">
            <AlertTriangle size={24} />
            <p>
              {__(
                "The selected settings will be wiped out and replaced with the imported values. Unchecked sections will remain untouched. This action cannot be undone.",
                "arraysubs",
              )}
            </p>
          </div>
          <div className="arraysubs-easy-setup__confirm-actions">
            <button
              type="button"
              className="button button-link"
              onClick={() => setImportStep("select")}
            >
              {__("Cancel", "arraysubs")}
            </button>
            <button
              type="button"
              className="button button-primary arraysubs-easy-setup__confirm-btn"
              onClick={handleImport}
            >
              {__("Confirm Import", "arraysubs")}
            </button>
          </div>
        </div>
      </Modal>

      <SetupWizard
        isOpen={wizardModal.isOpen}
        onClose={wizardModal.close}
        onComplete={(result) => {
          showToast(
            result?.message ||
              __("Setup wizard completed successfully!", "arraysubs"),
            "success",
          );
          wizardModal.close();
        }}
      />

      <ToastContainer toasts={toasts} removeToast={removeToast} />
    </DefaultPageLayout>
  );
};

export default EasySetup;
