/**
 * Centralized Catalog Configuration Store
 *
 * Manages all catalog configuration state (Internet, SIM) with localStorage persistence.
 * This store serves as the single source of truth for configuration state,
 * eliminating URL param coupling and enabling reliable navigation.
 */

import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import { logger } from "@/lib/logger";
import {
  simConfigureFormSchema,
  type SimCardType,
  type ActivationType,
  type MnpData,
} from "@customer-portal/domain/sim";
import {
  buildSimOrderConfigurations,
  type OrderConfigurations,
  type AccessModeValue,
} from "@customer-portal/domain/orders";

// ============================================================================
// Types
// ============================================================================

export interface InternetConfigState {
  planSku: string | null;
  accessMode: AccessModeValue | null;
  installationSku: string | null;
  addonSkus: string[];
  currentStep: number;
}

export interface SimConfigState {
  planSku: string | null;
  simType: SimCardType;
  eid: string;
  selectedAddons: string[];
  activationType: ActivationType;
  scheduledActivationDate: string;
  wantsMnp: boolean;
  mnpData: MnpData;
  currentStep: number;
}

interface CatalogStore {
  // Internet configuration
  internet: InternetConfigState;
  setInternetConfig: (config: Partial<InternetConfigState>) => void;
  resetInternetConfig: () => void;

  // SIM configuration
  sim: SimConfigState;
  setSimConfig: (config: Partial<SimConfigState>) => void;
  resetSimConfig: () => void;

  // Checkout transition helpers
  buildInternetCheckoutParams: () => URLSearchParams | null;
  buildSimCheckoutParams: () => URLSearchParams | null;
  buildServiceOrderConfigurations: () => OrderConfigurations | undefined;
  restoreInternetFromParams: (params: URLSearchParams) => void;
  restoreSimFromParams: (params: URLSearchParams) => void;
}

// ============================================================================
// Initial States
// ============================================================================

const initialInternetState: InternetConfigState = {
  planSku: null,
  accessMode: null,
  installationSku: null,
  addonSkus: [],
  currentStep: 1,
};

const initialSimState: SimConfigState = {
  planSku: null,
  simType: "eSIM",
  eid: "",
  selectedAddons: [],
  activationType: "Immediate",
  scheduledActivationDate: "",
  wantsMnp: false,
  mnpData: {
    reservationNumber: "",
    expiryDate: "",
    phoneNumber: "",
    mvnoAccountNumber: "",
    portingLastName: "",
    portingFirstName: "",
    portingLastNameKatakana: "",
    portingFirstNameKatakana: "",
    portingGender: "",
    portingDateOfBirth: "",
  },
  currentStep: 1,
};

const stringOrUndefined = (value: string | null | undefined): string | undefined => {
  if (typeof value !== "string") return undefined;
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : undefined;
};

const buildSimFormInput = (sim: SimConfigState) => ({
  simType: sim.simType,
  eid: stringOrUndefined(sim.eid),
  selectedAddons: sim.selectedAddons,
  activationType: sim.activationType,
  scheduledActivationDate: stringOrUndefined(sim.scheduledActivationDate),
  wantsMnp: sim.wantsMnp,
  mnpData: sim.wantsMnp
    ? {
        reservationNumber: stringOrUndefined(sim.mnpData.reservationNumber) ?? "",
        expiryDate: stringOrUndefined(sim.mnpData.expiryDate) ?? "",
        phoneNumber: stringOrUndefined(sim.mnpData.phoneNumber) ?? "",
        mvnoAccountNumber: stringOrUndefined(sim.mnpData.mvnoAccountNumber),
        portingLastName: stringOrUndefined(sim.mnpData.portingLastName),
        portingFirstName: stringOrUndefined(sim.mnpData.portingFirstName),
        portingLastNameKatakana: stringOrUndefined(sim.mnpData.portingLastNameKatakana),
        portingFirstNameKatakana: stringOrUndefined(sim.mnpData.portingFirstNameKatakana),
        portingGender: stringOrUndefined(sim.mnpData.portingGender),
        portingDateOfBirth: stringOrUndefined(sim.mnpData.portingDateOfBirth),
      }
    : undefined,
});

// ============================================================================
// Store
// ============================================================================

export const useCatalogStore = create<CatalogStore>()(
  persist(
    (set, get) => ({
      // ======================================================================
      // Internet State
      // ======================================================================
      internet: initialInternetState,

      setInternetConfig: (config: Partial<InternetConfigState>) => {
        set(state => ({
          internet: { ...state.internet, ...config },
        }));
      },

      resetInternetConfig: () => {
        set({ internet: initialInternetState });
      },

      // ======================================================================
      // SIM State
      // ======================================================================
      sim: initialSimState,

      setSimConfig: (config: Partial<SimConfigState>) => {
        set(state => ({
          sim: { ...state.sim, ...config },
        }));
      },

      resetSimConfig: () => {
        set({ sim: initialSimState });
      },

      // ======================================================================
      // Checkout Helpers
      // ======================================================================

      buildInternetCheckoutParams: () => {
        const { internet } = get();

        if (!internet.planSku || !internet.accessMode || !internet.installationSku) {
          return null;
        }

        // Build URLSearchParams directly from state
        const params = new URLSearchParams({
          type: "internet",
          planSku: internet.planSku,
          accessMode: internet.accessMode,
          installationSku: internet.installationSku,
        });

        // Add addons if present
        if (internet.addonSkus.length > 0) {
          params.set("addons", internet.addonSkus.join(","));
        }

        return params;
      },

      buildSimCheckoutParams: () => {
        const { sim } = get();

        if (!sim.planSku) {
          return null;
        }

        // Build URLSearchParams directly from state
        const params = new URLSearchParams({
          type: "sim",
          planSku: sim.planSku,
          simType: sim.simType,
          activationType: sim.activationType,
        });

        // Add optional fields only if present
        if (sim.simType === "eSIM" && sim.eid?.trim()) {
          params.set("eid", sim.eid.trim());
        }

        if (sim.activationType === "Scheduled" && sim.scheduledActivationDate?.trim()) {
          params.set("scheduledAt", sim.scheduledActivationDate.trim().replace(/-/g, ""));
        }

        if (sim.selectedAddons.length > 0) {
          params.set("addons", sim.selectedAddons.join(","));
        }

        if (sim.wantsMnp) {
          params.set("isMnp", "true");
          const mnp = sim.mnpData;

          // Add MNP fields if present
          if (mnp.reservationNumber?.trim()) params.set("mnpNumber", mnp.reservationNumber.trim());
          if (mnp.expiryDate?.trim())
            params.set("mnpExpiry", mnp.expiryDate.trim().replace(/-/g, ""));
          if (mnp.phoneNumber?.trim()) params.set("mnpPhone", mnp.phoneNumber.trim());
          if (mnp.mvnoAccountNumber?.trim())
            params.set("mvnoAccountNumber", mnp.mvnoAccountNumber.trim());
          if (mnp.portingLastName?.trim())
            params.set("portingLastName", mnp.portingLastName.trim());
          if (mnp.portingFirstName?.trim())
            params.set("portingFirstName", mnp.portingFirstName.trim());
          if (mnp.portingLastNameKatakana?.trim())
            params.set("portingLastNameKatakana", mnp.portingLastNameKatakana.trim());
          if (mnp.portingFirstNameKatakana?.trim())
            params.set("portingFirstNameKatakana", mnp.portingFirstNameKatakana.trim());
          if (mnp.portingGender?.trim()) params.set("portingGender", mnp.portingGender.trim());
          if (mnp.portingDateOfBirth?.trim())
            params.set("portingDateOfBirth", mnp.portingDateOfBirth.trim().replace(/-/g, ""));
        }

        return params;
      },

      buildServiceOrderConfigurations: () => {
        const { sim } = get();
        try {
          const formData = simConfigureFormSchema.parse(buildSimFormInput(sim));
          return buildSimOrderConfigurations(formData);
        } catch (error) {
          logger.warn("Failed to build SIM order configurations from store state", {
            error: error instanceof Error ? error.message : String(error),
          });
          return undefined;
        }
      },

      restoreInternetFromParams: (params: URLSearchParams) => {
        // Directly parse URL params to state
        const planSku = params.get("planSku") || null;
        const accessMode = params.get("accessMode") as AccessModeValue | null;
        const installationSku = params.get("installationSku") || null;
        const addonsStr = params.get("addons");
        const addonSkus = addonsStr
          ? addonsStr
              .split(",")
              .map(s => s.trim())
              .filter(Boolean)
          : [];

        set(state => ({
          internet: {
            ...state.internet,
            planSku,
            accessMode,
            installationSku,
            addonSkus,
          },
        }));
      },

      restoreSimFromParams: (params: URLSearchParams) => {
        // Directly parse URL params to state
        const planSku = params.get("planSku") || null;
        const simType = (params.get("simType") as SimCardType) || "eSIM";
        const activationType = (params.get("activationType") as ActivationType) || "Immediate";
        const eid = params.get("eid") || "";
        const scheduledAt = params.get("scheduledAt") || "";
        const addonsStr = params.get("addons");
        const selectedAddons = addonsStr
          ? addonsStr
              .split(",")
              .map(s => s.trim())
              .filter(Boolean)
          : [];
        const wantsMnp = params.get("isMnp") === "true";

        // Parse MNP data if present
        const mnpData: MnpData = wantsMnp
          ? {
              reservationNumber: params.get("mnpNumber") || "",
              expiryDate: params.get("mnpExpiry") || "",
              phoneNumber: params.get("mnpPhone") || "",
              mvnoAccountNumber: params.get("mvnoAccountNumber") || "",
              portingLastName: params.get("portingLastName") || "",
              portingFirstName: params.get("portingFirstName") || "",
              portingLastNameKatakana: params.get("portingLastNameKatakana") || "",
              portingFirstNameKatakana: params.get("portingFirstNameKatakana") || "",
              portingGender: params.get("portingGender") || "",
              portingDateOfBirth: params.get("portingDateOfBirth") || "",
            }
          : { ...initialSimState.mnpData };

        set(state => ({
          sim: {
            ...state.sim,
            planSku,
            simType,
            activationType,
            eid,
            scheduledActivationDate: scheduledAt,
            wantsMnp,
            selectedAddons,
            mnpData,
          },
        }));
      },
    }),
    {
      name: "catalog-config-store",
      storage: createJSONStorage(() => localStorage),
      // Only persist configuration state, not transient UI state
      partialize: state => ({
        internet: state.internet,
        sim: state.sim,
      }),
    }
  )
);

// ============================================================================
// Selectors
// ============================================================================

export const selectInternetConfig = (state: CatalogStore) => state.internet;
export const selectSimConfig = (state: CatalogStore) => state.sim;
export const selectInternetStep = (state: CatalogStore) => state.internet.currentStep;
export const selectSimStep = (state: CatalogStore) => state.sim.currentStep;

// ============================================================================
// Utility Functions
// ============================================================================

/**
 * Clear all catalog configuration from localStorage
 * Useful for testing or debugging
 */
export const clearCatalogStore = () => {
  if (typeof window !== "undefined") {
    localStorage.removeItem("catalog-config-store");
  }
};
