using QVCopier.Models;
using System;
using System.Linq;
using System.Windows.Forms;
using QVCopier.Utility;

namespace QVCopier
{
    public partial class QvcMainForm : Form
    {
        private void InitLogger()
        {
            UpdateLogStat();
            Logger.LogAdded += Logger_LogAdded;
            Logger.Info("Application started.");
        }


        private void Logger_LogAdded(object sender, LogEntry e)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<LogEntry>(AddLog), e);
            }
            else
            {
                AddLog(e);
            }
        }

        private void AddLog(LogEntry e)
        {
            _logs.Add(e);
            UpdateLogStat();
            switch (e.Level)
            {
                case LogLevel.Debug:
                    if (DebugCheckBox.Checked) LogListView.Items.Add(CreateLogListViewItem(e));
                    break;

                case LogLevel.Info:
                    if (InfoCheckBox.Checked) LogListView.Items.Add(CreateLogListViewItem(e));
                    break;

                case LogLevel.Warning:
                    if (WarningCheckBox.Checked) LogListView.Items.Add(CreateLogListViewItem(e));
                    break;

                case LogLevel.Error:
                    if (ErrorCheckBox.Checked) LogListView.Items.Add(CreateLogListViewItem(e));
                    break;

                case LogLevel.Fatal:
                    if (FatalCheckBox.Checked) LogListView.Items.Add(CreateLogListViewItem(e));
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void UpdateLogStat()
        {
            FatalCheckBox.Text = $"Fatal({_logs.Count(p => p.Level == LogLevel.Fatal)})";
            ErrorCheckBox.Text = $"Error({_logs.Count(p => p.Level == LogLevel.Error)})";
            WarningCheckBox.Text = $"Warning({_logs.Count(p => p.Level == LogLevel.Warning)})";
            InfoCheckBox.Text = $"Info({_logs.Count(p => p.Level == LogLevel.Info)})";
            DebugCheckBox.Text = $"Debug({_logs.Count(p => p.Level == LogLevel.Debug)})";
        }

        private ListViewItem CreateLogListViewItem(LogEntry logEntry)
        {
            return new()
            {
                Text = logEntry.Time.ToString("yyyy-MM-dd HH:mm:ss.ff"),
                SubItems =
                {
                    logEntry.Level.ToString(),
                    logEntry.Log
                }
            };
        }

        private void LogFilterCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            LogListView.Items.Clear();
            LogListView.Items.AddRange(_logs.Where(p =>
            {
                switch (p.Level)
                {
                    case LogLevel.Debug: return DebugCheckBox.Checked;
                    case LogLevel.Info: return InfoCheckBox.Checked;
                    case LogLevel.Warning: return WarningCheckBox.Checked;
                    case LogLevel.Error: return ErrorCheckBox.Checked;
                    case LogLevel.Fatal: return FatalCheckBox.Checked;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }).Select(CreateLogListViewItem).ToArray());
        }
    }
}