"use client";

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

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
 */
function trimOptional(value?: string | null) {
  if (typeof value !== "string") {
    return;
  }
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : undefined;
}

/** Convert YYYY-MM-DD (from date input) to YYYYMMDD (FreeBit API format) */
function toYYYYMMDD(value: string): string {
  return value.replace(/-/g, "");
}

function buildFormData(configState: SimConfigState): SimConfigureFormData {
  return {
    simType: configState.simType,
    eid: trimOptional(configState.eid),
    selectedAddons: configState.selectedAddons,
    activationType: configState.activationType,
    scheduledActivationDate:
      configState.activationType === "Scheduled"
        ? trimOptional(configState.scheduledActivationDate)?.replace(/-/g, "")
        : undefined,
    wantsMnp: configState.wantsMnp,
    mnpData: configState.wantsMnp
      ? {
          reservationNumber: configState.mnpData.reservationNumber.trim(),
          expiryDate: toYYYYMMDD(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)?.replace(
            /-/g,
            ""
          ),
        }
      : undefined,
  };
}

function useConfigSetters(setConfig: (config: Partial<SimConfigState>) => void) {
  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]
  );

  return {
    setSimType,
    setEid,
    setSelectedAddons,
    setActivationType,
    setScheduledActivationDate,
    setWantsMnp,
    setMnpData,
    setCurrentStep,
  };
}

export function useSimConfigure(planId?: string): UseSimConfigureResult {
  const router = useRouter();
  const servicesBasePath = useServicesBasePath();
  const searchParams = useSearchParams();
  const urlPlanSku = searchParams.get("planSku");
  const paramsSignature = useMemo(() => searchParams.toString(), [searchParams]);

  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);

  const { data: simData, isLoading: simLoading } = useAccountSimCatalog();
  const selectedPlanSku = configState.planSku || urlPlanSku || planId;
  const selectedPlan = useMemo(() => {
    if (!selectedPlanSku) return null;
    return (simData?.plans ?? []).find(p => p.sku === selectedPlanSku) ?? null;
  }, [simData?.plans, selectedPlanSku]);

  useEffect(() => {
    const effectivePlanSku = urlPlanSku || planId;
    if (effectivePlanSku && configState.planSku !== effectivePlanSku) {
      const resetSimConfig = useCatalogStore.getState().resetSimConfig;
      resetSimConfig();
      setConfig({ planSku: effectivePlanSku });
    }

    const params = new URLSearchParams(paramsSignature);
    const hasConfigParams = params.has("planSku") ? params.size > 1 : params.size > 0;
    const shouldRestore =
      hasConfigParams && lastRestoredSignatureRef.current !== paramsSignature && paramsSignature;
    if (shouldRestore) {
      restoreFromParams(params);
      lastRestoredSignatureRef.current = paramsSignature;
    }

    if (!effectivePlanSku && !configState.planSku) {
      router.push(`${servicesBasePath}/sim`);
    }
  }, [
    configState.planSku,
    paramsSignature,
    planId,
    restoreFromParams,
    router,
    setConfig,
    servicesBasePath,
    urlPlanSku,
  ]);

  const addons = simData?.addons ?? [];
  const activationFees = simData?.activationFees ?? [];

  const setters = useConfigSetters(setConfig);

  const validate = useCallback((): boolean => {
    if (!configState.planSku) return false;
    try {
      simConfigureFormSchema.parse(buildFormData(configState));
      return true;
    } catch {
      return false;
    }
  }, [configState]);

  return {
    plan: selectedPlan || null,
    loading: simLoading,
    addons,
    activationFees,
    simType: configState.simType,
    eid: configState.eid,
    selectedAddons: configState.selectedAddons,
    activationType: configState.activationType,
    scheduledActivationDate: configState.scheduledActivationDate,
    wantsMnp: configState.wantsMnp,
    mnpData: configState.mnpData,
    currentStep: configState.currentStep,
    buildCheckoutSearchParams: buildParams,
    validate,
    ...setters,
  };
}
