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

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';

export type UserPlan = 'free' | 'basic' | 'premium' | 'max' | 'business';

interface AuthUser {
  userId: string;
  email: string;
  role?: string;
  plan?: UserPlan;
}

interface AuthState {
  token: string | null;
  user: AuthUser | null;
  isAuthenticated: boolean;
  hasHydrated: boolean;
  setHasHydrated: (v: boolean) => void;
  register: (email: string, password: string) => Promise<void>;
  login: (email: string, password: string) => Promise<void>;
  loginWithGoogle: (credential: string) => Promise<void>;
  loginWithApple: (identityToken: string) => Promise<void>;
  updatePlan: (plan: UserPlan, billingCycle?: 'monthly' | 'yearly') => Promise<void>;
  logout: () => void;
  checkAuth: () => Promise<void>;
}

async function verifyAndStore(
  token: string,
  set: (partial: Partial<AuthState>) => void
) {
  const verify = await axios.post(`${API_URL}/api/auth/verify`, { token });
  if (verify.data.valid) {
    set({ token, user: verify.data.user, isAuthenticated: true });
  } else {
    throw new Error('Token verification failed');
  }
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set, get) => ({
      token: null,
      user: null,
      isAuthenticated: false,
      hasHydrated: false,
      setHasHydrated: (v) => set({ hasHydrated: v }),

      register: async (email, password) => {
        await axios.post(`${API_URL}/api/auth/register`, { email, password });
        // Auto-login after successful registration
        const res = await axios.post(`${API_URL}/api/auth/login`, { email, password });
        await verifyAndStore(res.data.token, set);
      },

      login: async (email, password) => {
        const res = await axios.post(`${API_URL}/api/auth/login`, { email, password });
        await verifyAndStore(res.data.token, set);
      },

      loginWithGoogle: async (credential) => {
        const res = await axios.post(`${API_URL}/api/auth/google`, { credential });
        await verifyAndStore(res.data.token, set);
      },

      loginWithApple: async (identityToken) => {
        const res = await axios.post(`${API_URL}/api/auth/apple`, { identityToken });
        await verifyAndStore(res.data.token, set);
      },

      updatePlan: async (plan, billingCycle) => {
        const { token } = get();
        const res = await axios.post(
          `${API_URL}/api/auth/plan`,
          { plan, billingCycle },
          { headers: { Authorization: `Bearer ${token}` } }
        );
        await verifyAndStore(res.data.token, set);
      },

      logout: () => {
        set({ token: null, user: null, isAuthenticated: false });
      },

      checkAuth: async () => {
        const { token } = get();
        if (!token) {
          set({ isAuthenticated: false });
          return;
        }
        try {
          const verify = await axios.post(`${API_URL}/api/auth/verify`, { token });
          if (!verify.data.valid) {
            set({ token: null, user: null, isAuthenticated: false });
          }
        } catch {
          set({ token: null, user: null, isAuthenticated: false });
        }
      },
    }),
    {
      name: 'cahoo-auth-storage',
      onRehydrateStorage: () => (state) => {
        state?.setHasHydrated(true);
      },
    }
  )
);
