import { create } from "zustand";
import { api } from "../lib/api.ts";

export type UserStatus = "online" | "idle" | "dnd" | "offline";

export interface User {
  id: string;
  username: string;
  display_name: string;
  email: string;
  avatar: string;
  bio: string;
  accent_color: string;
  status: UserStatus;
  status_text: string;
  created_at: string;
  banner_url?: string;
  tagline?: string;
  pronouns?: string;
  social_links?: { platform: string; url: string }[];
}

export interface PublicProfile extends User {
  badges: { id: string; name: string; icon: string; description?: string; server_id?: string }[];
}

export type BlockedUser = {
  id: string;
  username: string;
  created_at: string;
};

export interface UpdateProfilePayload {
  avatar_url?: string;
  display_name?: string;
  bio?: string;
  accent_color?: string;
  status_text?: string;
  status?: UserStatus;
  banner_url?: string;
  tagline?: string;
  pronouns?: string;
  social_links?: { platform: string; url: string }[];
}

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  login: (identifier: string, password: string) => Promise<void>;
  register: (
    email: string,
    username: string,
    password: string,
    displayName?: string,
  ) => Promise<void>;
  logout: () => Promise<void>;
  fetchMe: () => Promise<void>;
  updateProfile: (data: UpdateProfilePayload) => Promise<void>;
  changePassword: (
    currentPassword: string,
    newPassword: string,
  ) => Promise<void>;
  requestPasswordReset: (email: string) => Promise<void>;
  resetPassword: (token: string, newPassword: string) => Promise<void>;
  getPublicProfile: (userId: string) => Promise<PublicProfile>;
  listBlocks: () => Promise<BlockedUser[]>;
  blockUser: (userId: string) => Promise<void>;
  unblockUser: (userId: string) => Promise<void>;
  clearError: () => void;
}

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

  login: async (identifier, password) => {
    set({ isLoading: true, error: null });
    try {
      await api.post("/auth/login/password", {
        email: identifier,
        password,
      });
      const user = await api.get<User>("/auth/me");
      set({ user, isAuthenticated: true, isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error: error instanceof Error ? error.message : "Login failed",
      });
      throw error;
    }
  },

  register: async (email, username, password, displayName) => {
    set({ isLoading: true, error: null });
    try {
      await api.post("/auth/register", {
        email,
        username,
        password,
        display_name: displayName || username,
      });
      const user = await api.get<User>("/auth/me");
      set({ user, isAuthenticated: true, isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error:
          error instanceof Error ? error.message : "Registration failed",
      });
      throw error;
    }
  },

  logout: async () => {
    set({ isLoading: true, error: null });
    try {
      await api.post("/auth/logout");
      set({ user: null, isAuthenticated: false, isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error: error instanceof Error ? error.message : "Logout failed",
      });
      throw error;
    }
  },

  fetchMe: async () => {
    set({ isLoading: true, error: null });
    try {
      const user = await api.get<User>(`/auth/me?t=${Date.now()}`);
      set({ user, isAuthenticated: true, isLoading: false });
    } catch (error) {
      set({
        user: null,
        isAuthenticated: false,
        isLoading: false,
        error:
          error instanceof Error ? error.message : "Failed to fetch user",
      });
    }
  },

  updateProfile: async (data) => {
    set({ isLoading: true, error: null });
    try {
      const user = await api.patch<User>("/auth/me", data);
      set({ user, isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error: error instanceof Error ? error.message : "Update failed",
      });
      throw error;
    }
  },

  changePassword: async (currentPassword, newPassword) => {
    set({ isLoading: true, error: null });
    try {
      await api.put("/auth/me/password", {
        current_password: currentPassword,
        new_password: newPassword,
      });
      set({ isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error:
          error instanceof Error
            ? error.message
            : "Password change failed",
      });
      throw error;
    }
  },

  requestPasswordReset: async (email) => {
    set({ isLoading: true, error: null });
    try {
      await api.post("/auth/request-password-reset", { email });
      set({ isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error:
          error instanceof Error
            ? error.message
            : "Failed to request password reset",
      });
      throw error;
    }
  },

  resetPassword: async (token, newPassword) => {
    set({ isLoading: true, error: null });
    try {
      await api.post("/auth/reset-password", { token, new_password: newPassword });
      set({ isLoading: false });
    } catch (error) {
      set({
        isLoading: false,
        error:
          error instanceof Error
            ? error.message
            : "Failed to reset password",
      });
      throw error;
    }
  },

  clearError: () => set({ error: null }),

  getPublicProfile: async (userId) => api.get<PublicProfile>(`/users/${userId}/profile`),

  listBlocks: async () => api.get<BlockedUser[]>('/users/me/blocks'),

  blockUser: async (userId) => {
    await api.post('/users/me/blocks', { user_id: userId });
  },

  unblockUser: async (userId) => {
    await api.delete(`/users/me/blocks/${userId}`);
  },
}));
