using System.Diagnostics;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace DragonVideoPlayer
{
    public class ReservationItem
    {
        public string Title { get; set; }
        public string Memo { get; set; }
        public string Url { get; set; }
        public string Start { get; set; }
        public string Minutes { get; set; }
    }
    public partial class ReservationForm : Form
    {
        private DataGridView gridRecording;
        private Button btnStop;
        private Button btn_del2;
        private Button btn_clear2;

        private HashSet<string> startedSet = new HashSet<string>();
        private const string SAVE_FILE = "reservations.json";
        private MenuStrip menuStrip1;
        private TextBox txtUrl;
        private TextBox txtMemo;
        private TextBox txtTitle;
        private DateTimePicker dtStart;
        private NumericUpDown numMinutes;
        private Button btnAdd;
        private Button btnDelete;
        private Button btnClear;
        private DataGridView grid;
        private System.Windows.Forms.Timer reservationTimer;
        private readonly Dictionary<int, Process> runningProcesses = new();

        public ReservationForm()
        {
            InitializeUI();
            Load += ReservationForm_Load;
            FormClosing += (s, e) => SaveReservations();
        }

        private void InitializeUI()
        {
            Width = 800;
            Height = 600;
            Text = "予約録画";
            var tab = new TabControl
            {
                Dock = DockStyle.Fill
            };

            var tabMain = new TabPage("予約一覧");
            var tabRecording = new TabPage("録画中");

            tab.TabPages.Add(tabMain);
            tab.TabPages.Add(tabRecording);

            Controls.Add(tab);
            menuStrip1 = new MenuStrip();
            Controls.Add(menuStrip1);

            txtUrl = new TextBox { Left = 20, Top = 40, Width = 400 };
            txtTitle = new TextBox { Left = 20, Top = 75, Width = 120 };

            txtMemo = new TextBox { Left = 160, Top = 75, Width = 200 };
              dtStart = new DateTimePicker
            {
                Left = 20,
                Top = 105,
                Width = 150,
                Format = DateTimePickerFormat.Custom,
                CustomFormat = "yyyy/MM/dd HH:mm:ss"
            };
            numMinutes = new NumericUpDown
            {
                Left = 180,
                Top = 105,
                Width = 120,
                Minimum = 1,
                Maximum = 1440,
                Value = 60
            };

            btnAdd = new Button { Left = 20, Top = 140, Width = 100, Text = "追加" };
            btnClear = new Button { Left = 130, Top = 140, Width = 100, Text = "全クリア" };
            btnDelete = new Button { Left = 240, Top = 140, Width = 100, Text = "削除" };

            btnAdd.Click += BtnAdd_Click;
            btnDelete.Click += BtnDelete_Click;
            btnClear.Click += BtnClear_Click;

            grid = new DataGridView
            {
                Left = 20,
                Top = 180,
                Width = 550,
                Height = 300,
                AllowUserToAddRows = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                MultiSelect = false,
                ReadOnly = true
            };
            grid.ScrollBars = ScrollBars.Vertical;
            grid.Columns.Add("Title", "タイトル");
            grid.Columns.Add("Memo", "覚書");
            grid.Columns.Add("Url", "URL");
            grid.Columns.Add("Start", "開始時間");
            grid.Columns.Add("Minutes", "録画時間(分)");

            tabMain.Controls.Add(txtUrl);
            tabMain.Controls.Add(txtTitle);
            tabMain.Controls.Add(txtMemo);
            tabMain.Controls.Add(dtStart);
            tabMain.Controls.Add(numMinutes);
            tabMain.Controls.Add(btnAdd);
            tabMain.Controls.Add(btnDelete);
            tabMain.Controls.Add(btnClear);
            tabMain.Controls.Add(grid);

            MainMenuStrip = menuStrip1;

            reservationTimer = new System.Windows.Forms.Timer();
            reservationTimer.Interval = 1000;
            reservationTimer.Tick += ReservationTimer_Tick;
            gridRecording = new DataGridView
            {
             
                Left = 20,
                Top = 40,
                Width = 400,
                Height = 500,
                AllowUserToAddRows = false,
                SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                MultiSelect = false,
                ReadOnly = true
            };
            
            btnStop = new Button
            {
                
                Left = 0,
                Top = 0,
                Text = "停止",
              
                Height = 40
            };

            btn_del2 = new Button
            {

                Left = 100,
                Top = 0,
                Text = "削除",

                Height = 40
            };
            btn_clear2 = new Button
            {

                Left = 170,
                Top = 0,
                Text = "クリア",

                Height = 40
            };
            btnStop.Click += BtnStop_Click;
            btn_del2.Click += btn_del2_Click;
            btn_clear2.Click += btn_clear2_Click;

            gridRecording.ScrollBars = ScrollBars.Vertical;
            gridRecording.Columns.Add("Key", "ID");
            gridRecording.Columns.Add("Title", "タイトル");
            gridRecording.Columns.Add("Start", "開始時刻");
            tabRecording.Controls.Add(btnStop);
            tabRecording.Controls.Add(btn_del2);
            tabRecording.Controls.Add(btn_clear2);
            tabRecording.Controls.Add(gridRecording);
           
          
            
        }
        private void SaveReservations()
        {
            try
            {
                var list = new List<ReservationItem>();

                foreach (DataGridViewRow row in grid.Rows)
                {
                    list.Add(new ReservationItem
                    {
                        Title = row.Cells[0].Value?.ToString(),
                        Memo = row.Cells[1].Value?.ToString(),
                        Url = row.Cells[2].Value?.ToString(),
                        Start = row.Cells[3].Value?.ToString(),
                        Minutes = row.Cells[4].Value?.ToString()
                    });
                }

                File.WriteAllText(SAVE_FILE,
                    JsonSerializer.Serialize(list, new JsonSerializerOptions
                    {
                        WriteIndented = true
                    }));
            }
            catch { }
        }
        private void LoadReservations()
        {
            if (!File.Exists(SAVE_FILE)) return;

            try
            {
                var json = File.ReadAllText(SAVE_FILE);
                var list = JsonSerializer.Deserialize<List<ReservationItem>>(json);

                grid.Rows.Clear();

                foreach (var item in list)
                {
                    // 過去の予約はスキップ（重要）
                    if (DateTime.TryParse(item.Start, out DateTime dt))
                    {
                        if (dt < DateTime.Now) continue;
                    }

                    grid.Rows.Add(item.Title, item.Memo, item.Url, item.Start, item.Minutes);
                }
            }
            catch { }
        }
        private void ReservationForm_Load(object sender, EventArgs e)
        {
            string[] files =
            {
                "abema.txt", "abema2.txt", "mov3.txt", "primehome.txt",
                "radiko.txt", "rakuten.txt", "utako_moe.txt","arva.txt"
            };

            foreach (var file in files)
            {
                AddMenuFromTxt(file);
            }

            reservationTimer.Start();
            LoadReservations();
        }

        private void AddMenuFromTxt(string file)
        {
            if (!File.Exists(file)) return;

            var root = new ToolStripMenuItem(Path.GetFileNameWithoutExtension(file));
            menuStrip1.Items.Add(root);

            foreach (var url in File.ReadAllLines(file).Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                string title = GetTitleFromUrl(url);
                var item = new ToolStripMenuItem(title);
                item.Tag = url;
                item.Click += (s, e) =>
                {
                    txtUrl.Text = (string)((ToolStripMenuItem)s).Tag;
                    txtTitle.Text = ((ToolStripMenuItem)s).Text;
                };
                root.DropDownItems.Add(item);
            }
        }


        private string GetTitleFromUrl(string url)
        {
            if (url.Contains("linear-abematv")) return title_generate.Get_abema(url, 3);
            if (url.Contains("mov3")) return title_generate.Get_mov3(url); if (url.Contains("mov3")) return title_generate.Get_mov3(url);
            if (url.Contains("ok.ru")) return title_generate.Get_mov3(url); if (url.Contains("mov3")) return title_generate.Get_mov3(url);

            if (url.Contains("arva.netgenx.site")) return title_generate.Get_arva_netgen(url);

            if (url.Contains("abema.tv/now-on-air")) return title_generate.Get_abema(url, 2);
            if (url.Contains("rakuten")) return title_generate.GetName_rakuten(url, 2);
            if (url.Contains("primehome")) return title_generate.Get_primehome(url);
            if (url.Contains("radiko")) return title_generate.GetRadikoStation(url);
            if (url.Contains("utako")) return title_generate.Get_UtakoMoe(url);
            return url;
        }

        private void BtnAdd_Click(object sender, EventArgs e)
        {
            grid.Rows.Add(
                txtTitle.Text,
                txtMemo.Text,
                txtUrl.Text,
                dtStart.Value.ToString("yyyy/MM/dd HH:mm:ss"),
                numMinutes.Value.ToString());
        }

        private void BtnDelete_Click(object sender, EventArgs e)
        {
            if (grid.SelectedRows.Count > 0)
            {
                grid.Rows.Remove(grid.SelectedRows[0]);
            }
        }

        private void BtnClear_Click(object sender, EventArgs e)
        {
            grid.Rows.Clear();
        }

        private void ReservationTimer_Tick(object sender, EventArgs e)
        {
            for (int i = grid.Rows.Count - 1; i >= 0; i--)
            {
                var row = grid.Rows[i];
                DateTime start = DateTime.Parse(row.Cells[3].Value.ToString());
                int minutes = int.Parse(row.Cells[4].Value.ToString());
                string url = row.Cells[2].Value.ToString();
                string title = row.Cells[0].Value.ToString();
                string note_text= row.Cells[1].Value.ToString();

                string uniqueId = url + start.ToString();

                if (startedSet.Contains(uniqueId))
                    continue;

                if (DateTime.Now >= start)
                {
                  
                    startedSet.Add(uniqueId);

                    grid.Rows.RemoveAt(i);

                    int key = Guid.NewGuid().GetHashCode();
                    StartRecording(url, title, note_text, minutes, key);

                    SaveReservations();
              
             
                }
            }
        }

        private void StartRecording(string url, string title,String note, int minutes, int key)
        {
            try
            {
                title = filename.FileName_repalce(title);
                string date_st = DateTime.Now.ToString("yyyy年M月d日HH時mm分");
               string output = "";
                if (string.IsNullOrEmpty(note) == true)
                {
                    output = $"{title}_{date_st}.mp4";
                }
                else
                {
                    note = filename.FileName_repalce(note);

                    output = $"{title}_{note}_{date_st}.mp4";

                }
                string ytdlp_path = config_class.config_text_read("yt-dlpのパス");
                string stream_path = config_class.config_text_read("streamlinkのパス");

                ProcessStartInfo psi;

                if (Regex.IsMatch(url, @"m3u8", RegexOptions.IgnoreCase))
                {
                    psi = new ProcessStartInfo
                    {
                        FileName = ytdlp_path,
                        Arguments = $"\"{url}\" --no-part -o \"{output}\"",
                        UseShellExecute = true
                    };
                }
                else
                {
                    psi = new ProcessStartInfo
                    {
                        FileName = stream_path,
                        Arguments = $"\"{url}\" best -o \"{output}\"",
                        UseShellExecute = true
                    };
                }
                Debug.WriteLine(psi.FileName +" "+psi.Arguments);
                var proc = Process.Start(psi);
                runningProcesses[key] = proc;

                // 録画中リスト追加（UIスレッド）
                BeginInvoke(() =>
                {
                    gridRecording.Rows.Add(key, title, DateTime.Now.ToString("HH:mm:ss"));
                });

                // 自動終了
                Task.Run(async () =>
                {
                    await Task.Delay(TimeSpan.FromMinutes(minutes));

                    StopRecording(key);
                });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        private void btn_del2_Click(object sender, EventArgs e)
        {
            if (gridRecording.SelectedRows.Count > 0)
            {
                gridRecording.Rows.Remove(gridRecording.SelectedRows[0]);
            }
        }
        private void btn_clear2_Click(object sender, EventArgs e)
        {
            gridRecording.Rows.Clear();
        }

      
        private void StopRecording(int key)
        {
            try
            {
                if (runningProcesses.TryGetValue(key, out var p))
                {
                    if (!p.HasExited)
                        p.Kill(true);
                }
            }
            catch { }

            runningProcesses.Remove(key);

            // UIから削除
            BeginInvoke(() =>
            {
                foreach (DataGridViewRow row in gridRecording.Rows)
                {
                    if ((int)row.Cells[0].Value == key)
                    {
                        gridRecording.Rows.Remove(row);
                        break;
                    }
                }
            });
        }
        private void BtnStop_Click(object sender, EventArgs e)
        {
            if (gridRecording.SelectedRows.Count == 0) return;

            int key = (int)gridRecording.SelectedRows[0].Cells[0].Value;

            StopRecording(key);
        }
    }
}
