using InABox.Core;
using Inflector;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InABox.Poster.CSV;

public class CSVPosterSettings : PosterSettings
{
    [FileNameEditor("CSV Files (*.csv)|*.csv", RequireExisting = false)]
    public string DefaultOutputFile { get; set; }

    public override string DefaultScript(Type TPostable)
    {
        var tName = TPostable.Name;
        var decapital = tName[0..1].ToLower() + tName[1..];

        var ns = TPostable.Namespace;

        return @"
using " + ns + @";
using InABox.Poster.CSV;
using InABox.Core;
using System.Collections.Generic;

public class Module
{
    // Output Results for CSV
    public ICSVExport<" + tName + @"> Results { get; set; }

    // Customise 'model' before loading data. Return false if the post needs to be cancelled.
    public bool BeforePost(IDataModel<" + tName + @"> model)
    {
        return true;
    }

    public bool Process(IDataModel<" + tName + @"> model)
    {
        // Create new export object. You can use any object as your map,
        // but for simple cases just use " + tName + @".
        var export = new CSVExport<" + $"{tName}, {tName}" + @">();

        // Define the mapping from the fields of " + tName + @" to columns in the CSV file.
        export.DefineMapping(new()
        {
            new(""ID"", " + decapital + @" => " + decapital + @".ID),
            new(""Column1"", " + decapital + @" => " + decapital +  @".Column1),
            new(""Column2"", " + decapital + @" => " + decapital +  @".Column2),
            new(""Column3"", " + decapital + @" => " + decapital + @".Column3),
            // etc.
        });
        foreach(var " + decapital + @" in model.GetTable<" + tName + @">().ToObjects<" + tName + @">())
        {
            // Do processing
            
            // Add item to export
            export.Add(" + $"{decapital}, {decapital}" + @");
        }

        Results = export; // Set result
        return true; // return true for success.
    }

    // Perform any post-processing. All the items of type '" + tName + @" will be saved after this function is called.
    public void AfterPost(IDataModel<" + tName + @"> model)
    {
    }
}";
    }
}
