using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using EQNetwork.Objects;
using EQNetwork.Utility;
using EQNetwork.Aspects;

namespace EQNetwork.Interfaces
{
    public partial interface IUserService
    {
        /// <summary>
        /// Get User information (by UserId)
        /// Returns User object (very limited info if not logged in, else still somewhat limited)
        /// </summary>
        /// <param name="userId"></param>
        User Get(int userId);

        /// <summary>
        /// Get User information (by Username)
        /// Returns User object (very limited info if not logged in, else still somewhat limited)
        /// </summary>
        /// <param name="username"></param>
        User Get(string username);

        /// <summary>
        /// Get logged in User information
        /// Returns User object (fairly complete info... all except password)
        /// </summary>
        User Get();

        /// <summary>
        /// Create a User
        /// Returns a Session object (essentially logs in the new User)
        /// </summary>
        /// <param name="user"></param>
        Session Create(ref User user);

        /// <summary>
        /// Update a User (only updates fields that have been modified in User object)
        /// Returns updated User object
        /// </summary>
        /// <param name="user"></param>
        void Update(ref User user);

        /// <summary>
        /// Upload a User icon
        /// Returns updated User object (filename will have changed)
        /// </summary>
        /// <param name="path">File path</param>
        void UploadIcon(string path);

        /// <summary>
        /// Upload a User icon
        /// Returns updated User object (filename will have changed)
        /// </summary>
        /// <param name="fileUploadSpec">Can be a path, a stream, or a url</param>
        void UploadIcon(FileUploadSpec fileUploadSpec);

        /// <summary>
        /// Delete a User icon
        /// Returns updated User object (filename will be null)
        /// </summary>
        void DeleteIcon();

        /// <summary>
        /// Link logged in User to a Facebook account
        /// Returns updated User object (filename will be null)
        /// </summary>
        /// <param name="accessToken">Facebook Access Token</param>
        /// <param name="expirationDate">Facebook Expiration Date</param>
        User LinkFacebook(string accessToken, DateTime expirationDate);

        /// <summary>
        /// Unlink logged in User from Facebook account
        /// Returns updated User object
        /// </summary>
        User UnlinkFacebook();

        /// <summary>
        /// Link logged in User to a Twitter account
        /// Returns updated User object
        /// </summary>
        /// <param name="twitterUserId">Twitter UserId</param>
        /// <param name="screenName">Twitter ScreenName</param>
        /// <param name="oAuthToken">Twitter OAuth Token</param>
        /// <param name="oAuthTokenSecret">Twither OAuth Token Secret</param>
        User LinkTwitter(string twitterUserId, string screenName, string oAuthToken, string oAuthTokenSecret);

        /// <summary>
        /// Unlink logged User from Twitter account
        /// Returns updated User object
        /// </summary>
        User UnlinkTwitter();

        /// <summary>
        /// Delete the logged in User's account
        /// </summary>
        void Delete();

        /// <summary>
        /// Delete User (by User object)
        /// </summary>
        /// <param name="user">User object</param>
        void Delete(User user);

        /// <summary>
        /// Delete User (by UserId)
        /// </summary>
        /// <param name="userId"></param>
        void Delete(int userId);

        /// <summary>
        /// Email a list of usernames associated with an email address *to* that email address (used for Forgot Username)
        /// </summary>
        /// <param name="email"></param>
        string EmailAccounts(string email);
        
        /// <summary>
        /// List Collections for logged in User (Collection types and filters specified in ListCollectionsContext)
        /// </summary>
        /// <param name="listCollectionsContext">Collection types and filters</param>
        /// <param name="pagingParameters"></param>
        List<Collection> ListCollections( 
            ListCollectionsContext listCollectionsContext, 
            PagingParameters pagingParameters);

        /// <summary>
        /// List Collections for specified User (Collection types and filters specified in ListCollectionsContext)
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="listCollectionsContext">Collection types and filters</param>
        /// <param name="pagingParameters"></param>
        List<Collection> ListCollections(int userId,
            ListCollectionsContext listCollectionsContext,
            PagingParameters pagingParameters);

        /// <summary>
        /// Search for Users
        /// </summary>
        /// <param name="search">Search string (matches beginings of words)</param>
        /// <param name="pagingParameters"></param>

        /// <summary>
        /// List Users being followed or contributed by the logged in User (types and filters specified in ListUsersContext)
        /// Will also list the Users following and contributing to the logged in User (ShowInverse in ListUserContext)
        /// </summary>
        /// <param name="listUsersContext"></param>
        /// <param name="pagingParameters"></param>
        List<User> ListUsers(ListUsersContext listUsersContext, PagingParameters pagingParameters);
        
        /// <summary>
        /// List the ContentFiles that have been favorited by the logged in User
        /// </summary>
        /// <param name="listContentFilesContext"></param>
        /// <param name="pagingParameters"></param>
        List<ContentFile> ListFavoritedContentFiles(
            ListContentFilesContext listContentFilesContext,
            PagingParameters pagingParameters);

        /// <summary>
        /// Sends an Email to the specified User with a Password Reset link
        /// </summary>
        /// <param name="username"></param>
        void RequestPasswordReset(string username);

        /// <summary>
        /// Resends the confirmation email (first sent when User was created)
        /// </summary>
        void ResendConfirmationEmail();
        
        /// <summary>
        /// Using the PasswordResetGuid sent int the RequestPasswordReset email... change the password
        /// </summary>
        /// <param name="passwordResetGuid"></param>
        /// <param name="password"></param>
        void ResetPassword(Guid passwordResetGuid, string password);

        PurchaseTransaction Purchase(PurchaseContext purchaseContext);

        List<Friend> FacebookFindFriends(string search, Db.SocialSearchType socialSearchType, PagingParameters pagingParameters);
        List<Friend> TwitterFindFriends(string search, Db.SocialSearchType socialSearchType, PagingParameters pagingParameters);

        User UpdateSocial(bool isSocialOn, int fbBits, int twitterBits);

        void SocialAdd(string action, int? collectionId, int? contentFileId, bool force);
        void SocialRemove(string action, int? collectionId, int? contentFileId, bool force);
    }
}
