import useUsers from "@/hooks/useUsers";
import {Ticket, TicketStatus, TicketStatusLabel, TicketType, TicketTypeLabel} from "@/interfaces/ticket";
import {User} from "@/interfaces/user";
import {USER_TYPE_LABELS} from "@/resources/user";
import axios from "axios";
import moment from "moment";
import {useState} from "react";
import {toast} from "react-toastify";
import ShortUniqueId from "short-unique-id";
import Button from "../Low/Button";
import Input from "../Low/Input";
import Select from "../Low/Select";
import {checkAccess} from "@/utils/permissions";

interface Props {
	user: User;
	ticket: Ticket;
	onClose: () => void;
}

export default function TicketDisplay({user, ticket, onClose}: Props) {
	const [subject] = useState(ticket.subject);
	const [type, setType] = useState<TicketType>(ticket.type);
	const [description] = useState(ticket.description);
	const [reporter] = useState(ticket.reporter);
	const [reportedFrom] = useState(ticket.reportedFrom);
	const [status, setStatus] = useState(ticket.status);
	const [assignedTo, setAssignedTo] = useState<string | null>(ticket.assignedTo || null);
	const [isLoading, setIsLoading] = useState(false);

	const {users} = useUsers();

	const submit = () => {
		if (!type) return toast.error("Please choose a type!", {toastId: "missing-type"});

		setIsLoading(true);
		axios
			.patch(`/api/tickets/${ticket.id}`, {
				subject,
				type,
				description,
				reporter,
				reportedFrom,
				status,
				assignedTo,
			})
			.then(() => {
				toast.success(`The ticket has been updated!`, {toastId: "submitted"});
				onClose();
			})
			.catch((e) => {
				console.error(e);
				toast.error("Something went wrong, please try again later!", {
					toastId: "error",
				});
			})
			.finally(() => setIsLoading(false));
	};

	const del = () => {
		if (!confirm("Are you sure you want to delete this ticket?")) return;

		setIsLoading(true);
		axios
			.delete(`/api/tickets/${ticket.id}`)
			.then(() => {
				toast.success(`The ticket has been deleted!`, {toastId: "submitted"});
				onClose();
			})
			.catch((e) => {
				console.error(e);
				toast.error("Something went wrong, please try again later!", {
					toastId: "error",
				});
			})
			.finally(() => setIsLoading(false));
	};

	return (
		<form className="flex flex-col gap-4 pt-8">
			<Input label="Subject" type="text" name="subject" placeholder="Subject..." value={subject} onChange={(e) => null} disabled />

			<div className="-md:flex-col flex w-full items-center gap-4">
				<div className="flex w-full flex-col gap-3">
					<label className="text-mti-gray-dim text-base font-normal">Status</label>
					<Select
						options={Object.keys(TicketStatusLabel).map((x) => ({
							value: x,
							label: TicketStatusLabel[x as keyof typeof TicketStatusLabel],
						}))}
						value={{value: status, label: TicketStatusLabel[status]}}
						onChange={(value) => setStatus((value?.value as TicketStatus) ?? undefined)}
						placeholder="Status..."
					/>
				</div>
				<div className="flex w-full flex-col gap-3">
					<label className="text-mti-gray-dim text-base font-normal">Type</label>
					<Select
						options={Object.keys(TicketTypeLabel).map((x) => ({
							value: x,
							label: TicketTypeLabel[x as keyof typeof TicketTypeLabel],
						}))}
						value={{value: type, label: TicketTypeLabel[type]}}
						onChange={(value) => setType(value!.value as TicketType)}
						placeholder="Type..."
					/>
				</div>
			</div>

			<div className="flex w-full flex-col gap-3">
				<label className="text-mti-gray-dim text-base font-normal">Assignee</label>
				<Select
					options={[
						{value: "me", label: "Assign to me"},
						...users
							.filter((x) => checkAccess(x, ["admin", "developer", "agent"]))
							.map((u) => ({
								value: u.id,
								label: `${u.name} - ${u.email}`,
							})),
					]}
					disabled={checkAccess(user, ["agent"])}
					value={
						assignedTo
							? {
									value: assignedTo,
									label: `${users.find((u) => u.id === assignedTo)?.name} - ${users.find((u) => u.id === assignedTo)?.email}`,
							  }
							: null
					}
					onChange={(value) => (value ? setAssignedTo(value.value === "me" ? user.id : value.value) : setAssignedTo(null))}
					placeholder="Assignee..."
					isClearable
				/>
			</div>

			<div className="-md:flex-col flex w-full items-center gap-4">
				<Input label="Reported From" type="text" name="reportedFrom" onChange={() => null} value={reportedFrom} disabled />
				<Input label="Date" type="text" name="date" onChange={() => null} value={moment(ticket.date).format("DD/MM/YYYY - HH:mm")} disabled />
			</div>

			<div className="-md:flex-col flex w-full items-center gap-4">
				<Input label="Reporter's Name" type="text" name="reporter" onChange={() => null} value={reporter.name} disabled />
				<Input label="Reporter's E-mail" type="text" name="reporter" onChange={() => null} value={reporter.email} disabled />
				<Input
					label="Reporter's Type"
					type="text"
					name="reporterType"
					onChange={() => null}
					value={USER_TYPE_LABELS[reporter.type]}
					disabled
				/>
			</div>

			<textarea
				className="input border-mti-gray-platinum h-full min-h-[300px] w-full cursor-text rounded-3xl border bg-white px-7 py-8"
				placeholder="Write your ticket's description here..."
				contentEditable={false}
				value={description}
				spellCheck
			/>

			<div className="-md:flex-col-reverse mt-2 flex w-full items-center justify-between gap-4">
				<Button type="button" color="red" className="w-full md:max-w-[200px]" variant="outline" onClick={del} isLoading={isLoading}>
					Delete
				</Button>

				<div className="-md:flex-col-reverse flex w-full items-center justify-end gap-4">
					<Button type="button" color="red" className="w-full md:max-w-[200px]" variant="outline" onClick={onClose} isLoading={isLoading}>
						Cancel
					</Button>
					<Button type="button" className="w-full md:max-w-[200px]" isLoading={isLoading} onClick={submit}>
						Update
					</Button>
				</div>
			</div>
		</form>
	);
}
