import { create } from 'zustand';
import { persist } from 'zustand/middleware';

export interface ContextItem {
  type: 'doctor' | 'clinic';
  db_uuid: string;
  name: string;
  role: 'admin' | 'clinic' | 'doctor' | 'secretary' | 'representation' | 'user';
  scope?: string | null;
  doctor_uuid?: string;
  permissions?: Record<string, any>;
}

interface AuthState {
  token: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  userUuid: string | null;
  userName: string | null;
  primaryRole: 'admin' | 'clinic' | 'doctor' | 'secretary' | 'representation' | 'user' | null;
  dbUuid: string | null;
  dbKey: string | null;
  doctorUuid: string | null;
  context: ContextItem | null;
  availableContexts: ContextItem[];

  login: (token: string, refreshToken?: string | null) => void;
  logout: () => void;
  refresh: () => Promise<string | null>;
  fetchMe: () => Promise<void>;
  switchContext: (dbUuid: string) => Promise<void>;
}

function getToken(): string | null {
  try {
    const raw = localStorage.getItem('clinicpro-auth');
    if (!raw) return null;
    return JSON.parse(raw)?.state?.token ?? null;
  } catch {
    return null;
  }
}

async function apiFetch(path: string, options: RequestInit = {}) {
  const token = getToken();
  const res = await fetch(path, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      ...options.headers,
    },
  });
  return res.json();
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set, get) => ({
      token: null,
      refreshToken: null,
      isAuthenticated: false,
      userUuid: null,
      userName: null,
      primaryRole: null,
      dbUuid: null,
      dbKey: null,
      doctorUuid: null,
      context: null,
      availableContexts: [],

      login: (token, refreshToken = null) => {
        set({ token, refreshToken, isAuthenticated: true });
        get().fetchMe();
      },

      logout: () => {
        const rt = get().refreshToken;
        if (rt) {
          apiFetch('/oauth/logout', {
            method: 'POST',
            body: JSON.stringify({ refresh_token: rt }),
          }).catch(() => {});
        }
        set({
          token: null,
          refreshToken: null,
          isAuthenticated: false,
          userUuid: null,
          userName: null,
          primaryRole: null,
          dbUuid: null,
          dbKey: null,
          doctorUuid: null,
          context: null,
          availableContexts: [],
        });
      },

      refresh: async () => {
        const rt = get().refreshToken;
        if (!rt) return null;
        try {
          const res = await fetch('/oauth/token/refresh', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ refresh_token: rt }),
          });
          const json = await res.json();
          if (!res.ok || !json?.access_token) return null;
          set({
            token: json.access_token,
            refreshToken: json.refresh_token ?? rt,
            isAuthenticated: true,
          });
          return json.access_token as string;
        } catch {
          return null;
        }
      },

      fetchMe: async () => {
        try {
          const res = await apiFetch('/oauth/userinfo');
          if (!res.success) return;
          const d = res.data;
          set({
            userUuid:          d.uuid,
            userName:          d.realName,
            primaryRole:       d.primary_role ?? null,
            dbUuid:            d.db_uuid ?? null,
            dbKey:             d.db_key ?? null,
            doctorUuid:        d.doctor_uuid ?? null,
            context:           d.context ?? null,
            availableContexts: d.available_contexts ?? [],
          });
        } catch {
          // شبکه در دسترس نیست — state دست‌نخورده بماند
        }
      },

      switchContext: async (dbUuid: string) => {
        const res = await apiFetch('/api/v1/auth/switch-context', {
          method: 'POST',
          body: JSON.stringify({ db_uuid: dbUuid }),
        });
        if (res.success) {
          set({
            dbUuid:      res.data.db_uuid,
            dbKey:       res.data.db_key,
            doctorUuid:  res.data.context?.doctor_uuid ?? get().doctorUuid,
            context:     res.data.context,
            primaryRole: res.data.context?.role ?? null,
          });
        }
      },
    }),
    {
      name: 'clinicpro-auth',
      partialize: (s) => ({
        token:             s.token,
        refreshToken:      s.refreshToken,
        isAuthenticated:   s.isAuthenticated,
        userUuid:          s.userUuid,
        userName:          s.userName,
        primaryRole:       s.primaryRole,
        dbUuid:            s.dbUuid,
        dbKey:             s.dbKey,
        doctorUuid:        s.doctorUuid,
        context:           s.context,
        availableContexts: s.availableContexts,
      }),
    }
  )
);
