using Oap.OapApplication;
using OrchardCore.Autoroute.Models;
using OrchardCore.ContentFields.Fields;
using OrchardCore.ContentFields.Settings;
using OrchardCore.ContentManagement.Metadata;
using OrchardCore.ContentManagement.Metadata.Settings;
using OrchardCore.Data.Migration;
using OrchardCore.Flows.Models;
using OrchardCore.Forms.Models;
using OrchardCore.Html.Models;
using OrchardCore.Html.Settings;
using OrchardCore.Lists.Models;
using OrchardCore.Mvc.Utilities;
using OrchardCore.Title.Models;

namespace Oap.Content;

public class Migrations : DataMigration
{
	public Migrations(IContentDefinitionManager contentDefinitionManager)
	{
		m_contentDefinitionManager = contentDefinitionManager;
	}

	public async Task<int> CreateAsync()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync(ContentTypes.OapApplicationFormStep, type => type
				.Securable()
				.Draftable()
				.Versionable()
				.WithPart(nameof(TitlePart), part => part
					.WithPosition("1"))
				.WithPart(nameof(AutoroutePart), part => part
					.WithPosition("2")
					.WithSettings(new AutoroutePartSettings
					{
						AllowCustomPath = true,
						AllowUpdatePath = true,
					}))
				.WithPart(nameof(FlowPart), part => part
					.WithPosition("3")));

		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync(ContentTypes.OapApplicationForm, type => type
				.Creatable()
				.Listable()
				.Securable()
				.Draftable()
				.Versionable()
				.WithPart(nameof(AutoroutePart), part => part
					.WithPosition("2")
					.WithSettings(new AutoroutePartSettings
					{
						AllowCustomPath = true,
						AllowUpdatePath = true,
					}))
				.WithPart(nameof(ListPart), part => part
					.WithDisplayName("Form Steps")
					.WithPosition("3")
					.WithSettings(new ListPartSettings
					{
						PageSize = 10,
						EnableOrdering = true,
						ContainedContentTypes = [ContentTypes.OapApplicationFormStep]
					})
				));

		await m_contentDefinitionManager
			.AlterPartDefinitionAsync(nameof(OapApplicationPart), builder => builder
				.Attachable()
				.WithField(nameof(OapApplicationPart.Status), field => field
					.OfType(nameof(TextField))
					.WithDisplayName(nameof(OapApplicationPart.Status))
					.WithDescription("The status of the OAP Application.")
					.WithEditor("PredefinedList")
					.WithSettings(new TextFieldPredefinedListEditorSettings
					{
						Options = new[]
						{
							new ListValueOption { Name = OapApplicationStatuses.InProgress, Value = OapApplicationStatuses.InProgress.HtmlClassify() },
							new ListValueOption { Name = OapApplicationStatuses.Submitted, Value = OapApplicationStatuses.Submitted.HtmlClassify() },
						},
						DefaultValue = OapApplicationStatuses.InProgress.HtmlClassify(),
						Editor = EditorOption.Radio,
					}))
				.WithDescription("Makes a content item into an OAP Application."));

		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync(ContentTypes.OapApplication, type => type
				.Creatable()
				.Listable()
				.Securable()
				.WithPart(nameof(HtmlBodyPart), part => part
					.WithDisplayName("Notes")
					.WithSettings(new ContentTypePartSettings { Editor = "Wysiwyg", })
				)
				.WithPart(nameof(OapApplicationPart)));

		return 1;
	}

	public async Task<int> UpdateFrom1Async()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync(ContentTypes.OapApplicationFormStep, type => type
				.WithPart(nameof(HtmlBodyPart), part => part
					.WithPosition("2")
					.WithEditor("Wysiwyg")
					.WithSettings(new HtmlBodyPartSettings
					{
						SanitizeHtml = true,
					})));

		return 2;
	}

	public Task<int> UpdateFrom2Async()
	{
		return Task.FromResult(3);
	}

	public Task<int> UpdateFrom3Async()
	{
		return Task.FromResult(4);
	}

	public Task<int> UpdateFrom4Async()
	{
		return Task.FromResult(5);
	}

	public Task<int> UpdateFrom5Async()
	{
		return Task.FromResult(6);
	}

	public async Task<int> UpdateFrom6Async()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync(ContentTypes.OapApplicationForm, type => type
				.WithPart(nameof(TitlePart)));

		return 7;
	}

	public async Task<int> UpdateFrom7Async()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Input", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("1")
					.WithDisplayName("Details to help the user correctly fill out this form field.")
					.WithEditor("Wysiwyg")
                ));

		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("TextArea", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("1")
					.WithDisplayName("Details to help the user correctly fill out this form field.")
					.WithEditor("Wysiwyg")
                ));
				
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Select", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("1")
					.WithDisplayName("Details to help the user correctly fill out this form field.")
					.WithEditor("Wysiwyg")
                ));

		return 8;
	}

	public async Task<int> UpdateFrom8Async()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Input", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("4")
                )
                .WithPart("InputPart", part => part
                    .WithPosition("5")
                )
                .WithPart("FormElementValidationPart", part => part
                    .WithPosition("6")
                ));

		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("TextArea", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("4")
                )
                .WithPart("TextAreaPart", part => part
                    .WithPosition("5")
                )
                .WithPart("FormElementValidationPart", part => part
                    .WithPosition("6")
                ));
				
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Select", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
                    .WithPosition("4")
                )
                .WithPart("SelectPart", part => part
                    .WithPosition("5")
                )
                .WithPart("FormElementValidationPart", part => part
                    .WithPosition("6")
                ));

		return 9;
	}
	public async Task<int> UpdateFrom9Async()
	{
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Input", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
					.WithDisplayName("Explanation")
					.WithDescription("Details to help the user correctly fill out this form field.")
                ));

		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("TextArea", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
					.WithDisplayName("Explanation")
					.WithDescription("Details to help the user correctly fill out this form field.")
                ));
				
		await m_contentDefinitionManager
			.AlterTypeDefinitionAsync("Select", type => type
				.WithPart("Explanation", "HtmlBodyPart", part => part
					.WithDisplayName("Explanation")
					.WithDescription("Details to help the user correctly fill out this form field.")
                ));

		return 10;
	}

	private readonly IContentDefinitionManager m_contentDefinitionManager;
}
