import React from "react";
import { addAttachments, createCard, getBoardOwners, getBoards, getBoardStructure } from "../handlers/phpApiHandler";
import { GetBoardStructureResponse } from "../types/phpMiddlewareTypes/phpReturnTypes";
import { GenericSelect } from "./selects/genericSelect";
import { BsmapFormProps, TargetData, TargetMode } from "../types/addInTypes";
import { getTargetData, getTargetMode, setTargetData } from "../utils/localStorageUtils";
import { showUIMessage } from "../utils/outlookUtils";
import { ActionButton } from "./actionButton";


export const BsmapForm: React.FC<BsmapFormProps> = (props) => {
	const [boardId, setBoardId] = React.useState(0);
	const [workflowId, setWorkflowId] = React.useState(0);
	const [columnId, setColumnId] = React.useState(0);
	const [laneId, setLaneId] = React.useState(0);
	const [ownerId, setOwnerId] = React.useState(0);
	const [priorityId, setPriorityId] = React.useState(3); // Default average

	const [boardStructure, setBoardStructure] = React.useState<GetBoardStructureResponse["data"]>()

	const [boardOptions, setBoardOptions] = React.useState<HTMLOptionElement[]>();
	const [workflowOptions, setWorkflowOptions] = React.useState<HTMLOptionElement[]>();
	const [columnOptions, setColumnOptions] = React.useState<HTMLOptionElement[]>();
	const [laneOptions, setLaneOptions] = React.useState<HTMLOptionElement[]>();
	const [ownerOptions, setOwnerOptions] = React.useState<HTMLOptionElement[]>();
	const [priorityOptions, setPriorityOptions] = React.useState<HTMLOptionElement[]>();
	
	let initialValues:TargetData|null = null;
	try {
		initialValues = getTargetData('default'); // The form defaults to the default data
	} catch (e) {
		// Do nothing. Just means that we still have not set the default.
	}

	// Aparently the only way to use async/await in a react component is by using
	// the useEffect functionality.
	React.useEffect(() => {
		// Self-calling function (Equivalent to creating a function and calling it)
		(async() => {
			const boards = await getBoards();
			// So that the first board is selected by default.
			if (initialValues){
				setBoardId(initialValues.board_id);
			} else {
				setBoardId(boards[0].board_id);
			}
			

			// localStorage.setItem('boards', JSON.stringify(boards));
			const options:HTMLOptionElement[] = []
			for (const board of boards) {
				const option = new Option();
				option.text = board.name;
				option.value = board.board_id.toString();

				options.push(option);
			}
			setBoardOptions(options);

			
			if (initialValues){
				setPriorityId(initialValues.priority_id);
			} // No need for else since in the useState() we set 3 (average) as a default.

			const priorityOptions:HTMLOptionElement[] = [
				new Option('Critical', '1'),
				new Option('High', '2'),
				new Option('Average', '3'),
				new Option('Low', '5')
			];
			setPriorityOptions(priorityOptions);
		})();
	}, []);

	// When boardId changes reload workflows and owners
	React.useEffect(() => {
		(async() => {
			const boardStructure = await getBoardStructure(boardId);

			//Update boardStructure.
			setBoardStructure(boardStructure);

			// Set selected options.
			if (initialValues && boardId == initialValues.board_id) {
				setWorkflowId(initialValues.workflow_id);
				setOwnerId(initialValues.owner_id);
			} else {
				setWorkflowId(boardStructure[0].workflow_id);
				setOwnerId(0);
			}
			
			const options:HTMLOptionElement[] = [];
			for (const workflow of boardStructure) {
				const option = new Option();
				option.text = workflow.name;
				option.value = workflow.workflow_id.toString();

				options.push(option);
			}
			setWorkflowOptions(options);

			const owners = await getBoardOwners(boardId);
			const defaultOption = new Option('No user assigned.', '0')
			
			const ownerOptions:HTMLOptionElement[] = [
				defaultOption
			];
			for (const user of owners) {
				const option = new Option();
				option.text = user.username;
				option.value = user.user_id.toString();

				ownerOptions.push(option);
			}
			setOwnerOptions(ownerOptions);
		})();
	}, [boardId]);

	// When workflowId changes reload columns and lanes
	React.useEffect(() => {
		(async () => {
			const workflow = boardStructure.filter(x => x.workflow_id == workflowId)[0];

			const columnOptions:HTMLOptionElement[] = [];
			
			// Set selections
			if (initialValues && workflowId == initialValues.workflow_id){
				setColumnId(initialValues.column_id);
				setLaneId(initialValues.lane_id);
			} else {
				setColumnId(workflow.columns[0].column_id);
				setLaneId(workflow.lanes[0].lane_id);
			}
			
			for (const column of workflow.columns) {
				const option = new Option();
				option.text = column.name;
				option.value = column.column_id.toString();

				columnOptions.push(option);
			}
			setColumnOptions(columnOptions);

			const laneOptions:HTMLOptionElement[] = [];

			for (const lane of workflow.lanes) {
				const option = new Option();
				option.text = lane.name;
				option.value = lane.lane_id.toString();

				laneOptions.push(option);
			}
			setLaneOptions(laneOptions);
		})()
	}, [workflowId]);

	const submitForm = async () => {
		const targetData:TargetData = {
			board_id: boardId,
			workflow_id: workflowId,
			column_id: columnId,
			lane_id: laneId,
			priority_id: priorityId,
			owner_id: ownerId == 0 ? null : ownerId
		}
		switch(props.submitType) {
			case "setDefault":
				const targetMode: TargetMode = getTargetMode();
				setTargetData(targetMode, targetData);
				showUIMessage('Data successfully saved onto localStorage().');
				break;
			case "createCard":
				const createdCardId = await createCard(targetData);
				const mailAttachments = Office.context.mailbox.item.attachments;
				for (const attachment of mailAttachments){
					attachment.id = attachment.id.replace(/\//g, "-").replace(/\+/g, "_");
				}
				await addAttachments(createdCardId, mailAttachments);
				showUIMessage(`Card with id (${createdCardId}) successfully created on Businessmap.`);
				break;
		}
	};

	return (
		<div id="bsmapForm">
			<div id="set" className="mainContainer">
				<div id="boardSettingsContainer">
					<h2 className="headerTitle">Board Settings</h2>
					{boardOptions && <GenericSelect name="Board" value={boardId} items={boardOptions} onChange={e => setBoardId(Number(e.value))} /> }
					{workflowOptions && <GenericSelect name="Workflow" value={workflowId} items={workflowOptions} onChange={e => setWorkflowId(Number(e.value))} /> }
					{columnOptions && <GenericSelect name="Column" value={columnId} items={columnOptions} onChange={e => setColumnId(Number(e.value))}/> }
					{laneOptions && <GenericSelect name="Lane" value={laneId} items={laneOptions} onChange={e => setLaneId(Number(e.value))} /> }
					{ownerOptions && <GenericSelect name="Owner" value={ownerId} items={ownerOptions} onChange={e => setOwnerId(Number(e.value))} /> }
					{priorityOptions && <GenericSelect name="Priority" value={priorityId} items={priorityOptions} onChange={e => setPriorityId(Number(e.value))} /> }
					{props.submitType == "setDefault" && 
						<div className="messageBar">
							<div className="messageBar-content">
								<div className="messageBar-icon">
									<i>
										<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
											className="bi bi-info-circle" viewBox="0 0 16 16">
											<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
											<path
												d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
										</svg>
									</i>
								</div>
								<div id="boardBannerText" className="messageBar-text">
									Select board, workflow, column and lane where cards will be created by default. Optionally, you
									can also specify a default owner.
								</div>
							</div>
						</div>
					}
					{/* Only works if all options are loaded. */}
					<ActionButton
					type="button" 
					id="submit" 
					className="btnSave" 
					disabled={!boardOptions || !workflowOptions || !columnOptions || !laneOptions || !ownerOptions || !priorityOptions}
					onClick={submitForm}>
						Save
					</ActionButton>
					<div id="messageBox" className="messageBar mbEmpty">
						<div className="messageBar-content">
							<div id="message" className="messageBar-text">
								&nbsp;
							</div>
						</div>
					</div>
					<div>&nbsp;</div>
				</div>
			</div>
		</div>
	);
}