import { GetPostsAttributes } from "@/app/lib/actions/entityManagement/post/postActions";
import { Post, Project, Bucket, PostBucket, Attachment } from "@/models";
import { Attributes } from "@sequelize/core";
import { UUID } from "crypto";
import { EntityEditorTextArea } from '../input/EntityEditorTextArea';
import {
	ChangeEventHandler,
	MouseEventHandler,
	useState,
} from "react";
import {
	Accordion,
	AccordionBody,
	AccordionHeader,
	AccordionItem,
} from "react-bootstrap";

export type PostTableCallbacks = {
	savePost: (p: Partial<Attributes<Post>>) => void;
    refetch: () => any;
	closeEditor: () => any;
	uploadAttachment: () => any;
};

export type EditorState = {
	isEditorOpen: boolean;
	editorPost: GetPostsAttributes;
};

export type EditorProps = {
	editorPost: GetPostsAttributes;
	projectList: {
		id: number;
		readableIdentifier: string;
	}[];
	callbacks: PostTableCallbacks;
};

export default function PostEditor({
	editorPost,
	projectList,
	callbacks,
}: EditorProps) {
	// Setup State Hooks
	let [postContentState, setPostContentState] = useState(editorPost.content);
	let [postTitleState, setPostTitleState] = useState(editorPost.title);
	let [postProjectIDState, setPostProjectIDState] = useState(
		editorPost.project.id
	);

	// Handle changing the selected project using the dropdown select
	const projectSelectionChange: ChangeEventHandler<HTMLSelectElement> = (e) =>
		setPostProjectIDState(parseInt(e.target.value));
	// Handle clicking the save button
	const onClickSaveButton: MouseEventHandler<HTMLButtonElement> = (e) => {
		callbacks?.savePost({
			id: editorPost?.id as number,
			content: postContentState as string,
			title: postTitleState as string,
			project_id: postProjectIDState,
		});
	};
	const onClickCancelButton: MouseEventHandler<HTMLButtonElement> = (e) => {
		callbacks?.closeEditor();
	};

	return (
		<>
			<form className="bg-light w-[100%] h-content p-1">
				<h1 key="heading-editpost" className="m-2">
					Edit Post
				</h1>
				<h2 key="label-title" className="m-2">
					Title
				</h2>
				<input
					key="input-title"
					value={postTitleState}
					onChange={(e) => setPostTitleState(e.target.value)}
					type="text"
					className="m-2"
				/>
				<h2 key="label-content" className="m-2">
					Content
				</h2>
				<EntityEditorTextArea 
                    contentHook={{
                    state: postContentState,
                    setState: setPostContentState
                    }}
                    className={ "w-[100%] min-h-auto h-content align-top text-start text-base line-clamp-6 m-2" }
                    >
                </EntityEditorTextArea>
				<h2 key="label-project" className="m-2">
					Project
				</h2>
				<select
					key="input-project"
					onChange={projectSelectionChange}
					name="projects"
					id="projects"
					defaultValue={editorPost?.project?.id}
					placeholder={editorPost?.project?.name}
					value={postProjectIDState}
					className="m-2"
				>
					<option key="projectSelectionOpt-0" value={0}>
						unassigned
					</option>
					{projectList?.map((p) => (
						<option
							key={`projectSelectionOpt-${p.id}`}
							value={p.id}
						>
							{p.readableIdentifier}
						</option>
					))}
				</select>
				<h2 key="label-attachments">Attachments</h2>
				<table key="table-buckets" className="table table-striped">
					<thead>
						<tr>
							<td>Buckets</td>
						</tr>
					</thead>
					<tbody>
						{editorPost?.buckets ? (
							(() => {
								let bucketMap: Map<
									UUID,
									Attributes<Bucket>
								> = new Map(
									editorPost.buckets.map((b) => [
										b.id as UUID,
										b,
									])
								);
								let bucketList = [
									...editorPost.buckets.map((b) => b.id),
								];
								return bucketList.map((e) => {
									return (
										<>
											<tr
												key={`bucketAccordionRow-${bucketList
													.indexOf(e)
													.toString()}`}
											>
												<Accordion>
													<AccordionItem
														eventKey={bucketList
															.indexOf(e)
															.toString()}
													>
														<AccordionHeader>
															{e}
														</AccordionHeader>
														<AccordionBody>
															<ul>
																<li>
																	<input
																		type="file"
																		className="btn btn-success"
																		onChange={(
																			e
																		) => {
																			for (
																				let index = 0;
																				index <
																				((
																					e
																						.target
																						.files as FileList
																				)
																					.length as number);
																				index++
																			) {
																				const element =
																					(
																						e
																							.target
																							.files as FileList
																					)[
																						index
																					];
																				const fReader =
																					new FileReader();
																				fReader.readAsDataURL(
																					element
																				);
																				fReader.onloadend =
																					(
																						event
																					) => {
																						console.log(
																							event
																								.target
																								?.result
																						);
																					};
																			}
																		}}
																	/>
																</li>
																{(() => {
																	const bucket =
																		bucketMap.get(
																			e as UUID
																		);
																	return bucket &&
																		bucket.attachments ? (
																		bucket.attachments.map(
																			(
																				attachment
																			) => (
																				<li
																					key={`listItem-file-${attachment.filename}`}
																				>
																					{
																						attachment.filename
																					}
																				</li>
																			)
																		)
																	) : (
																		<></>
																	);
																})()}
															</ul>
														</AccordionBody>
													</AccordionItem>
												</Accordion>
											</tr>
										</>
									);
								});
							})()
						) : (
							<></>
						)}
					</tbody>
				</table>
				<button type="button" className="m-2 btn btn-primary">
					Preview
				</button>
				<button
					type="button"
					className="m-2 btn btn-success"
					onClick={onClickSaveButton}
				>
					Save
				</button>
				<button
					type="button"
					className="m-2 btn btn-danger"
					onClick={onClickCancelButton}
				>
					Cancel
				</button>
			</form>
		</>
	);
}

type EditorRendererProps = {
	editorPost: GetPostsAttributes;
	headings: string[];
	editorState: EditorState;
	editorControls: any;
	callbacks: any;
	projects: any;
};

export function EditorRenderer({
	editorPost,
	headings,
	editorState,
	callbacks,
	projects,
}: EditorRendererProps) {
	return editorState.isEditorOpen &&
		editorState.editorPost &&
		editorState.editorPost.id == editorPost.id ? (
		<tr>
			<th scope="row" colSpan={headings.length}>
				<PostEditor
					callbacks={callbacks}
					editorPost={editorState.editorPost}
					projectList={projects}
				/>
			</th>
		</tr>
	) : (
		""
	);
}
