using Microsoft.VisualBasic.FileIO;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace DragonVideoPlayer
{
    public class VideoListView : Form
    {
        Label lavel_sousu;
        Label lavel_pagesu;

        private ContextMenuStrip contextMenu;
        private ListView listView1;
        private ImageList imageList1;
        private TrackBar trackBar1;
        private TextBox textBox1;
        private Button button2;

        private int get_page;
        private int list_view_su;

        private CancellationTokenSource _cts;
        private System.Windows.Forms.Timer _timer;
        private MainForm _form;
        public VideoListView(MainForm form)
        {
            _form = form;
            InitializeCustomUI();

            get_page = 0;
            list_view_su = 50;

            listView1.Columns.Add("画像", 256);
            listView1.Columns.Add("パス", 200);
            listView1.Columns.Add("サイズ", 60);
            listView1.Columns.Add("更新日", 80);
            listView1.Columns.Add("作成日", 80);

            imageList1.ImageSize = new Size(256, 145);
            imageList1.ColorDepth = ColorDepth.Depth32Bit;
            listView1.SmallImageList = imageList1;
            listView1.ItemActivate += ListView1_ItemActivate;
            trackBar1.Minimum = 0;
            trackBar1.Maximum = 100;

            // TrackBar間引き
            _timer = new System.Windows.Forms.Timer();
            _timer.Interval = 200;
            _timer.Tick += (s, e) =>
            {
                _timer.Stop();
                LoadPage();
            };

            trackBar1.ValueChanged += (s, e) =>
            {
                get_page = trackBar1.Value;
                _timer.Stop();
                _timer.Start();
            };

            this.Shown += (s, e) => LoadPage();
            contextMenu = new ContextMenuStrip();
            if (config_class.config_bool_read("削除機能を有効") == true)
            {
                contextMenu.Items.Add("削除", null, DeleteMenu_Click);
            }

            listView1.ContextMenuStrip = contextMenu;
            listView1.MouseDown += ListView1_MouseDown;
            listView1.KeyDown += (s, e) =>
            {
                if (config_class.config_bool_read("削除機能を有効") == true)
                {
                    if (e.KeyCode == Keys.Delete)
                        DeleteMenu_Click(null, null);
                }
            };
        }

        private void InitializeCustomUI()
        {
            this.Text = "動画DB:ListView一覧ページ";
            this.Width = 600;
            this.Height = 600;
            listView1 = new ListView();
            imageList1 = new ImageList();
            trackBar1 = new TrackBar();
            textBox1 = new TextBox();
            button2 = new Button();

            listView1.Location = new Point(10, 100);
            listView1.Size = new Size(700, 600);
            listView1.View = View.Details;
            listView1.FullRowSelect = true;
            listView1.GridLines = true;

            trackBar1 = new TrackBar();
            trackBar1.Location = new Point(10, 70);
            trackBar1.Width = 300;
            lavel_sousu = new Label();
            lavel_sousu.Location = new Point(150, 50); ;
            lavel_sousu.Text = "DB総数";
            lavel_pagesu = new Label();
            lavel_pagesu.Text = "ページ数";
            lavel_pagesu.Location = new Point(10, 50);



            textBox1.Location = new Point(20, 20);
            textBox1.Width = 200;

            button2.Text = "検索";
            button2.Location = new Point(230, 20);
            button2.Click += (s, e) =>
            {
                get_page = 0;
                trackBar1.Value = 0;
                LoadPage();
            };

            this.Controls.Add(listView1);
            this.Controls.Add(trackBar1);
            this.Controls.Add(textBox1);
            this.Controls.Add(button2);
            this.Controls.Add(lavel_pagesu);
            this.Controls.Add(lavel_sousu);

            this.Size = new Size(900, 700);
        }
        private void ListView1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                var item = listView1.GetItemAt(e.X, e.Y);
                if (item != null)
                {
                    listView1.SelectedItems.Clear();
                    item.Selected = true;
                }
            }
        }
        private void DeleteMenu_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0) return;

            var item = listView1.SelectedItems[0];
            string path = item.SubItems[1].Text;



            if (config_class.config_bool_read("削除機能を有効") == true)
            {
                if (config_class.config_bool_read("削除で確認する") == true)
                {     //メッセージボックスを表示する
                    DialogResult result = MessageBox.Show(path + "を削除しますか？",
                "質問",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Exclamation,
                MessageBoxDefaultButton.Button2);

                    //何が選択されたか調べる
                    if (result == DialogResult.Yes)
                    {
                        try
                        {
                            Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
        path,
        UIOption.AllDialogs,
        RecycleOption.SendToRecycleBin,
        UICancelOption.DoNothing
        ); this.Text = path + "を削除しました。";
                        }
                        catch (System.Exception ex)
                        {
                            error.write_error_log(ex.Message + ex.StackTrace);
                            Debug.WriteLine(ex.Message);

                        }
                    }
                    else if (result == DialogResult.No)
                    {
                        //「いいえ」が選択された時
                        this.Text = path + "削除をキャンセルしました";
                    }
                    else if (result == DialogResult.Cancel)
                    {
                        //「キャンセル」が選択された時
                        this.Text = path + "削除をキャンセルしました";
                    }
                }

            }
            else
            {
                try
                {
                    Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
        path,
        UIOption.AllDialogs,
        RecycleOption.SendToRecycleBin,
        UICancelOption.DoNothing
        );

                    this.Text = path + "を削除しました。";
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine(ex.Message);

                }







            }
        }
        private void ListView1_ItemActivate(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0) return;

            string path = listView1.SelectedItems[0].SubItems[1].Text;

            // ここで再生
            _form.StartMpv(path);

        }
        static string ConvertUrlToFileName(string url)
        {
            // https:// または http:// を削除
            string result = Regex.Replace(url, @"^https?://", "");

            // / を _
            result = result.Replace("/", "_");

            // Windows禁止文字を削除
            result = Regex.Replace(result, @"[\\:*?""<>|]", "");

            return result;
        }
        // =========================
        // ページロード
        // =========================
        private void LoadPage()
        {
            int total = sql_class.listview_sql_count(textBox1.Text);
            lavel_sousu.Text = "DB総数:" + total.ToString();
            // ページ数
            int maxPage = (total + list_view_su - 1) / list_view_su;


            // TrackBarは0始まり
            trackBar1.Maximum = Math.Max(0, maxPage - 1);
            _cts?.Cancel();
            _cts = new CancellationTokenSource();
            var token = _cts.Token;

            listView1.Items.Clear();
            imageList1.Images.Clear();

            int start = get_page * list_view_su;
            lavel_pagesu.Text = "ページ数：" + get_page.ToString() + "/" + maxPage.ToString();
            Task.Run(() =>
            {
                List<string> list;

                if (string.IsNullOrEmpty(textBox1.Text))
                {
                    list = sql_class.sql_all_db(
                        config_class.config_int_read("動画DBのソート"),
                        config_class.config_int_read("動画DBのソートの順序"),
                        list_view_su,
                        start);
                }
                else
                {
                    list = sql_class.sql_kensaku(
                        textBox1.Text,
                        config_class.config_int_read("動画DBのソート"),
                        config_class.config_int_read("動画DBのソートの順序"),
                        list_view_su,
                        start);
                }

                if (token.IsCancellationRequested) return;

                var items = new List<ListViewItem>();
                var images = new List<Image>();

                foreach (var video_path in list)
                {
                    if (token.IsCancellationRequested) return;

                    try
                    {
                        string img_path = video_path.Replace(@":\", "_").Replace(@"\", "_") + ".jpg";
                        string full_img_path = "./img/" + img_path;

                        if (Regex.IsMatch(full_img_path, "https?:", RegexOptions.IgnoreCase))
                        {
                            String img_base = ConvertUrlToFileName(video_path);
                            string dir = "./img/";
                            full_img_path = Path.Combine(dir, img_base + ".jpg");

                        }
                        string size_st = "";
                        string stCreate = "";
                        string stUpdate = "";

                        if (File.Exists(video_path))
                        {
                            DateTime dtCreate = File.GetCreationTime(video_path);
                            DateTime dtUpdate = File.GetLastWriteTime(video_path);

                            stCreate = dtCreate.ToString("yyyy/MM/dd HH:mm");
                            stUpdate = dtUpdate.ToString("yyyy/MM/dd HH:mm");

                            long filesize = new FileInfo(video_path).Length;
                            size_st = FormatSize(filesize);
                        }

                        ListViewItem item = new ListViewItem("");

                        if (File.Exists(full_img_path))
                        {
                            Image img;
                            using (var bmpTemp = new Bitmap(full_img_path))
                            {
                                img = new Bitmap(bmpTemp);
                            }
                            images.Add(img);
                            item.ImageIndex = images.Count - 1;
                        }

                        item.SubItems.Add(video_path);
                        item.SubItems.Add(size_st);
                        item.SubItems.Add(stUpdate);
                        item.SubItems.Add(stCreate);

                        items.Add(item);
                    }
                    catch (Exception ex)
                    {
                        error.write_error_log(ex.Message + ex.StackTrace);
                        Debug.WriteLine(ex.Message);
                    }
                }

                BeginInvoke(() =>
                {
                    if (token.IsCancellationRequested) return;

                    imageList1.Images.AddRange(images.ToArray());
                    listView1.Items.AddRange(items.ToArray());
                });

            }, token);
        }

        private static string FormatSize(double size)
        {
            if (size >= 1_000_000_000)
                return (size / 1_000_000_000).ToString("0.0") + "G";
            else if (size >= 1_000_000)
                return (size / 1_000_000).ToString("0") + "M";
            else
                return (size / 1000).ToString("0") + "K";
        }
    }
}