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;
  custom_site_name?: string;
  custom_phcc_site_name?: string;
  custom_department?: string;
  username?: string;
  language?: string;
  time_zone?: string;
  user_image?: string;
  enabled: number;
  roles: Array<{
    role: string;
  }>;
  csrf_token?: string;
}

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

const storeCsrfToken = (token?: string) => {
  if (token && token !== 'None' && typeof window !== 'undefined') {
    (window as any).csrf_token = token;
  }
};

/**
 * Fetch current logged-in user's profile
 */
export const fetchCurrentUserProfile = async (): Promise<UserProfile> => {
  try {
    const result = await apiService.apiCall<UserProfile & { user_id?: string }>(
      '/api/method/asset_lite.api.custom_api.get_user_details'
    );

    if (!result?.user_id && !result?.email) {
      throw new Error('No user logged in');
    }

    storeCsrfToken(result.csrf_token);

    const userData: UserProfile = {
      ...result,
      name: result.user_id || result.email,
      email: result.email || result.user_id || '',
      roles: result.roles || [],
    };

    return userData;
  } 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 csrfToken = await apiService.getCSRFToken();
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      Accept: 'application/json',
    };
    if (csrfToken) {
      headers['X-Frappe-CSRF-Token'] = csrfToken;
    }

    const response = await fetch(`/api/resource/User/${encodeURIComponent(userEmail)}`, {
      method: 'PUT',
      headers,
      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 {
    if (!oldPassword) {
      throw new Error('Current password is required');
    }

    const csrfToken = await apiService.getCSRFToken();
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      Accept: 'application/json',
    };
    if (csrfToken) {
      headers['X-Frappe-CSRF-Token'] = csrfToken;
    }

    const response = await fetch('/api/method/frappe.core.doctype.user.user.update_password', {
      method: 'POST',
      headers,
      credentials: 'include',
      body: JSON.stringify({
        new_password: newPassword,
        old_password: oldPassword,
      }),
    });

    const result = await response.json();

    if (!response.ok) {
      let errorMsg = 'Failed to change password';
      if (result.exc) {
        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 {
            // 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,
};
