import { umbDocumentTypeData } from './document-type/document-type.db.js';
import { umbUserPermissionData } from './user-permission.data.js';
import { UmbEntityData } from './entity.data.js';
import { createDocumentTreeItem } from './utils.js';
import { UmbMockDocumentTypeModel } from './document-type/document-type.data.js';
import {
	ContentStateModel,
	DocumentItemResponseModel,
	DocumentResponseModel,
	DocumentTreeItemResponseModel,
	DocumentTypeResponseModel,
	PagedDocumentTreeItemResponseModel,
	PagedDocumentTypeResponseModel,
	PagedRecycleBinItemResponseModel,
	PublishDocumentRequestModel,
	PublishedStateModel,
} from '@umbraco-cms/backoffice/backend-api';
import { UMB_DOCUMENT_ENTITY_TYPE } from '@umbraco-cms/backoffice/document';

export const data: Array<DocumentResponseModel> = [
	{
		urls: [
			{
				culture: 'en-US',
				url: '/',
			},
		],
		isTrashed: false,
		templateId: null,
		id: 'all-property-editors-document-id',
		contentTypeId: 'all-property-editors-document-type-id',
		values: [
			{
				alias: 'richTextEditor',
				culture: null,
				segment: null,
				value:
					'Some value for the RTE with an <a href="http://foo.com">external link</a> and an <a href="/{localLink:umb://document/c05da24d7740447b9cdcbd8ce2172e38}">internal link</a> foo foo <div class="umb-macro-holder TestMacro umb-macro-mce_1 mceNonEditable"><!-- <?UMBRACO_MACRO macroAlias="TestMacro" /> --><ins>Macro alias: <strong>TestMacro</strong></ins></div>',
			},
			{
				alias: 'email',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'colorPicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'contentPicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'eyeDropper',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'multiUrlPicker',
				culture: 'en-us',
				segment: null,
				value: [
					{
						name: undefined,
						published: undefined,
						queryString: undefined,
						target: undefined,
						trashed: undefined,
						udi: 'umb://document/c05da24d7740447b9cdcbd8ce2172e38',
						url: 'umb://document/c05da24d7740447b9cdcbd8ce2172e38',
					},
				],
			},
			{
				alias: 'multiUrlPicker',
				culture: 'da-dk',
				segment: null,
				value: null,
			},
			{
				alias: 'multiNodeTreePicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'datePicker',
				culture: null,
				segment: null,
				value: '2023-12-24',
			},
			{
				alias: 'datePickerTime',
				culture: null,
				segment: null,
				value: '2023-12-24 14:52',
			},
			{
				alias: 'time',
				culture: null,
				segment: null,
				value: '14:52:00',
			},
			{
				alias: 'email',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'textBox',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'dropdown',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'textArea',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'slider',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'toggle',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'tags',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'markdownEditor',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'radioButtonList',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'checkboxList',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'blockList',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'mediaPicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'imageCropper',
				culture: null,
				segment: null,
				value: {
					focalPoint: { left: 0.5, top: 0.5 },
					src: 'data:image/png;base64,[encoded data, 77548 characters]',
					crops: [
						{
							alias: 'Almost Bot Left',
							width: 1000,
							height: 1000,
							coordinates: {
								x1: 0.04113924050632909,
								x2: 0.3120537974683548,
								y1: 0.32154746835443077,
								y2: 0.031645569620253146,
							},
						},
						{
							alias: 'Almost top right',
							width: 1000,
							height: 1000,
							coordinates: {
								x1: 0.3086962025316458,
								x2: 0.04449683544303807,
								y1: 0.04746835443037985,
								y2: 0.305724683544304,
							},
						},
						{
							alias: 'TopLeft',
							width: 1000,
							height: 1000,
							coordinates: {
								x1: 0,
								x2: 0.5,
								y1: 0,
								y2: 0.5,
							},
						},
						{
							alias: 'bottomRight',
							width: 1000,
							height: 1000,
							coordinates: {
								x1: 0.5,
								x2: 0,
								y1: 0.5,
								y2: 0,
							},
						},
						{
							alias: 'Gigantic crop',
							width: 40200,
							height: 104000,
						},
						{
							alias: 'Desktop',
							width: 1920,
							height: 1080,
						},
						{
							alias: 'Banner',
							width: 1920,
							height: 300,
						},
						{
							alias: 'Tablet',
							width: 600,
							height: 800,
						},
						{
							alias: 'Mobile',
							width: 400,
							height: 800,
						},
					],
				},
			},
			{
				alias: 'uploadField',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'blockGrid',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'blockGrid',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'numberRange',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'orderDirection',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'overlaySize',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'label',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'integer',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'decimal',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'memberPicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'memberGroupPicker',
				culture: null,
				segment: null,
				value: null,
			},
			{
				alias: 'userPicker',
				culture: null,
				segment: null,
				value: null,
			},
		],
		variants: [
			{
				state: ContentStateModel.PUBLISHED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'en-us',
				segment: null,
				name: 'All properties',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
			{
				state: ContentStateModel.PUBLISHED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'da-dk',
				segment: null,
				name: 'Alle redigeringsfelter',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
		],
	},
	{
		urls: [
			{
				culture: 'en-US',
				url: '/',
			},
		],
		templateId: null,
		id: 'c05da24d-7740-447b-9cdc-bd8ce2172e38',
		contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681',
		isTrashed: false,
		values: [
			{
				culture: null,
				segment: null,
				alias: 'masterText',
				value: 'i have a master text',
			},
			{
				culture: null,
				segment: null,
				alias: 'pageTitle',
				value: 'with a page title',
			},
			{
				culture: null,
				segment: null,
				alias: 'blogPostText',
				value: 'My first blog post',
			},
			{
				culture: 'en-us',
				segment: null,
				alias: 'blogTextStringUnderMasterTab',
				value: 'in the master tab',
			},
			{
				culture: 'en-us',
				segment: null,
				alias: 'blogTextStringUnderGroupUnderMasterTab',
				value: 'which is under another group in the tab',
			},
			{
				culture: 'da-dk',
				segment: null,
				alias: 'blogTextStringUnderMasterTab',
				value: 'på master dokument tab B',
			},
			{
				culture: 'da-dk',
				segment: null,
				alias: 'blogTextStringUnderGroupUnderMasterTab',
				value: 'denne er under en anden gruppe i tab B',
			},
			{
				culture: 'no-no',
				segment: null,
				alias: 'blogTextStringUnderMasterTab',
				value: 'Norsk på master dokument tab B',
			},
			{
				culture: 'no-no',
				segment: null,
				alias: 'blogTextStringUnderGroupUnderMasterTab',
				value: 'Norsk denne er under en anden gruppe i tab B',
			},
			{
				culture: null,
				segment: null,
				alias: 'localBlogTabString',
				value: '1234567',
			},
		],
		variants: [
			{
				state: ContentStateModel.PUBLISHED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'en-us',
				segment: null,
				name: 'Article in english',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
			{
				state: ContentStateModel.PUBLISHED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'da-dk',
				segment: null,
				name: 'Artikel på Dansk',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
			{
				state: ContentStateModel.PUBLISHED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'no-no',
				segment: null,
				name: 'Artikel på Norsk',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
			{
				state: ContentStateModel.PUBLISHED_PENDING_CHANGES,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'es-es',
				segment: null,
				name: 'Articulo en ingles',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
			{
				state: ContentStateModel.NOT_CREATED,
				publishDate: '2023-02-06T15:31:51.354764',
				culture: 'pl-pl',
				segment: null,
				name: 'Artykuł w języku polskim',
				createDate: '2023-02-06T15:31:46.876902',
				updateDate: '2023-02-06T15:31:51.354764',
			},
		],
	},
	{
		urls: [],
		templateId: null,
		id: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4',
		contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681',
		isTrashed: false,
		values: [
			{
				culture: null,
				segment: null,
				alias: 'masterText',
				value: 'i have a master text B',
			},
			{
				culture: null,
				segment: null,
				alias: 'pageTitle',
				value: 'with a page title B',
			},
			{
				culture: null,
				segment: null,
				alias: 'blogPostText',
				value: 'My first blog post B',
			},
			{
				culture: 'en-us',
				segment: null,
				alias: 'blogTextStringUnderMasterTab',
				value: 'in the master tab B',
			},
			{
				culture: 'en-us',
				segment: null,
				alias: 'blogTextStringUnderGroupUnderMasterTab',
				value: 'which is under another group in the tab B',
			},
			{
				culture: 'da-dk',
				segment: null,
				alias: 'blogTextStringUnderMasterTab',
				value: 'på master dokument tab B',
			},
			{
				culture: 'da-dk',
				segment: null,
				alias: 'blogTextStringUnderGroupUnderMasterTab',
				value: 'denne er under en anden gruppe i tab B',
			},
			{
				culture: null,
				segment: null,
				alias: 'localBlogTabString',
				value: '1234567890',
			},
		],
		variants: [
			{
				state: ContentStateModel.DRAFT,
				publishDate: '2023-02-06T15:32:24.957009',
				culture: 'en-us',
				segment: null,
				name: 'Blog post B',
				createDate: '2023-02-06T15:32:05.350038',
				updateDate: '2023-02-06T15:32:24.957009',
			},
		],
	},
	{
		urls: [
			{
				culture: 'en-US',
				url: '/',
			},
		],
		templateId: null,
		id: 'simple-document-id',
		contentTypeId: 'simple-document-type-id',
		isTrashed: false,
		variants: [
			{
				state: ContentStateModel.DRAFT,
				publishDate: '2023-02-06T15:32:24.957009',
				culture: 'en-us',
				segment: null,
				name: 'Simple Document',
				createDate: '2023-02-06T15:32:05.350038',
				updateDate: '2023-02-06T15:32:24.957009',
			},
		],
		values: [
			{
				alias: 'multiNodeTreePicker',
				culture: null,
				segment: null,
				value: null,
			},
		],
	},
];

export const treeData: Array<DocumentTreeItemResponseModel> = [
	{
		isProtected: false,
		isPublished: true,
		isEdited: false,
		noAccess: false,
		isTrashed: false,
		id: 'all-property-editors-document-id',
		contentTypeId: 'all-property-editors-document-type-id',
		isContainer: false,
		parentId: null,
		name: 'All property editors',
		type: 'document',
		icon: 'document',
		hasChildren: false,
		variants: [
			{
				name: 'All property editors',
				culture: 'en-us',
				state: PublishedStateModel.PUBLISHED,
			},
			{
				name: 'All property editors',
				culture: 'da-dk',
				state: PublishedStateModel.PUBLISHED,
			},
		],
	},
	{
		isProtected: false,
		isPublished: true,
		isEdited: false,
		noAccess: false,
		isTrashed: false,
		id: 'c05da24d-7740-447b-9cdc-bd8ce2172e38',
		contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681',
		isContainer: false,
		parentId: null,
		name: 'Article in english',
		type: 'document',
		icon: 'document',
		hasChildren: true,
		variants: [
			{
				state: PublishedStateModel.PUBLISHED,
				culture: 'en-us',
				name: 'Article in english',
			},
			{
				state: PublishedStateModel.PUBLISHED,
				culture: 'da-dk',
				name: 'Artikel på Dansk',
			},
			{
				state: PublishedStateModel.PUBLISHED,
				culture: 'no-no',
				name: 'Artikel på Norsk',
			},
			{
				state: PublishedStateModel.PUBLISHED,
				culture: 'es-es',
				name: 'Articulo en ingles',
			},
			{
				state: PublishedStateModel.PUBLISHED,
				culture: 'pl-pl',
				name: 'Artykuł w języku polskim',
			},
		],
	},
	{
		isProtected: false,
		isPublished: false,
		isEdited: false,
		noAccess: false,
		isTrashed: false,
		id: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4',
		contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681',
		isContainer: false,
		parentId: 'c05da24d-7740-447b-9cdc-bd8ce2172e38',
		name: 'Blog post B',
		type: 'document',
		icon: 'document',
		hasChildren: false,
		variants: [
			{
				state: PublishedStateModel.UNPUBLISHED,
				culture: 'en-us',
				name: 'Blog post B',
			},
		],
	},
	{
		name: 'Simple',
		type: 'document',
		icon: 'document',
		hasChildren: false,
		id: 'simple-document-id',
		contentTypeId: 'simple-document-type-id',
		isContainer: false,
		parentId: null,
		noAccess: false,
		isProtected: false,
		isPublished: false,
		isEdited: false,
		isTrashed: false,
		variants: [
			{
				state: PublishedStateModel.UNPUBLISHED,
				culture: 'en-us',
				name: 'Simple Document',
			},
		],
	},
];

const createDocumentItem = (item: DocumentResponseModel): DocumentItemResponseModel => {
	return {
		id: item.id,
		name: item.variants?.[0].name, // Hack: TODO: we need to get all variants as part of the document
		contentTypeId: item.contentTypeId,
		isTrashed: item.isTrashed,
	};
};

// TODO: look into making a combined document model so we don't need to maintain two+ data sets.
// Temp mocked database
// TODO: all properties are optional in the server schema. I don't think this is correct.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
class UmbDocumentData extends UmbEntityData<DocumentResponseModel> {
	private treeData = treeData;

	constructor() {
		super(data);
	}

	// TODO: Can we do this smarter so we don't need to make this for each mock data:
	insert(item: DocumentResponseModel) {
		super.insert(item);
		this.treeData.push(createDocumentTreeItem(item));
	}

	update(id: string, item: DocumentResponseModel) {
		super.save(id, item);
		this.treeData = this.treeData.map((x) => {
			if (x.id === id) {
				return createDocumentTreeItem(item);
			} else {
				return x;
			}
		});
	}

	publish(id: string, data: PublishDocumentRequestModel) {
		// Update detail data:
		const foundIndex = this.data.findIndex((item) => item.id === id);
		if (foundIndex !== -1) {
			// update
			this.data[foundIndex].variants?.forEach((variant) => {
				if (data.cultures?.includes(variant.culture ?? '')) {
					variant.state = ContentStateModel.PUBLISHED;
				}
			});
		}

		// TODO: Tree data is not aware about variants and status of variants: so this is not good enough:
		this.treeData = this.treeData.map((x) => {
			if (x.id && x.id === id) {
				return { ...x, isPublished: true };
			} else {
				return x;
			}
		});
		return true;
	}

	unpublish(id: string, data: PublishDocumentRequestModel) {
		// Update detail data:
		const foundIndex = this.data.findIndex((item) => item.id === id);
		if (foundIndex !== -1) {
			// update
			this.data[foundIndex].variants?.forEach((variant) => {
				if (data.cultures?.includes(variant.culture ?? '')) {
					variant.state = ContentStateModel.DRAFT;
				}
			});
		}

		// TODO: Tree data is not aware about variants and status of variants: so this is not good enough:
		this.treeData = this.treeData.map((x) => {
			if (x.id && x.id === id) {
				return { ...x, isPublished: false };
			} else {
				return x;
			}
		});

		return true;
	}

	trash(ids: string[]): DocumentResponseModel[] {
		const result = super.trash(ids);
		this.treeData = this.treeData.map((x) => {
			if (x.id && ids.includes(x.id)) {
				return { ...x, isTrashed: true };
			} else {
				return x;
			}
		});
		return result;
	}

	getTreeRoot(): PagedDocumentTreeItemResponseModel {
		const items = this.treeData.filter((item) => item.parentId === null && item.isTrashed === false);
		const treeItems = items.map((item) => item);
		const total = items.length;
		return { items: treeItems, total };
	}

	getTreeItemChildrenOf(id: string): PagedDocumentTreeItemResponseModel {
		const items = this.treeData.filter((item) => item.parentId === id && item.isTrashed === false);
		const treeItems = items.map((item) => item);
		const total = items.length;
		return { items: treeItems, total };
	}

	getTreeItem(ids: Array<string>): Array<DocumentTreeItemResponseModel> {
		const items = this.treeData.filter((item) => ids.includes(item.id ?? ''));
		return items.map((item) => item);
	}

	getItems(ids: Array<string>): Array<DocumentItemResponseModel> {
		const items = this.data.filter((item) => ids.includes(item.id ?? ''));
		return items.map((item) => createDocumentItem(item));
	}

	getDocumentByIdAllowedDocumentTypes(id: string): PagedDocumentTypeResponseModel {
		const item = this.getById(id);
		if (item?.contentTypeId) {
			const docType = umbDocumentTypeData.getById(item.contentTypeId);

			if (docType) {
				const allowedTypes = docType?.allowedContentTypes ?? [];
				const mockedTypes = allowedTypes
					.map((allowedType) => umbDocumentTypeData.getById(allowedType.id))
					.filter((item) => item !== undefined) as Array<UmbMockDocumentTypeModel>;
				const items = mockedTypes.map((item) => mapToDocumentType(item));
				const total = items.length;
				return { items, total };
			}
		}
		return { items: [], total: 0 };
	}

	getAllowedDocumentTypesAtRoot(): PagedDocumentTypeResponseModel {
		return umbDocumentTypeData.getAll(); //.filter((docType) => docType.allowedAsRoot);
	}

	getRecycleBinRoot(): PagedRecycleBinItemResponseModel {
		const items = this.treeData.filter((item) => item.parentId === null && item.isTrashed === true);
		const treeItems = items.map((item) => item);
		const total = items.length;
		return { items: treeItems, total };
	}

	getRecycleBinChildrenOf(parentId: string): PagedRecycleBinItemResponseModel {
		const items = this.treeData.filter((item) => item.parentId === parentId && item.isTrashed === true);
		const treeItems = items.map((item) => item);
		const total = items.length;
		return { items: treeItems, total };
	}

	// permissions

	getUserPermissionsForDocument(id: string): Array<any> {
		return umbUserPermissionData
			.getAll()
			.items.filter(
				(permission: any) =>
					permission.target.entityType === UMB_DOCUMENT_ENTITY_TYPE && permission.target.documentId === id,
			);
	}
}

const mapToDocumentType = (item: UmbMockDocumentTypeModel): DocumentTypeResponseModel => {
	return {
		alias: item.alias,
		name: item.name,
		description: item.description,
		icon: item.icon,
		allowedAsRoot: item.allowedAsRoot,
		variesByCulture: item.variesByCulture,
		variesBySegment: item.variesBySegment,
		isElement: item.isElement,
		properties: item.properties,
		containers: item.containers,
		allowedContentTypes: item.allowedContentTypes,
		compositions: item.compositions,
		id: item.id,
		allowedTemplateIds: item.allowedTemplateIds,
		defaultTemplateId: item.defaultTemplateId,
		cleanup: item.cleanup,
	};
};

export const umbDocumentData = new UmbDocumentData();
