import type {
  CompleteValues,
  StartValues,
  VerifyOtpValues,
} from '@/features/onboard/onboarding.types';

const ONBOARDING_SESSION_KEY = 'playzer:onboarding-session';
export const OTP_MAX_ATTEMPTS = 5;

export const defaultStartFormValues: StartValues = {
  fullName: '',
  email: '',
};

export const defaultVerifyOtpFormValues: VerifyOtpValues = {
  otp: '',
};

export const defaultCompleteFormValues: CompleteValues = {
  password: '',
  complexName: '',
  physicalAddress: '',
  planCode: '',
};

export type OnboardingSessionState = {
  requestId: string | null;
  onboardingEmail: string | null;
  verifiedEmail: string | null;
  remainingAttempts: number;
  resendCooldownSeconds: number;
  startForm: StartValues;
  verifyOtpForm: VerifyOtpValues;
  completeForm: CompleteValues;
};

const defaultOnboardingSessionState: OnboardingSessionState = {
  requestId: null,
  onboardingEmail: null,
  verifiedEmail: null,
  remainingAttempts: OTP_MAX_ATTEMPTS,
  resendCooldownSeconds: 0,
  startForm: defaultStartFormValues,
  verifyOtpForm: defaultVerifyOtpFormValues,
  completeForm: defaultCompleteFormValues,
};

function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null;
}

function normalizeSessionState(value: unknown): OnboardingSessionState {
  if (!isObject(value)) {
    return defaultOnboardingSessionState;
  }

  return {
    requestId: typeof value.requestId === 'string' ? value.requestId : null,
    onboardingEmail: typeof value.onboardingEmail === 'string' ? value.onboardingEmail : null,
    verifiedEmail: typeof value.verifiedEmail === 'string' ? value.verifiedEmail : null,
    remainingAttempts:
      typeof value.remainingAttempts === 'number'
        ? value.remainingAttempts
        : defaultOnboardingSessionState.remainingAttempts,
    resendCooldownSeconds:
      typeof value.resendCooldownSeconds === 'number'
        ? value.resendCooldownSeconds
        : defaultOnboardingSessionState.resendCooldownSeconds,
    startForm: {
      fullName:
        isObject(value.startForm) && typeof value.startForm.fullName === 'string'
          ? value.startForm.fullName
          : defaultStartFormValues.fullName,
      email:
        isObject(value.startForm) && typeof value.startForm.email === 'string'
          ? value.startForm.email
          : defaultStartFormValues.email,
    },
    verifyOtpForm: {
      otp:
        isObject(value.verifyOtpForm) && typeof value.verifyOtpForm.otp === 'string'
          ? value.verifyOtpForm.otp
          : defaultVerifyOtpFormValues.otp,
    },
    completeForm: {
      password:
        isObject(value.completeForm) && typeof value.completeForm.password === 'string'
          ? value.completeForm.password
          : defaultCompleteFormValues.password,
      complexName:
        isObject(value.completeForm) && typeof value.completeForm.complexName === 'string'
          ? value.completeForm.complexName
          : defaultCompleteFormValues.complexName,
      physicalAddress:
        isObject(value.completeForm) && typeof value.completeForm.physicalAddress === 'string'
          ? value.completeForm.physicalAddress
          : defaultCompleteFormValues.physicalAddress,
      planCode:
        isObject(value.completeForm) && typeof value.completeForm.planCode === 'string'
          ? value.completeForm.planCode
          : defaultCompleteFormValues.planCode,
    },
  };
}

export function getOnboardingSessionState(): OnboardingSessionState {
  if (typeof window === 'undefined') {
    return defaultOnboardingSessionState;
  }

  const rawState = window.sessionStorage.getItem(ONBOARDING_SESSION_KEY);
  if (!rawState) {
    return defaultOnboardingSessionState;
  }

  try {
    return normalizeSessionState(JSON.parse(rawState));
  } catch {
    return defaultOnboardingSessionState;
  }
}

export function setOnboardingSessionState(state: OnboardingSessionState) {
  if (typeof window === 'undefined') return;
  window.sessionStorage.setItem(ONBOARDING_SESSION_KEY, JSON.stringify(state));
}

export function updateOnboardingSessionState(
  updater: (current: OnboardingSessionState) => OnboardingSessionState
): OnboardingSessionState {
  const currentState = getOnboardingSessionState();
  const nextState = updater(currentState);
  setOnboardingSessionState(nextState);
  return nextState;
}

export function clearOnboardingSessionState() {
  if (typeof window === 'undefined') return;
  window.sessionStorage.removeItem(ONBOARDING_SESSION_KEY);
}
