using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LinqToTwitter;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Azyobuzi.Twirunrun
{
    public partial class MainForm : Form, ITwirunrunMainForm
    {
        public MainForm()
        {
            InitializeComponent();
            timelineTabs.Owner = this;
        }

        private string statusBrowserUri = "file:///" + (Application.StartupPath + @"\html\resultPage.html").Replace('\\', '/');

        TwitterContext twCtx = new TwitterContext();

        TwitterContext ITwirunrunMainForm.TwitterContext
        {
            get
            {
                return twCtx;
            }
        }

        UpdateStatusPanel ITwirunrunMainForm.UpdateStatusPanel
        {
            get
            {
                return updateStatusPanel1;
            }
        }

        private void IniOAuth()
        {
            var auth = new PinAuthorizer();
            auth.Credentials = new InMemoryCredentials()
            {
                ConsumerKey = AppSettings.ConsumerKey,
                ConsumerSecret = AppSettings.ConsumerSecret
            };
            if (string.IsNullOrWhiteSpace(Settings.Instance.AccessToken) || string.IsNullOrWhiteSpace(Settings.Instance.AccessTokenSecret))
            {
                auth.GoToTwitterAuthorization = (url) => Process.Start(url);
                auth.GetPin = () =>
                {
                    using (var f = new PinForm())
                    {
                        f.Text = "Twitter認証";
                        f.TopMost = true;
                        f.DescriptionLbl.Text = "Twitterの認証画面で表示される暗証番号を入力してください";
                        f.ShowDialog();
                        return f.InputText;
                    }
                };

                ((Action)(() => auth.Authorize())).IgnoreException();

                if (!auth.IsAuthorized)
                {
                    MessageBox.Show("認証できませんでした。", "Twitter認証");
                    Application.Exit();
                }

                Settings.Instance.AccessToken = auth.OAuthTwitter.OAuthToken;
                Settings.Instance.AccessTokenSecret = auth.OAuthTwitter.OAuthTokenSecret;
                Settings.Instance.MyScreenName = auth.ScreenName;
                Settings.Instance.Save();//一応保存
            }
            else
            {
                auth.Credentials.OAuthToken = Settings.Instance.AccessToken;
                auth.Credentials.AccessToken = Settings.Instance.AccessTokenSecret;
                auth.Credentials = auth.Credentials;
            }

            twCtx.AuthorizedClient = auth;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //var f = new PictureViewer("http://img.ly/show/full/2eCe");
            //f.Text = "http://img.ly/2eCe";
            //f.PictureBox.DoubleClick += (_sender, _e) => MessageBox.Show("DoubleClick");
            //f.ShowDialog();
            Icons.AddCompleted =
                () => ((TimelineTabPage)timelineTabs.SelectedTab).Timeline.Refresh();
            IniOAuth();

            #region タブ初期化
            if (Settings.Instance.Tabs.Count == 0)
                Settings.Instance.Tabs.AddRange(
                    new[]
                    {
                        new TabInfo()
                        {
                            Name = "Home",
                            Type = TabTypes.Home,
                            Deletable = false,
                            NotifyNewTweet = true,
                            RefreshInterval = 90,
                            PostGet = true,
                            GetHits = 60
                        },
                        new TabInfo()
                        {
                            Name = "Mentions",
                            Type = TabTypes.Mentions,
                            Deletable = false,
                            NotifyNewTweet = true,
                            RefreshInterval = 180,
                            GetHits = 30
                        },
                        new TabInfo()
                        {
                            Name = "DirectMessages",
                            Type = TabTypes.DirectMessages,
                            Deletable = false,
                            NotifyNewTweet = true,
                            RefreshInterval = 300,
                            GetHits = 30
                        }
                    }
                );
            #endregion
            timelineTabs.TabPages.AddRange(Settings.Instance.Tabs.Select(tab => tab.CreateTabPage(timelineTabs)).ToArray());

            LoadSettings();

            statusBrowser1.Navigate(statusBrowserUri);
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            RefreshTimelines(GetTabPages());
        }

        private IEnumerable<TimelineTabPage> GetTabPages()
        {
            return timelineTabs.TabPages.OfType<TimelineTabPage>();
        }

        private void RefreshTimelines(IEnumerable<TimelineTabPage> tabs)
        {
            var t = new Thread(() => tabs.AsParallel().ForAll(tab => tab.RefreshTimeline()));
            t.IsBackground = true;
            t.Start();
        }

        private void LoadSettings()
        {
            var s = Settings.Instance;
            updateStatusPanel1.Dock = s.PostPanelPosition;
            postPanelSplitter.Dock = s.PostPanelPosition;
            timelineTabs.Alignment = s.TabAlignment;
            updateStatusPanel1.Height = s.PostPanelHeight;
        }

        private void updateStatusPanel1_RunUpdateStatus(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(updateStatusPanel1.Text))
            {
                var t = new Thread(_ =>
                {
                    StatusChange("投稿中...");
                    var args = (Tuple<string, string>)_;
                    var status = twCtx.UpdateStatus(args.Item1, args.Item2);
                    lock (RecentStatusesCollection.Instance)
                        RecentStatusesCollection.Instance.Add(new StatusInfo(status));
                    StatusChange("投稿完了");
                    RefreshTimelines(GetTabPages().Where(tab => tab.TabSettings.PostGet));
                });
                t.IsBackground = true;
                t.Start(Tuple.Create(updateStatusPanel1.Text, updateStatusPanel1.ReplyToId));

                updateStatusPanel1.Clear();
            }
            else
                RefreshTimelines(GetTabPages().Where(tab => tab.TabSettings.PostGet));
        }

        public void StatusChange(string status)
        {
            this.Invoke((MethodInvoker)(() => statusLabel.Text = status));
        }

        private void 終了XToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public void ShowDetailStatus(StatusInfo status)
        {
            statusBrowser1.Scripts.ShowStatus(status);
        }

        private void statusBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            if (!e.Url.AbsoluteUri.Equals(Uri.EscapeUriString(statusBrowserUri), StringComparison.InvariantCultureIgnoreCase))
            {
                e.Cancel = true;
                //TODO:プレビューとか
                Process.Start(e.Url.ToString());
            }
        }
    }
}
