using System.Text.Json;
using System.Text.Json.Serialization;

namespace View_by_Distance.Shared.Models;

public record FileHolder(DateTime? CreationTime,
                         string? DirectoryName,
                         bool Exists,
                         string ExtensionLowered,
                         string FullName,
                         int? Id,
                         DateTime? LastWriteTime,
                         long? Length,
                         string Name,
                         string NameWithoutExtension)
{

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, FileHolderSourceGenerationContext.Default.FileHolder);
        return result;
    }

    private static FileHolder GetExisting(FileInfo fileInfo, int? id) =>
        new(fileInfo.CreationTime,
            fileInfo.DirectoryName,
            fileInfo.Exists,
            fileInfo.Extension.ToLower(),
            fileInfo.FullName,
            id,
            fileInfo.LastWriteTime,
            fileInfo.Length,
            fileInfo.Name,
            Path.GetFileNameWithoutExtension(fileInfo.FullName));

    private static FileHolder GetNonExisting(FileInfo fileInfo, int? id) =>
        new(null,
            fileInfo.DirectoryName,
            fileInfo.Exists,
            fileInfo.Extension.ToLower(),
            fileInfo.FullName,
            id,
            null,
            null,
            fileInfo.Name,
            Path.GetFileNameWithoutExtension(fileInfo.FullName));

    public static FileHolder Get(FileInfo fileInfo, int? id) =>
        fileInfo.Exists ? GetExisting(fileInfo, id) : GetNonExisting(fileInfo, id);

    public static FileHolder Get(FilePath filePath, int? id)
    {
        FileHolder result;
        result = new(new(filePath.CreationTicks),
                     filePath.DirectoryName,
                     true,
                     filePath.ExtensionLowered,
                     filePath.FullName,
                     id,
                     new(filePath.LastWriteTicks),
                     filePath.Length,
                     filePath.Name,
                     Path.GetFileNameWithoutExtension(filePath.FullName));
        return result;
    }

    private static FileHolder GetExisting(FileHolder fileHolder) =>
        new(fileHolder.CreationTime,
            fileHolder.DirectoryName,
            fileHolder.Exists,
            fileHolder.ExtensionLowered,
            fileHolder.FullName,
            Id: null,
            fileHolder.LastWriteTime,
            fileHolder.Length,
            fileHolder.Name,
            Path.GetFileNameWithoutExtension(fileHolder.FullName));

    private static FileHolder GetNonExisting(FileHolder fileHolder) =>
        new(null,
            fileHolder.DirectoryName,
            fileHolder.Exists,
            fileHolder.ExtensionLowered,
            fileHolder.FullName,
            Id: null,
            null,
            null,
            fileHolder.Name,
            Path.GetFileNameWithoutExtension(fileHolder.FullName));

    public static FileHolder Get(FileHolder fileHolder) =>
        fileHolder.Exists ? GetExisting(fileHolder) : GetNonExisting(fileHolder);

    public static FileHolder Get(string file) =>
        Get(new FileInfo(file), id: null);

}

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FileHolder))]
internal partial class FileHolderSourceGenerationContext : JsonSerializerContext
{
}