/**
 * Global application state (Zustand).
 * Replaces the mutable state from webapp/js/dom.js.
 */

import { create } from "zustand";
import type { DutyWithUser, CalendarEvent } from "@/types";
import { getStartParamFromUrl } from "@/lib/launch-params";

export type CurrentView = "calendar" | "currentDuty";

/** YYYY-MM key for the month that duties/calendarEvents belong to; null when none loaded. */
export type DataForMonthKey = string | null;

export interface AppState {
  currentMonth: Date;
  /** When set, we are loading this month; currentMonth and data stay until load completes. */
  pendingMonth: Date | null;
  lang: "ru" | "en";
  duties: DutyWithUser[];
  calendarEvents: CalendarEvent[];
  /** YYYY-MM: duties and calendarEvents are for this month; null when loading or no data. */
  dataForMonthKey: DataForMonthKey;
  loading: boolean;
  error: string | null;
  accessDenied: boolean;
  /** Server detail from API 403 response; shown in AccessDenied component. */
  accessDeniedDetail: string | null;
  currentView: CurrentView;
  selectedDay: string | null;
  /** True when the first visible screen has finished loading; used to hide content until ready(). */
  appContentReady: boolean;

  setCurrentMonth: (d: Date) => void;
  nextMonth: () => void;
  prevMonth: () => void;
  setDuties: (d: DutyWithUser[]) => void;
  setCalendarEvents: (e: CalendarEvent[]) => void;
  setLoading: (v: boolean) => void;
  setError: (msg: string | null) => void;
  setAccessDenied: (v: boolean) => void;
  setAccessDeniedDetail: (v: string | null) => void;
  setLang: (v: "ru" | "en") => void;
  setCurrentView: (v: CurrentView) => void;
  setSelectedDay: (key: string | null) => void;
  setAppContentReady: (v: boolean) => void;
  /** Batch multiple state updates into a single re-render. */
  batchUpdate: (partial: Partial<Pick<AppState, "currentMonth" | "pendingMonth" | "lang" | "duties" | "calendarEvents" | "dataForMonthKey" | "loading" | "error" | "accessDenied" | "accessDeniedDetail" | "currentView" | "selectedDay" | "appContentReady">>) => void;
}

const now = new Date();
const initialMonth = new Date(now.getFullYear(), now.getMonth(), 1);

/** Initial view: currentDuty when opened via deep link (startParam=duty), else calendar. */
function getInitialView(): CurrentView {
  if (typeof window === "undefined") return "calendar";
  return getStartParamFromUrl() === "duty" ? "currentDuty" : "calendar";
}

export const useAppStore = create<AppState>((set) => ({
  currentMonth: initialMonth,
  pendingMonth: null,
  lang: "en",
  duties: [],
  calendarEvents: [],
  dataForMonthKey: null,
  loading: false,
  error: null,
  accessDenied: false,
  accessDeniedDetail: null,
  currentView: getInitialView(),
  selectedDay: null,
  appContentReady: false,

  setCurrentMonth: (d) => set({ currentMonth: d }),
  nextMonth: () =>
    set((s) => ({
      pendingMonth: new Date(s.currentMonth.getFullYear(), s.currentMonth.getMonth() + 1, 1),
    })),
  prevMonth: () =>
    set((s) => ({
      pendingMonth: new Date(s.currentMonth.getFullYear(), s.currentMonth.getMonth() - 1, 1),
    })),
  setDuties: (d) => set({ duties: d }),
  setCalendarEvents: (e) => set({ calendarEvents: e }),
  setLoading: (v) => set({ loading: v }),
  setError: (msg) => set({ error: msg }),
  setAccessDenied: (v) => set({ accessDenied: v }),
  setAccessDeniedDetail: (v) => set({ accessDeniedDetail: v }),
  setLang: (v) => set({ lang: v }),
  setCurrentView: (v) => set({ currentView: v }),
  setSelectedDay: (key) => set({ selectedDay: key }),
  setAppContentReady: (v) => set({ appContentReady: v }),
  batchUpdate: (partial) => set(partial),
}));
