import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { ViewController, NavController, NavParams, ModalController, Content, ToastController, PopoverController } from 'ionic-angular';
import { ThreadPage } from '../thread/thread';
import { Storage } from '@ionic/storage';
import { FileChooser } from '@ionic-native/file-chooser';
import { FilePath } from '@ionic-native/file-path';
import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer';
import { Events } from 'ionic-angular';
import { LoginPage } from '../login/login';

import * as pnut from 'pnut-butter';

/**
 * Generated class for the StreamPage page.
 *
 * See http://ionicframework.com/docs/components/#navigation for more info
 * on Ionic pages and navigation.
 */
@Component({
  selector: 'page-stream',
  templateUrl: 'stream.html',
})
export class StreamPage {

  @ViewChild(Content) content: Content;

  title: string;
  posts: Array<Object> = [];
  since_id: string;
  before_id: string;
  fetcher: any;
  fcaller: any;
  myUsername: string;
  showScrollBtn: boolean = false;
  showUnified: boolean;
  ccOnReply: boolean = false;

  constructor(public navCtrl: NavController, public navParams: NavParams, public modalCtrl: ModalController,
    private changeDetectorRef: ChangeDetectorRef, public toastCtrl: ToastController, private storage: Storage,
    public popoverCtrl: PopoverController, public events: Events) {
    // console.log(JSON.stringify(navParams));

    this.storage.get('cc').then((val) => {
      this.ccOnReply = val;
    });

    this.storage.get('unified').then((val) => {
      this.showUnified = val;

      switch (navParams.data.stream) {
        case 'global':
          this.title = 'Global';
          this.fetcher = pnut.global;
          this.fetchPosts();
          break;
        case 'personal':
          this.title = 'Timeline';
          console.log(this.showUnified);
          this.fetcher = this.showUnified ? pnut.unified : pnut.personal;
          this.fetchPosts();
          break;
        case 'mentions':
          this.title = 'Mentions';
          this.fetcher = pnut.mentions;
          this.fetchMyPosts();
          break;
        case 'bookmarks':
          this.title = 'Bookmarks';
          this.fetcher = pnut.bookmarks;
          this.fetchMyPosts();
          break;
      }

    }).catch(err => {
      console.log('ERROR: ' + err);
    });


    pnut.user('me').then(res => {
      this.myUsername = res.data.username;
    }).catch(err => {
      // console.log('-*-');
      // console.log(JSON.stringify(err));
    });

    this.events.subscribe('stream:reload', (event) => {
      console.log('-reload-');
      this.refreshPage();
    });

  }

  ngAfterViewInit() {
    this.content.ionScroll.subscribe((event) => {
      // console.log('scrolling ', event);
      if (event.scrollTop > 0) {
        this.showScrollBtn = true;
      } else {
        this.showScrollBtn = false;
      }
      this.changeDetectorRef.detectChanges();
    });
  }

  refreshPage() {
    // this.navCtrl.setRoot(this.navCtrl.getActive().component);
    this.navCtrl.setRoot(StreamPage, {stream: 'personal'});
  }

  fetchOlderPosts(infiniteScroll) {
    let params = {
      include_deleted: 0,
      include_raw: 1,
      include_reposted_by:1,
      before_id: this.before_id,
      count: 40
    };
    if (this.title === 'Mentions') {
      this.fcaller = this.fetcher('me', params);
    } else {
      this.fcaller = this.fetcher(params);
    }
    this.fcaller.then(res => {
      if (res.data.length > 0) {
        this.posts.push.apply(this.posts, this.parseData(res.data));
        this.before_id = res.meta.min_id;
      }
      console.log('since_id: ' + this.since_id);
      console.log('before_id: ' + this.before_id);
      infiniteScroll.complete();
    }).catch(err => {
      console.log(err);
    });
  }

  fetchNewerPosts(refresher) {
    let params = {
      include_deleted: 0,
      include_raw: 1,
      include_reposted_by: 1,
      since_id: this.since_id,
      count: 40
    };
    if (this.title === 'Mentions') {
      this.fcaller = this.fetcher('me', params);
    } else {
      this.fcaller = this.fetcher(params);
    }
    this.fcaller.then(res => {
      if (res.data.length > 0) {
        Array.prototype.unshift.apply(this.posts, this.parseData(res.data));
        this.since_id = res.meta.max_id;
      }
      console.log('since_id: ' + this.since_id);
      console.log('before_id: ' + this.before_id);
      refresher.complete();
    }).catch(err => {
      console.log(err);
    });
  }

  fetchPosts() {
    let params = {
      include_deleted: 0,
      include_raw: 1,
      include_reposted_by: 1,
      count: 40
    };
    this.fetcher(params).then(res => {
      if (res.meta.code === 401) {
        this.storage.clear();
        this.navCtrl.setRoot(LoginPage);
      } else {
        this.posts = this.parseData(res.data);
        this.since_id = res.meta.max_id;
        this.before_id = res.meta.min_id;
        console.log('since_id: ' + this.since_id);
        console.log('before_id: ' + this.before_id);
      }

    });
  }

  parseData(data) {
    var pdata = [];
    for (var i = 0; i < data.length; i++) {
      if (!data[i].is_deleted) {
        if (data[i]['repost_of']) {
          data[i] = data[i]['repost_of']
          var reposted_by_string = "";
          for (var j = 0; j < data[i]['reposted_by'].length; j++) {
            reposted_by_string = reposted_by_string + data[i]['reposted_by'][j]['username'] + ", ";
          }
          // data[i]['reposted_by_string'] = "Reposted by: " + reposted_by_string;
        }
        if (data[i].content) {
          for (var k = 0; k < data[i]['content']['entities']['mentions'].length; k++) {
            var men = data[i]['content']['entities']['mentions'][k]['text'];
            if (this.myUsername === men) {
              data[i]['you_are_mentioned'] = true;
            }
          }
        }
        pdata.push(data[i]);
      }
    }
    return pdata;
  }

  fetchThread(threadid) {
    pnut.thread(threadid, {include_deleted: 0, include_raw: 1, count: 140}).then(res => {
      if (res.meta.code === 401) {
        this.storage.clear();
        this.navCtrl.setRoot(LoginPage);
      } else {
        this.navCtrl.push(ThreadPage, {posts: res.data, me: this.myUsername});
      }
    });
  }

  fetchMyPosts() {
    console.log('-- fetching mentions --');
    this.fetcher('me', {include_raw: 1, count: 40}).then(res => {
      if (res.meta.code === 401) {
        this.storage.clear();
        this.navCtrl.setRoot(LoginPage);
      } else {
        this.posts = res.data;
        this.since_id = res.meta.max_id;
        this.before_id = res.meta.min_id;
        console.log('since_id: ' + this.since_id);
        console.log('before_id: ' + this.before_id);
      }
    });
  }

  bookmark(postid, bookmarked) {
    if (bookmarked) {
      pnut.deleteBookmark(postid).then(res => {
        console.log(res);
        this.updatePost(res.data.id);
        this.presentToast("Bookmark updated.");
      }).catch(err => {
        console.log(err);
      });
    } else {
      pnut.bookmark(postid).then(res => {
        console.log(res);
        this.updatePost(res.data.id);
        this.presentToast("Bookmark updated.");
      }).catch(err => {
        console.log(err);
      });
    }
  }

  repost(postid, reposted) {
    if (reposted) {
      pnut.deleteRepost(postid).then(res => {
        console.log(res);
        this.updatePost(res.data.id);
        this.presentToast("Repost updated.");
      }).catch(err => {
        console.log(err);
      });
    } else {
      pnut.repost(postid).then(res => {
        console.log(res);
        this.updatePost(res.data.id);
        this.presentToast("Repost updated.");
      }).catch(err => {
        console.log(err);
      });
    }
  }

  updatePost(postid) {
    pnut.post(postid, {include_raw: 1}).then(res => {
      for (var i = 0; i < this.posts.length; i++) {
        if (this.posts[i]['id'] === postid) {
          this.posts[i] = res.data;
          break;
        }
      }
    }).catch(err => {
      console.log(err);
    });
  }

  showNewPost() {
    let newPostModal = this.modalCtrl.create(NewPostModal, {me: this.myUsername});
    newPostModal.present();
  }

  showReplyPost(postData) {
    let newPostModal = this.modalCtrl.create(NewPostModal, {type: 'reply', post: postData, me: this.myUsername, cc: this.ccOnReply});
    newPostModal.present();
  }

  showQuotedPost(postData) {
    console.log(postData);
    let newPostModal = this.modalCtrl.create(NewPostModal, {type: 'quote', post: postData, me: this.myUsername, cc: this.ccOnReply});
    newPostModal.present();
  }

  showImage(url) {
    window.open(url, '_system');
  }

  presentToast(text) {
    let toast = this.toastCtrl.create({
      position: 'top',
      message: text,
      duration: 2000
    });
    toast.present();
  }

  presentPostMenu(myEvent, postData) {
    let popover = this.popoverCtrl.create(PostMenu, {post: postData, me: this.myUsername});
    popover.present({ev: myEvent});
  }

  scrollToTop() {
    this.content.scrollToTop();
  }

}

@Component({
  // templateUrl: 'new-post.html'
  selector: 'modal-newpost',
  template: `
<ion-header>
  <ion-toolbar>

    <ion-buttons start>
      <button ion-button (click)="dismiss()">
        <span ion-text color="primary">Cancel</span>
      </button>
    </ion-buttons>

    <ion-title>{{ title }}</ion-title>

  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <ion-card-content>
      <ion-item>
        <ion-textarea [(ngModel)]="ptext" autocomplete="true" spellcheck="true" clearInput="true" rows="8"></ion-textarea>
      </ion-item>
    </ion-card-content>
    <ion-row justify-content-end>
      <ion-col offset-0>
        <button ion-button (click)="attachImage()">
          <ion-icon name="attach"></ion-icon>
        </button>
      </ion-col>
      <ion-col col-2><div text-center>{{textCount()}}</div></ion-col>
      <ion-col col-2>
        <button ion-button (click)="send()">
          <ion-icon name="send"></ion-icon>
        </button>
      </ion-col>
    </ion-row>
    <progress id='p' *ngIf="showProgress"></progress>
    <ion-list>
      <ion-item *ngFor="let f of files">
        <ion-thumbnail item-start>
          <img src="{{ f.link }}">
        </ion-thumbnail>
        <p>{{ f.name }}</p>
        <button ion-button color="dark" clear item-end (click)="unattach(f.id)">
          <ion-icon name="remove-circle"></ion-icon>
        </button>
      </ion-item>
    </ion-list>
  </ion-card>
</ion-content>
`
})
export class NewPostModal {
  title: string;
  replyid: string;
  ptext: string = "";
  showProgress: boolean = false;
  files: Array<Object> = [];
  fname: string = "";
  fpath: string = "";
  options: Object = {};
  myUsername: string;
  authToken: string;
  longpost: Object = {};
  raw: {type: string, value: Object}[] = [];

  constructor(public navParams: NavParams, public viewCtrl: ViewController, public toastCtrl: ToastController,
    private fileChooser: FileChooser, private storage: Storage, public events: Events, private filePath: FilePath,
    private transfer: FileTransfer) {
    console.log(JSON.stringify(this.navParams));
    this.myUsername = navParams.data.me;
    if (navParams.data.type === 'reply') {
      this.replyid = navParams.data.post.id;
      this.options = {replyTo: this.replyid};
      if (navParams.data.post.user.username !== this.myUsername) {
        this.ptext = "@" + navParams.data.post.user.username + " ";
      } else {
        this.ptext = ""
      }
      if (navParams.data.post.content.entities) {
        if (navParams.data.post.content.entities.mentions.length > 0) {
          this.ptext = this.ptext + this.parseMentions(navParams.data.post.content.entities.mentions);
        }
      }
      this.title = "Reply to " + navParams.data.post.user.username
    } else if (navParams.data.type === 'quote') {
      this.ptext = " >> @" + navParams.data.post.user.username + ": " + navParams.data.post.content.text;
      this.title = "New Post";
    } else {
      this.title = "New Post";
    }
    this.storage.get('token').then((val) => {
      this.authToken = val;
    });
  }

  dismiss() {
   this.viewCtrl.dismiss();
  }

  send() {

    if (this.ptext.length > 254) {
      this.longpost = {
        'title': '',
        'body': this.ptext,
        'tstamp': new Date().valueOf()
      }
      this.ptext = this.ptext.substr(0, 40) + "... - http://chimpnut.nl/u/";
      this.ptext = this.ptext + this.navParams.data.me + "/lp/{object_id} - #longpost";
      this.raw.push({
        type: "nl.chimpnut.blog.post",
        value: this.longpost
      });
    }

    this.options['raw'] = this.raw;
    pnut.createPost(this.ptext, this.options).then(res => {
      console.log('-success-');
      console.log(JSON.stringify(res));
      this.presentToast("Status posted.");
      this.events.publish('stream:reload', {});
    }).catch(err => {
      console.log('-error posting-');
      console.log(JSON.stringify(err));
    });
    this.viewCtrl.dismiss();
  }

  presentToast(text) {
    let toast = this.toastCtrl.create({
      position: 'top',
      message: text,
      duration: 2000
    });
    toast.present();
  }

  parseMentions(mentions) {
    let mtext = ""
    for(var i = 0; i < mentions.length; i++) {
      let mu = mentions[i].text;
      if (mu !== this.myUsername) {
        mtext += "@" + mu + " ";
      }
    }
    if (mtext.length > 0) {
      if (this.navParams.data.cc) {
        mtext = "\n/" + mtext;
      }
      return mtext;
    } else {
      return "";
    }
  }

  textCount() {
    let counttext = ""
    let count = 254 - this.ptext.length
    if (count < 1) {
      counttext = "longpost"
    } else {
      counttext = String(count)
    }
    return counttext
  }

  attachImage() {
    // console.log('file chooser');
    const fileTransfer: FileTransferObject = this.transfer.create();

    this.fileChooser.open().then(uri => {
      console.log('File URI: ' + uri);
      this.filePath.resolveNativePath(uri).then(filePath => {
        this.fpath = filePath;
        this.fname = filePath.split('/').pop();

        let options: FileUploadOptions = {
          fileKey: 'content',
          fileName: this.fname,
          params: {
            name: this.fname,
            type: 'com.monkeystew.goober_m',
            is_public: true
          },
          headers: {'Authorization': 'Bearer ' + this.authToken}
        }

        this.showProgress = true;
        fileTransfer.upload(this.fpath, 'https://api.pnut.io/v0/files', options).then((response) => {

          let rdata = JSON.parse(response.response);
          let oembed = {
            '+io.pnut.core.file': {
              file_id: rdata.data.id,
              file_token: rdata.data.file_token,
              format: 'oembed'
            }
          }
          // console.log(JSON.stringify(oembed));
          this.raw.push({
            type: "io.pnut.core.oembed",
            value: oembed
          });
          this.files.push({
            name: this.fname,
            link: rdata.data.link,
            id: this.raw.length - 1
          });
          this.showProgress = false;
        }).catch((err) => {

          this.showProgress = false;
          let edata = JSON.parse(err.body);
          this.presentToast(edata.meta.error_message);
        });

      }).catch(err => {
        console.log('-error getting filepath-');
        console.log(err);
      });

    }).catch(err => {
      console.log(err);
    });

  }

  unattach(id) {
    console.log('removing item ' + id);
    this.raw.splice(id, 1);
    this.files.splice(id, 1);
  }
}

@Component({
  template: `
<ion-list>
  <button ion-item (click)="browse()">Open in Browser</button>
  <button ion-item (click)="share()">Share</button>
  <button ion-item *ngIf="showDelBtn" (click)="delete()">Delete</button>
</ion-list>
`
})
export class PostMenu {

  showDelBtn: boolean = false;

  constructor(public navParams: NavParams, public viewCtrl: ViewController, public toastCtrl: ToastController,
    public events: Events) {
    if (navParams.data.me == navParams.data.post.user.username) {
      this.showDelBtn = true;
    } else {
      this.showDelBtn = false;
    }
  }

  browse() {
    window.open('https://posts.pnut.io/' + this.navParams.data.post.id, '_system');
    this.close();
  }

  share() {
    (<any>window).shareContentPlugin.share(this.navParams.data.post.content.text, function(e) {
      console.log('sharing post:');
      console.log(JSON.stringify(e));
    }, function(e) {
      console.log('sharing failed:');
      console.log(JSON.stringify(e));
    });
    this.close();
  }

  delete() {
    pnut.deletePost(this.navParams.data.post.id).then(res => {
      console.log(res);
      this.presentToast('Post Deleted');
      this.events.publish('stream:reload', {});
    }).catch( err => {
      console.log('-error-');
      console.log(err);
    });
    this.close()
  }

  presentToast(text) {
    let toast = this.toastCtrl.create({
      position: 'top',
      message: text,
      duration: 2000
    });
    toast.present();
  }

  close() {
    this.viewCtrl.dismiss();
  }
}
