import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Storage } from "@ionic/storage";
import Twit from "twit";

@Injectable()
export class TwitterApiProvider {
  client: Twit;

  constructor(public http: HttpClient, private storage: Storage) {
    this.initApi();
  }

  private async initApi() {
    const access_token_key = await this.storage.get("accessTokenKey");
    const access_token_secret = await this.storage.get("accessTokenSecret");
    this.client = new Twit({
      consumer_key: "UxZkbKotkr8Uc6seupnaZ1kDE",
      consumer_secret: "fEAas8iugR60FOEXsFG0iajq6oyfIIXRBVMlTgWxBd1stWIKHq",
      access_token: access_token_key,
      access_token_secret: access_token_secret,
      timeout_ms: 60 * 1000 // optional HTTP request timeout to apply to all requests.
    });
  }

  public async fetchHomeFeed(maxId?) {
    const res = await this.client.get("statuses/home_timeline", {
      count: 20,
      include_entities: true,
      tweet_mode: "extended",
      max_id: maxId
    });
    return res.data;
  }

  public async fetchUser(userId) {
    const res = await this.client.get("users/show", { user_id: userId });
    return res.data;
  }

  public async fetchUserTimeline(userId, maxId?) {
    const res = await this.client.get("statuses/user_timeline", {
      user_id: userId,
      max_id: maxId,
      include_entities: true,
      tweet_mode: "extended",
      count: 20
    });
    return res.data;
  }

  public async createFriendship(userId) {
    return await this.client.post("friendships/create", { user_id: userId });
  }

  public async destroyFriendship(userId) {
    return await this.client.post("friendships/destroy", { user_id: userId });
  }

  public async muteUser(userId) {
    return await this.client.post("mutes/users/create", { user_id: userId });
  }

  public async unmuteUser(userId) {
    return await this.client.post("mutes/users/destroy", { user_id: userId });
  }

  public async blockUser(userId) {
    return await this.client.post("blocks/create", { user_id: userId });
  }

  public async unblockUser(userId) {
    return await this.client.post("blocks/destroy", { user_id: userId });
  }

  public async tweet(status, retweet?) {
    if (status.length === 0 && retweet) {
      // Simple retweet
      return await this.client.post("statuses/retweet", {
        id: retweet.data.id_str
      });
    } else if (!retweet) {
      // Simple tweet
      return await this.client.post("statuses/update", { status: status });
    } else if (status.length > 0 && retweet) {
      // Quoted tweet
      const url =
        "https://twitter.com/" +
        retweet.data.user.screen_name +
        "/status/" +
        retweet.data.id_str;
      return await this.client.post("statuses/update", {
        status: status,
        attachment_url: url
      });
    } else {
      return;
    }
  }

  public async fetchFriends(userId) {
    let friends = [];
    let cursor = -1;

    while (cursor != 0) {
      const res = await this.client.get("friends/list", {
        user_id: userId,
        count: 200,
        include_user_entities: false,
        cursor: cursor
      });

      cursor = res.data["next_cursor"];
      friends = friends.concat(res.data["users"]);
    }

    return friends;
  }

  public async likeTweet(tweetId) {
    return await this.client.post("favorites/create", { id: tweetId });
  }

  public async unlikeTweet(tweetId) {
    return await this.client.post("favorites/destroy", { id: tweetId });
  }

  public async fetchTweet(tweetId) {
    return await this.client.get("statuses/show", {
      id: tweetId,
      tweet_mode: "extended"
    });
  }

  public async searchRecentTweets(keyword: string, maxId?: string) {
    const res = await this.client.get("search/tweets", {
      q: keyword,
      result_type: "recent",
      count: 20,
      include_entities: true,
      tweet_mode: "extended",
      max_id: maxId
    });
    return res.data;
  }

  public async searchPopularTweets(keyword: string, maxId?: string) {
    const res = await this.client.get("search/tweets", {
      q: keyword,
      result_type: "popular",
      count: 20,
      include_entities: true,
      tweet_mode: "extended",
      max_id: maxId
    });
    return res.data;
  }

  public async searchUsers(keyword: string, page?: number) {
    const res = await this.client.get("users/search", {
      q: keyword,
      count: 10,
      include_entities: true,
      page: page
    });
    return res.data;
  }
}
