<script setup lang="ts">
	import draggable from "vuedraggable";
	import { v4 } from "uuid";
	import lmove from "lodash-move";
	import { Field, FieldArray, useForm, useFieldArray } from "vee-validate";
	import { ASpin } from "#components";
	import { storySchema } from "@client/storyFormSchema";
	import { FormStory, defaultChapter, FormChapter } from "@client/types/form/story";
	import { autoEdit, autoSave, debouncedAutoEdit, debouncedAutoSave } from "@client/utils";

	import findUser from "~/components/findUser.vue";

	import singleChapter from "./singleChapter.vue";
	import icon from "~/components/icon.vue";

	const router = useRouter();

	const props = defineProps<{
		canDraft?: boolean;
		endpoint: string;
		endpointMethod: "put" | "post";
		submitText?: string;
		draftData?: {
			endpoint: string;
			endpointMethod: "put" | "post";
		};
	}>();
	const dc = defaultChapter;
	const sdata = defineModel<FormStory>("data", {
		required: true,
	});
	let drag: boolean = false;
	const expandos = ref<string[]>([]);

	function logSubmit(values, actions) {
		console.debug("VALUE");
		console.debug(values);
		console.debug(actions);
	}
	const otherBtnInvoked = ref<boolean>(false);
	async function onSubmit(values, actions) {
		logSubmit(values, actions);
		if (props.canDraft) {
			if (otherBtnInvoked.value) {
				otherBtnInvoked.value = false;
				await autoSave(values);
			} else {
				const { data: dat } = await useApiFetch<any>(`/story/new`, {
					method: "post",
					body: values,
				});
				if (dat.value.success) {
					await router.push(`/story/${dat.value.story._id}/1`);
				}
			}
		} else {
			await autoEdit(values, props.endpoint, props.endpointMethod);
		}
	}

	const { values, setFieldValue, handleSubmit } = useForm<FormStory>({
		keepValuesOnUnmount: true,
		validationSchema: storySchema,
		initialValues: sdata.value,
	});
	function renumber(update: (idx: number, value: FormChapter) => void) {
		for (let i = 0; i < values.chapters.length; i++) {
			const nv = values.chapters[i];
			nv.index = i + 1;
			update(i, nv);
			sdata.value.chapters[i].index = i + 1;
		}
	}
	const subCb = handleSubmit(onSubmit);

	const pushHOF = (push) => (e) => {
		if (!Array.isArray(values.chapters)) {
			// noinspection TypeScriptValidateTypes
			setFieldValue("chapters", []);
		}
		const chaps = [...toRaw(values.chapters)];
		let lastIndex = chaps.length - 1;
		if (lastIndex < 0) lastIndex = 0;
		let lastChapter = chaps[lastIndex];
		// log.debug('chaptrs->', chaps);
		// log.debug('lastIndex->', lastIndex, lastChapter);
		let newChapter = Object.assign({}, defaultChapter, {
			summary: lastChapter?.summary || "",
			index: (lastChapter?.index || 0) + 1,
			bands: lastChapter?.bands || [],
			characters: lastChapter?.characters || [],
			relationships: lastChapter?.relationships || [],
			uuidKey: v4(),
			genre: lastChapter?.genre || [],
		});
		// console.debug("nc->", newChapter);
		// console.debug("pushi -> ", push);
		push(newChapter);
		sdata.value.chapters.push(newChapter);
	};
</script>
<template>
	<form
		data-testid="storyform"
		@submit="subCb"
		@change="
			() =>
				canDraft
					? draftData
						? debouncedAutoSave(values, draftData.endpoint, draftData.endpointMethod)
						: debouncedAutoSave(values)
					: debouncedAutoEdit(values, endpoint, endpointMethod)
		"
	>
		<!-- <a-form v-bind:model="acData"> -->

		<Field name="title" v-slot="{ value, field, errorMessage }">
			<a-form-item label="Title" :help="errorMessage" :validate-status="!!errorMessage ? 'error' : ''">
				<a-input :data-testid="`storyform.${field.name}`" v-bind="field" :value="value" />
			</a-form-item>
		</Field>
		<a-form-item label="Co-author (optional)">
			<find-user data-testid="storyform.coauthor" :initial-option="sdata.coAuthor" fieldName="coAuthor" :multi="false" />
		</a-form-item>
		<Field :unchecked-value="false" :value="true" type="checkbox" name="completed" v-slot="{ value, field, errorMessage }">
			<a-checkbox :data-testid="`storyform.${field.name}`" v-bind="field"> Complete </a-checkbox>
		</Field>
		<a-divider />
		<!-- <test1/> -->
		<field-array name="chapters" v-slot="{ fields, push, remove, move, update }">
			<client-only :fallback="h(ASpin)">
				<div>
					<div v-for="(element, index) in values.chapters">
						<client-only>
							<Teleport :to="`#chapter-\\[${element.uuidKey}\\]`">
								<a-collapse v-model:active-key="expandos" collapsible="icon">
									<template #expandIcon="{ isActive }">
										<span :data-testid="`storyform.chapters[${index}].collapse`"> <RightOutlined :rotate="isActive ? 90 : undefined" /></span>
									</template>
									<a-collapse-panel :key="`${element.uuidKey}`" :data-testid="`storyform.chapters[${index}].outer`">
										<template #header>
											<div :data-testid="`storyform.chapters[${index}].header`" style="display: flex; align-items: center; justify-content: space-between">
												<span :data-testid="`storyform.chapters[${index}].titleEl`">{{ values.chapters[index]?.chapterTitle || "Untitled" }}</span>
												<a-button
													@click="
														(e) => {
															data.chapters.splice(index, 1);
															remove(index);
															renumber(update);
														}
													"
												>
													<icon istyle="regular" name="trash" />
												</a-button>
											</div>
										</template>
										<single-chapter :data="element" :name="`chapters[${index}]`" />
									</a-collapse-panel>
								</a-collapse>
							</Teleport>
						</client-only>
					</div>
				</div>
			</client-only>
			<client-only>
				<template #fallback>
					<div style="display: flex; justify-content: center">
						<a-spin />
					</div>
				</template>
				<draggable
					:component-data="{ type: 'transtion-group', 'data-testid': 'storyform.chapters' }"
					@start="drag = true"
					@end="drag = false"
					v-model="values.chapters"
					tag="div"
					data-testid="storyform.chapters"
					item-key="uuidKey"
					@change="
						(e) => {
							console.log(e);
							if (e.moved) {
								console.debug(e.moved);
								move(e.moved.oldIndex, e.moved.newIndex);
								data.chapters = lmove(data.chapters, e.moved.oldIndex, e.moved.newIndex);
								renumber(update);
								// w.tinymce.remove();
								// log.debug(toRaw(acData.chapters.map((a) => toRaw(a))));
							}
						}
					"
				>
					<template #item="{ element, index }">
						<div :id="`chapter-[${element.uuidKey}]`"></div>
					</template>
					<template #footer>
						<a-button data-testid="storyform.addChapter" :onClick="pushHOF(push)"> Add chapter </a-button>
					</template>
				</draggable>
			</client-only>
		</field-array>
		<a-button type="primary" html-type="submit">{{ submitText || "Post" }}</a-button>
		<a-button html-type="submit" v-if="canDraft" @click="() => (otherBtnInvoked = true)"> Save for Later </a-button>
	</form>
</template>
<style>
	.ant-collapse-item > .ant-collapse-header {
		align-items: center !important;
	}
	.ant-collapse-header.ant-collapse-icon-collapsible-only {
		align-items: center !important;
	}
</style>
