import apiService from './apiService';

export interface UserProfile {
  custom_user_id: string;
  name: string;
  email: string;
  first_name: string;
  middle_name?: string;
  last_name?: string;
  full_name: string;
  role_profile_name?: string;
  username?: string;
  language?: string;
  time_zone?: string;
  user_image?: string;
  enabled: number;
  roles: Array<{
    role: string;
  }>;
}

export interface UpdateUserProfileData {
  first_name?: string;
  middle_name?: string;
  last_name?: string;
  role_profile_name?: string;
  new_password?: string;
  custom_user_id?: string;
}

/**
 * Fetch current logged-in user's profile
 */
export const fetchCurrentUserProfile = async (): Promise<UserProfile> => {
  try {
    // First get the current user's email
    const sessionResponse = await fetch('/api/method/frappe.auth.get_logged_user', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
      credentials: 'include',
    });
    
    const sessionData = await sessionResponse.json();
    const userEmail = sessionData.message;
    
    if (!userEmail) {
      throw new Error('No user logged in');
    }
    
    // Use frappe.client.get which returns all fields including role_profile_name
    const response = await fetch('/api/method/frappe.client.get', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      credentials: 'include',
      body: JSON.stringify({
        doctype: 'User',
        name: userEmail,
      }),
    });
    
    const result = await response.json();
    
    // Debug: Log the response
    console.log('frappe.client.get response:', result);
    console.log('role_profile_name:', result.message?.role_profile_name);
    
    if (result.message) {
      const userData = result.message as UserProfile;
      
      // Roles are included in the response as a child table
      if (!userData.roles) {
        userData.roles = [];
      }
      
      return userData;
    }
    
    throw new Error('Failed to fetch user profile');
  } catch (error) {
    console.error('Error fetching user profile:', error);
    throw error;
  }
};

/**
 * Update user profile
 */
export const updateUserProfile = async (
  userEmail: string,
  data: UpdateUserProfileData
): Promise<UserProfile> => {
  try {
    const response = await fetch(`/api/resource/User/${encodeURIComponent(userEmail)}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
      },
      credentials: 'include',
      body: JSON.stringify(data),
    });
    
    const result = await response.json();
    
    if (!response.ok) {
      throw new Error(result.exc || result.message || 'Failed to update profile');
    }
    
    return result.data as UserProfile;
  } catch (error) {
    console.error('Error updating user profile:', error);
    throw error;
  }
};

/**
 * Change user password using Frappe's update_password method
 */
export const changeUserPassword = async (
  newPassword: string,
  oldPassword?: string
): Promise<{ message: string }> => {
  try {
    const response = await fetch('/api/method/frappe.core.doctype.user.user.update_password', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      credentials: 'include',
      body: JSON.stringify({
        new_password: newPassword,
        old_password: oldPassword,
      }),
    });
    
    const result = await response.json();
    
    if (!response.ok) {
      // Parse error message
      let errorMsg = 'Failed to change password';
      if (result.exc) {
        // Try to extract meaningful error from exception
        if (result.exc.includes('Incorrect Old Password')) {
          errorMsg = 'Incorrect old password';
        } else if (result.exc.includes('Password cannot be same')) {
          errorMsg = 'New password cannot be the same as old password';
        } else if (result._server_messages) {
          try {
            const messages = JSON.parse(result._server_messages);
            errorMsg = JSON.parse(messages[0]).message || errorMsg;
          } catch (e) {
            // Use default error
          }
        }
      }
      throw new Error(errorMsg);
    }
    
    return { message: 'Password changed successfully' };
  } catch (error) {
    console.error('Error changing password:', error);
    throw error;
  }
};

/**
 * Fetch role profiles for dropdown
 */
export const fetchRoleProfiles = async (): Promise<Array<{ name: string }>> => {
  try {
    const response = await apiService.apiCall<any>(
      `/api/resource/Role Profile?fields=["name"]&limit_page_length=100`
    );
    
    return response?.data || [];
  } catch (error) {
    console.error('Error fetching role profiles:', error);
    return [];
  }
};

export default {
  fetchCurrentUserProfile,
  updateUserProfile,
  changeUserPassword,
  fetchRoleProfiles,
};