'use client';

/**
 * Zustand auth store — persisted to sessionStorage.
 *
 * Manages the simulated authentication state: current user, role, and
 * isAuthenticated flag. The login(role) action looks up the matching
 * MockUser from the generated users array. The logout() action clears
 * everything.
 *
 * Uses Zustand's persist middleware with a custom storage adapter that
 * handles Date serialization (JSON.stringify loses Date instances).
 */

import { create } from 'zustand';
import { persist, type PersistStorage, type StorageValue } from 'zustand/middleware';
import type { MockUser } from '@/lib/mock-data/types';
import type { UserRole } from '@/lib/constants/navigation';
import { users } from '@/lib/mock-data/index';

// ── State interface ─────────────────────────────────────────────────────────

export interface AuthState {
  user: MockUser | null;
  role: UserRole | null;
  isAuthenticated: boolean;
  login: (role: UserRole) => void;
  logout: () => void;
}

// ── sessionStorage adapter with Date reviver ────────────────────────────────

/**
 * ISO 8601 date pattern used to revive Date strings during JSON.parse.
 */
const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/;

function dateReviver(_key: string, value: unknown): unknown {
  if (typeof value === 'string' && ISO_DATE_RE.test(value)) {
    return new Date(value);
  }
  return value;
}

const sessionStorageAdapter: PersistStorage<AuthState> = {
  getItem(name: string): StorageValue<AuthState> | null {
    if (typeof window === 'undefined') return null;
    const raw = sessionStorage.getItem(name);
    if (!raw) return null;
    return JSON.parse(raw, dateReviver) as StorageValue<AuthState>;
  },
  setItem(name: string, value: StorageValue<AuthState>): void {
    if (typeof window === 'undefined') return;
    sessionStorage.setItem(name, JSON.stringify(value));
  },
  removeItem(name: string): void {
    if (typeof window === 'undefined') return;
    sessionStorage.removeItem(name);
  },
};

// ── Store ───────────────────────────────────────────────────────────────────

export const useAuthStore = create<AuthState>()(
  persist(
    (set) => ({
      user: null,
      role: null,
      isAuthenticated: false,

      login: (role: UserRole) => {
        const matchedUser = users.find((u) => u.role === role) ?? null;
        set({
          user: matchedUser,
          role: matchedUser ? role : null,
          isAuthenticated: !!matchedUser,
        });
      },

      logout: () => {
        set({
          user: null,
          role: null,
          isAuthenticated: false,
        });
      },
    }),
    {
      name: 'divisi-auth',
      storage: sessionStorageAdapter,
    },
  ),
);
