using System.Collections.ObjectModel;
using System.IO;
using System.Management;
using System.Windows.Media;

namespace HistoryView.Controls.FileSelector;

public partial class DirectorySelector : UserControl
{
    public DirectorySelector()
    {
        InitializeComponent();
        GetPaths();
    }

    private void GetPaths()
    {
        //string rootPath = System.AppDomain.CurrentDomain.BaseDirectory;
        //DirectoryInfo root = new DirectoryInfo(rootPath);
        //FileInfo[] files = root.GetFiles();
        //DirectoryInfo[] dics = root.GetDirectories();

        //BaseDisk = [];
        //BaseDisk.AddRange(dics);

        BaseFolder = [];
        string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        DriveInfo[] drives = DriveInfo.GetDrives();
        FileDisplay d = new()
        {
            Name = "Desktop",
            Path = desktopPath,
            ImageSource = App.Current.Resources["Icon_Desktop"],
            Type = DisType.Folder
        };
        BaseFolder.Add(d);

        foreach (DriveInfo basePath in drives)
        {
            FileDisplay display = new()
            {
                Name = basePath.Name,
                Path = basePath.Name,
                ImageSource = App.Current.Resources["Icon_Folder"],
                Type = DisType.Folder
            };
            BaseFolder.Add(display);
        }
    }



    public string Extension
    {
        get { return (string)GetValue(ExtensionProperty); }
        set { SetValue(ExtensionProperty, value); }
    }

    public static readonly DependencyProperty ExtensionProperty =
        DependencyProperty.Register("Extension", typeof(string), typeof(DirectorySelector), new PropertyMetadata(default));



    public ICommand Confirm
    {
        get { return (ICommand)GetValue(ConfirmProperty); }
        set { SetValue(ConfirmProperty, value); }
    }

    public static readonly DependencyProperty ConfirmProperty =
        DependencyProperty.Register("Confirm", typeof(ICommand), typeof(DirectorySelector), new PropertyMetadata(default));




    public ICommand Cancel
    {
        get { return (ICommand)GetValue(CancelProperty); }
        set { SetValue(CancelProperty, value); }
    }

    public static readonly DependencyProperty CancelProperty =
        DependencyProperty.Register("Cancel", typeof(ICommand), typeof(DirectorySelector), new PropertyMetadata(default));






    public ObservableCollection<FileDisplay> BaseFolder
    {
        get { return (ObservableCollection<FileDisplay>)GetValue(BaseFolderProperty); }
        set { SetValue(BaseFolderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for BaseFolder.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BaseFolderProperty =
        DependencyProperty.Register("BaseFolder", typeof(ObservableCollection<FileDisplay>), typeof(DirectorySelector), new PropertyMetadata(default));

    public ObservableCollection<DirectoryInfo> History
    {
        get { return (ObservableCollection<DirectoryInfo>)GetValue(HistoryProperty); }
        set { SetValue(HistoryProperty, value); }
    }

    // Using a DependencyProperty as the backing store for History.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HistoryProperty =
        DependencyProperty.Register("History", typeof(ObservableCollection<DirectoryInfo>), typeof(DirectorySelector), new PropertyMetadata(default));


    public ObservableCollection<FileDisplay> Displays
    {
        get { return (ObservableCollection<FileDisplay>)GetValue(DisplaysProperty); }
        set { SetValue(DisplaysProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Displays.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DisplaysProperty =
        DependencyProperty.Register("Displays", typeof(ObservableCollection<FileDisplay>), typeof(DirectorySelector), new PropertyMetadata(default));




    public ObservableDictionary<int, FileDisplay> Parents
    {
        get { return (ObservableDictionary<int, FileDisplay>)GetValue(ParentsProperty); }
        set { SetValue(ParentsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Parents.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ParentsProperty =
        DependencyProperty.Register("Parents", typeof(ObservableDictionary<int, FileDisplay>), typeof(DirectorySelector), new PropertyMetadata(default));



    public FileInfo SelectedFile
    {
        get { return (FileInfo)GetValue(SelectedFileProperty); }
        set { SetValue(SelectedFileProperty, value); }
    }

    public static readonly DependencyProperty SelectedFileProperty =
        DependencyProperty.Register("SelectedFile", typeof(FileInfo), typeof(DirectorySelector), new PropertyMetadata(default));



    private string _current = "";


    private static void GetFullPath(DirectoryInfo dir, ref List<FileDisplay> paths)
    {
        paths ??= [];
        FileDisplay display = new()
        {
            Name = dir.Name,
            Path = dir.FullName,
            ImageSource = App.Current.Resources["Icon_Folder"],
            Type = DisType.Folder
        };
        paths.Add(display);

        if (dir.Parent is not null)
            GetFullPath(dir.Parent, ref paths);
    }


    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var t = (Button)e.Source;
        FileDisplay d = (FileDisplay)t.CommandParameter;
        if (string.IsNullOrEmpty(d.Path))
            return;

        if (d.Type == DisType.File)
        {
            SelectedFile = new(d.Path);
            return;
        }
        DirectoryInfo dir = new(d.Path);

        List<FileDisplay> s = [];
        GetFullPath(dir, ref s);
        Parents ??= [];
        Parents.Clear();
        for (int i = s.Count - 1; i >= 0; i--)
        {
            Parents[i] = s[i];
        }

        Displays ??= [];
        Displays.Clear();
        _current = d.Path;
        FileInfo[] files = dir.GetFiles();
        DirectoryInfo[] dics = dir.GetDirectories();

        foreach (DirectoryInfo item in dics)
        {
            if (item.Attributes.HasFlag(FileAttributes.Hidden))
                continue;
            if (item.Name.StartsWith('.'))
                continue;

            FileDisplay display = new()
            {
                Name = item.Name,
                Path = item.FullName,
                ImageSource = App.Current.Resources["Icon_Folder"],
                Type = DisType.Folder
            };
            Displays.Add(display);
        }

        foreach (var item in files)
        {
            if (item.Attributes.HasFlag(FileAttributes.Hidden))
                continue;
            if (this.Extension is not null && item.Extension != this.Extension)
                continue;
            FileDisplay display = new()
            {
                Name = item.Name.Remove(item.Name.LastIndexOf(item.Extension), item.Extension.Length),
                Path = item.FullName,
                ImageSource = App.Current.Resources["Icon_File"],
                FileType = item.Extension,
                Type = DisType.File
            };
            Displays.Add(display);
        }


    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(_current))
            return;


        Displays ??= [];
        Displays.Clear();
        Parents ??= [];
        Parents.Clear();
        DirectoryInfo? temp = new DirectoryInfo(_current).Parent;
        if (temp is null)
        {
            DriveInfo[] drives = DriveInfo.GetDrives();

            foreach (DriveInfo basePath in drives)
            {
                FileDisplay display = new()
                {
                    Name = basePath.Name,
                    Path = basePath.Name,
                    ImageSource = App.Current.Resources["Icon_Folder"],
                    Type = DisType.Folder
                };
                Displays.Add(display);
            }
            return;
        }

        List<FileDisplay> s = [];
        GetFullPath(temp, ref s);

        for (int i = s.Count - 1; i >= 0; i--)
        {
            Parents[i] = s[i];
        }


        _current = temp.FullName;
        FileInfo[] files = new DirectoryInfo(_current).GetFiles();
        DirectoryInfo[] dics = new DirectoryInfo(_current).GetDirectories();

        foreach (DirectoryInfo item in dics)
        {
            if (item.Attributes.HasFlag(FileAttributes.Hidden))
                continue;
            if (item.Name.StartsWith('.'))
                continue;
            if (!string.IsNullOrEmpty(this.Extension) && this.Extension != item.Extension)
                continue;

            FileDisplay display = new()
            {
                Name = item.Name,
                Path = item.FullName,
                ImageSource = App.Current.Resources["Icon_Folder"],
                Type = DisType.Folder
            };
            Displays.Add(display);
        }

        foreach (var item in files)
        {
            if (item.Attributes.HasFlag(FileAttributes.Hidden))
                continue;

            if (!string.IsNullOrEmpty(this.Extension) && this.Extension != item.Extension)
                continue;

            FileDisplay display = new()
            {
                Name = item.Name.Replace(item.Extension, ""),
                Path = item.FullName,
                ImageSource = App.Current.Resources["Icon_File"],
                FileType = item.Extension,
                Type = DisType.File
            };
            Displays.Add(display);
        }
    }
}