"use client";

import { useEffect, useCallback, useMemo, useRef } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useSimCatalog, useSimPlan } from ".";
import { useCatalogStore } from "../services/catalog.store";
import {
  simConfigureFormSchema,
  type SimConfigureFormData,
  type SimCardType,
  type ActivationType,
  type MnpData,
} from "@customer-portal/domain/sim";
import type {
  SimCatalogProduct,
  SimActivationFeeCatalogItem,
} from "@customer-portal/domain/catalog";

export type UseSimConfigureResult = {
  // data
  plan: SimCatalogProduct | null;
  activationFees: SimActivationFeeCatalogItem[];
  addons: SimCatalogProduct[];
  loading: boolean;

  // State from Zustand store
  simType: SimCardType;
  setSimType: (value: SimCardType) => void;
  eid: string;
  setEid: (value: string) => void;
  selectedAddons: string[];
  setSelectedAddons: (value: string[]) => void;
  activationType: ActivationType;
  setActivationType: (value: ActivationType) => void;
  scheduledActivationDate: string;
  setScheduledActivationDate: (value: string) => void;
  wantsMnp: boolean;
  setWantsMnp: (value: boolean) => void;
  mnpData: MnpData;
  setMnpData: (value: MnpData) => void;

  // step orchestration
  currentStep: number;
  setCurrentStep: (step: number) => void;

  // checkout
  buildCheckoutSearchParams: () => URLSearchParams | null;
  validate: () => boolean;
};

/**
 * Hook for managing SIM service configuration state
 * Uses Zustand store for centralized state management with persistence
 */
export function useSimConfigure(planId?: string): UseSimConfigureResult {
  const router = useRouter();
  const searchParams = useSearchParams();
  const urlPlanSku = searchParams.get("plan");
  const paramsSignature = useMemo(() => searchParams.toString(), [searchParams]);

  // Get state from Zustand store (persisted)
  const configState = useCatalogStore(state => state.sim);
  const setConfig = useCatalogStore(state => state.setSimConfig);
  const restoreFromParams = useCatalogStore(state => state.restoreSimFromParams);
  const buildParams = useCatalogStore(state => state.buildSimCheckoutParams);
  const lastRestoredSignatureRef = useRef<string | null>(null);

  // Fetch catalog data from BFF
  const { data: simData, isLoading: simLoading } = useSimCatalog();
  const { plan: selectedPlan } = useSimPlan(configState.planSku || urlPlanSku || planId);

  // Initialize/restore state on mount
  useEffect(() => {
    // If URL has plan param but store doesn't, this is a fresh entry
    const effectivePlanSku = urlPlanSku || planId;
    if (effectivePlanSku && configState.planSku !== effectivePlanSku) {
      setConfig({ planSku: effectivePlanSku });
    }

    // If URL has configuration params (back navigation from checkout), restore them
    const params = new URLSearchParams(paramsSignature);
    const hasConfigParams = params.has("plan") ? params.size > 1 : params.size > 0;
    const shouldRestore =
      hasConfigParams && lastRestoredSignatureRef.current !== paramsSignature && paramsSignature;
    if (shouldRestore) {
      restoreFromParams(params);
      lastRestoredSignatureRef.current = paramsSignature;
    }

    // Redirect if no plan selected
    if (!effectivePlanSku && !configState.planSku) {
      router.push("/catalog/sim");
    }
  }, [
    configState.planSku,
    paramsSignature,
    planId,
    restoreFromParams,
    router,
    setConfig,
    urlPlanSku,
  ]);

  // Derive catalog items
  const addons = simData?.addons ?? [];
  const activationFees = simData?.activationFees ?? [];

  // Wrapper functions for state updates
  const setSimType = useCallback(
    (value: SimCardType) => {
      setConfig({ simType: value });
    },
    [setConfig]
  );

  const setEid = useCallback(
    (value: string) => {
      setConfig({ eid: value });
    },
    [setConfig]
  );

  const setSelectedAddons = useCallback(
    (value: string[]) => {
      setConfig({ selectedAddons: value });
    },
    [setConfig]
  );

  const setActivationType = useCallback(
    (value: ActivationType) => {
      setConfig({ activationType: value });
    },
    [setConfig]
  );

  const setScheduledActivationDate = useCallback(
    (value: string) => {
      setConfig({ scheduledActivationDate: value });
    },
    [setConfig]
  );

  const setWantsMnp = useCallback(
    (value: boolean) => {
      setConfig({ wantsMnp: value });
    },
    [setConfig]
  );

  const setMnpData = useCallback(
    (value: MnpData) => {
      setConfig({ mnpData: value });
    },
    [setConfig]
  );

  const setCurrentStep = useCallback(
    (step: number) => {
      setConfig({ currentStep: step });
    },
    [setConfig]
  );

  // Basic validation
  const validate = useCallback((): boolean => {
    if (!configState.planSku) {
      return false;
    }

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

    const formData: SimConfigureFormData = {
      simType: configState.simType,
      eid: trimOptional(configState.eid),
      selectedAddons: configState.selectedAddons,
      activationType: configState.activationType,
      scheduledActivationDate:
        configState.activationType === "Scheduled"
          ? trimOptional(configState.scheduledActivationDate)
          : undefined,
      wantsMnp: configState.wantsMnp,
      mnpData: configState.wantsMnp
        ? {
            reservationNumber: configState.mnpData.reservationNumber.trim(),
            expiryDate: configState.mnpData.expiryDate.trim(),
            phoneNumber: configState.mnpData.phoneNumber.trim(),
            mvnoAccountNumber: trimOptional(configState.mnpData.mvnoAccountNumber),
            portingLastName: trimOptional(configState.mnpData.portingLastName),
            portingFirstName: trimOptional(configState.mnpData.portingFirstName),
            portingLastNameKatakana: trimOptional(configState.mnpData.portingLastNameKatakana),
            portingFirstNameKatakana: trimOptional(configState.mnpData.portingFirstNameKatakana),
            portingGender: trimOptional(configState.mnpData.portingGender),
            portingDateOfBirth: trimOptional(configState.mnpData.portingDateOfBirth),
          }
        : undefined,
    };

    try {
      simConfigureFormSchema.parse(formData);
      return true;
    } catch {
      return false;
    }
  }, [configState]);

  return {
    plan: selectedPlan || null,
    loading: simLoading,
    addons,
    activationFees,
    simType: configState.simType,
    setSimType,
    eid: configState.eid,
    setEid,
    selectedAddons: configState.selectedAddons,
    setSelectedAddons,
    activationType: configState.activationType,
    setActivationType,
    scheduledActivationDate: configState.scheduledActivationDate,
    setScheduledActivationDate,
    wantsMnp: configState.wantsMnp,
    setWantsMnp,
    mnpData: configState.mnpData,
    setMnpData,
    currentStep: configState.currentStep,
    setCurrentStep,
    buildCheckoutSearchParams: buildParams,
    validate,
  };
}
