import { writable, Writable } from "svelte/store";
import { ZodEffects, ZodNullable, ZodOptional, ZodType } from "zod";

export function localStorageSync<T>(initial: T, name: string, modifier: (stored: any) => T = (stored) => JSON.parse(stored), reverseModifier: (value: T) => string = (value) => JSON.stringify(value)): Writable<T> {
	const stored = localStorage.getItem(name) as T
	let value = initial;
	if (stored) {
		value = modifier(stored)
	}

	const writableStore = writable(value)

	writableStore.subscribe((value) => {
		const reversed = reverseModifier(value);
		localStorage.setItem(name, reversed)
	})

	return writableStore
}

export function isZodInstanceOf<T extends ZodType<any>>(
  schema: ZodType<any>,
  targetType: new (...args: any) => T
): schema is T {
  if (schema instanceof targetType) {
    return true;
  }

  if (schema instanceof ZodOptional || schema instanceof ZodNullable) {
    return isZodInstanceOf(schema._def.innerType, targetType);
  }else if (schema instanceof ZodEffects) {
		return getZodBaseType(schema._def.schema)
	}

  return false;
}

export function getZodBaseType(schema: ZodType<any>): ZodType<any> {
  if (schema instanceof ZodOptional || schema instanceof ZodNullable) {
    return getZodBaseType(schema._def.innerType);
  } else if (schema instanceof ZodEffects) {
		return getZodBaseType(schema._def.schema)
	}
  return schema;
}