import { create } from 'zustand';

type UpdateStatus = 'idle' | 'checking' | 'downloading' | 'ready' | 'not-available' | 'error';

function normalizeReleaseNotes(raw: unknown): string | null {
  if (!raw) return null;
  if (typeof raw === 'string') return raw;
  if (Array.isArray(raw)) {
    return raw.map((item: { version?: string; note?: string }) => item.note || '').filter(Boolean).join('\n') || null;
  }
  return null;
}

interface UpdateState {
  status: UpdateStatus;
  newVersion: string | null;
  releaseNotes: string | null;
  errorMessage: string | null;
  bannerDismissed: boolean;
  isElectron: boolean;

  checkUpdate: () => void;
  installUpdate: () => void;
  dismissBanner: () => void;
  initListeners: () => () => void;
}

export const useUpdateStore = create<UpdateState>((set) => ({
  status: 'idle',
  newVersion: null,
  releaseNotes: null,
  errorMessage: null,
  bannerDismissed: false,
  isElectron: !!window.sman?.updater,

  checkUpdate: () => {
    if (!window.sman?.updater) return;
    set({ status: 'checking' });
    window.sman.updater.check().then((result) => {
      if (result?.status === 'not-available') {
        set({ status: 'not-available' });
      } else if (result?.status === 'error') {
        set({ status: 'error', errorMessage: result.message });
      }
    }).catch(() => {
      set({ status: 'error', errorMessage: 'Failed to check' });
    });
  },

  installUpdate: () => {
    if (!window.sman?.updater) return;
    window.sman.updater.install();
  },

  dismissBanner: () => {
    set({ bannerDismissed: true });
  },

  initListeners: () => {
    if (!window.sman?.updater) return () => {};

    const unsubAvailable = window.sman.updater.onUpdateAvailable((info) => {
      set({
        status: 'downloading',
        newVersion: info.version,
        releaseNotes: normalizeReleaseNotes(info.releaseNotes),
        bannerDismissed: false,
      });
    });

    const unsubNotAvailable = window.sman.updater.onUpdateNotAvailable(() => {
      set({ status: 'not-available' });
    });

    const unsubDownloaded = window.sman.updater.onUpdateDownloaded((info) => {
      set({ status: 'ready', newVersion: info.version, bannerDismissed: false });
    });

    const unsubError = window.sman.updater.onUpdateError((info) => {
      set({ status: 'error', errorMessage: info.message });
    });

    return () => {
      unsubAvailable();
      unsubNotAvailable();
      unsubDownloaded();
      unsubError();
    };
  },
}));
