import RequestedBy from "@/components/ApprovalWorkflows/RequestedBy";
import StartedOn from "@/components/ApprovalWorkflows/StartedOn";
import Status from "@/components/ApprovalWorkflows/Status";
import Tip from "@/components/ApprovalWorkflows/Tip";
import UserWithProfilePic from "@/components/ApprovalWorkflows/UserWithProfilePic";
import WorkflowStepComponent from "@/components/ApprovalWorkflows/WorkflowStepComponent";
import Layout from "@/components/High/Layout";
import { ApprovalWorkflow, getUserTypeLabelShort, WorkflowStep } from "@/interfaces/approval.workflow";
import { User } from "@/interfaces/user";
import { sessionOptions } from "@/lib/session";
import { redirect, serialize } from "@/utils";
import { requestUser } from "@/utils/api";
import { getApprovalWorkflow } from "@/utils/approval.workflows.be";
import { shouldRedirectHome } from "@/utils/navigation.disabled";
import { getSpecificUsers, getUser } from "@/utils/users.be";
import { AnimatePresence, LayoutGroup, motion } from "framer-motion";
import { withIronSessionSsr } from "iron-session/next";
import Head from "next/head";
import Link from "next/link";
import { useState } from "react";
import { BsChevronLeft } from "react-icons/bs";
import { FaWpforms } from "react-icons/fa6";
import { MdOutlineDoubleArrow } from "react-icons/md";
import { RiThumbUpLine } from "react-icons/ri";
import { ToastContainer } from "react-toastify";

export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
    const user = await requestUser(req, res);
    if (!user) return redirect("/login")

    if (shouldRedirectHome(user) || !["admin", "developer", "teacher", "corporate", "mastercorporate"].includes(user.type))
        return redirect("/")

    const { id } = params as { id: string };

    const workflow: ApprovalWorkflow | null = await getApprovalWorkflow(id);

    if (!workflow)
        return redirect("/approval-workflows")

    const allAssigneeIds: string[] = [
        ...new Set(
            workflow.steps
                .map(step => step.assignees)
                .flat()
        )
    ];

    return {
        props: serialize({
            user,
            workflow,
            workflowAssignees: await getSpecificUsers(allAssigneeIds),
            workflowRequester: await getUser(workflow.requester),
        }),
    };
}, sessionOptions);

interface Props {
    user: User,
    workflow: ApprovalWorkflow,
    workflowAssignees: User[],
    workflowRequester: User,
}

export default function Home({ user, workflow, workflowAssignees, workflowRequester }: Props) {
    const steps = workflow.steps;

    let currentStep = steps.findIndex(step => !step.completed);
    if (currentStep === -1)
        currentStep = steps.length - 1;

    const [selectedStepIndex, setSelectedStepIndex] = useState<number>(currentStep);
    const [selectedStep, setSelectedStep] = useState<WorkflowStep>(steps[selectedStepIndex]);
    const [isPanelOpen, setIsPanelOpen] = useState(true);
    const [comments, setComments] = useState<string>(selectedStep.comments || "");

    const handleStepClick = (index: number, stepInfo: WorkflowStep) => {
        setSelectedStep(stepInfo);
        setSelectedStepIndex(index);
        setComments(stepInfo.comments || "");
        setIsPanelOpen(true);
    };

    const saveComments = () => {

    };

    return (
        <>
            <Head>
                <title> {workflow.name} | EnCoach</title>
                <meta
                    name="description"
                    content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
                />
                <meta name="viewport" content="width=device-width, initial-scale=1" />
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <ToastContainer />
            {user && (
                <Layout user={user} className="gap-6">

                    <section className="flex items-center gap-2">
                        <Link
                            href="/approval-workflows"
                            className="text-mti-purple hover:text-mti-purple-dark transition ease-in-out duration-300 text-xl">
                            <BsChevronLeft />
                        </Link>
                        <h1 className="text-2xl font-semibold">{workflow.name}</h1>
                    </section>

                    <section className="flex flex-col gap-6">
                        <div className="flex flex-row gap-6">
                            <RequestedBy
                                prefix={getUserTypeLabelShort(workflowRequester.type)}
                                name={workflowRequester.name}
                                profileImage="/blue-stock-photo.png" //{workflowRequester.profilePicture}
                            />
                            <StartedOn
                                date={workflow.startDate}
                            />
                            <Status
                                status={workflow.status}
                            />
                        </div>
                        {steps.find((step) => !step.completed) === undefined &&
                            <Tip text="All steps in this instance have been completed." />
                        }
                    </section>

                    <section className="flex flex-col gap-0">
                        {steps.map((step, index) => (
                            <WorkflowStepComponent
                                workflowAssignees={workflowAssignees}
                                key={index}
                                completed={step.completed}
                                completedBy={step.completedBy}
                                stepNumber={step.stepNumber}
                                stepType={step.stepType}
                                assignees={step.assignees}
                                finalStep={index === steps.length - 1}
                                currentStep={index === currentStep}
                                selected={index === selectedStepIndex}
                                onClick={() => handleStepClick(index, step)}
                            />
                        ))}
                    </section>

                    {/* Side panel */}
                    <AnimatePresence mode="wait">
                        <LayoutGroup key="sidePanel">
                            <section className={`absolute inset-y-0 right-0 h-full bg-mti-purple-ultralight bg-opacity-50 shadow-xl shadow-mti-purple transition-all duration-300 overflow-hidden ${isPanelOpen ? 'w-2/5' : 'w-0'}`}>
                                {isPanelOpen && selectedStep && (
                                    <motion.div
                                        className="p-6"
                                        key={selectedStep.stepNumber}
                                        initial={{ opacity: 0, x: 30 }}
                                        animate={{ opacity: 1, x: 0 }}
                                        exit={{ opacity: 0, x: 30 }}
                                        transition={{ duration: 0.2 }}
                                    >
                                        <div className="flex flex-row gap-2">
                                            <p className="text-2xl font-medium text-left align-middle">Step {selectedStepIndex + 1}</p>
                                            <div className="ml-auto flex flex-row">
                                                <button
                                                    className="min-w-fit max-h-fit text-lg font-medium flex items-center gap-2 text-left"
                                                    onClick={() => setIsPanelOpen(false)}
                                                >
                                                    Collapse
                                                    <MdOutlineDoubleArrow size={20} />
                                                </button>
                                            </div>
                                        </div>

                                        <hr className="my-4 h-[4px] bg-mti-purple-ultralight rounded-full w-full" />

                                        <div>
                                            <div className="my-8 flex flex-row gap-4 items-center text-lg font-medium">
                                                {selectedStep.stepType === "approval-by" ? (
                                                    <>
                                                        <RiThumbUpLine size={30} />
                                                        Approval Step
                                                    </>
                                                ) : (
                                                    <>
                                                        <FaWpforms size={30} />
                                                        Form Intake Step
                                                    </>
                                                )
                                                }
                                            </div>

                                            {selectedStep.completed ? (
                                                <div className={"text-base font-medium text-gray-500 flex flex-col gap-6"}>
                                                    Approved on {new Date(selectedStep.completedDate!).toLocaleString("en-CA", {
                                                        year: "numeric",
                                                        month: "2-digit",
                                                        day: "2-digit",
                                                        hour: "2-digit",
                                                        minute: "2-digit",
                                                        second: "2-digit",
                                                        hour12: false,
                                                    }).replace(", ", " at ")}
                                                    <div className="flex flex-row gap-1 text-sm">
                                                        <p className="text-base">Approved by:</p>
                                                        {(() => {
                                                            const assignee = workflowAssignees.find(
                                                                (assignee) => assignee.id === selectedStep.completedBy
                                                            );
                                                            return assignee ? (
                                                                <UserWithProfilePic
                                                                    textSize="text-base"
                                                                    prefix={getUserTypeLabelShort(assignee.type)}
                                                                    name={assignee.name}
                                                                    profileImage={assignee.profilePicture}
                                                                />
                                                            ) : (
                                                                "Unknown"
                                                            );
                                                        })()}
                                                    </div>
                                                    <p className="text-sm">No additional actions are required.</p>
                                                </div>

                                            ) : (
                                                <div className={"text-base font-medium text-gray-500"}>
                                                    One assignee is required to sign off to complete this step:
                                                    <div className="flex flex-col gap-2 mt-3">
                                                        {workflowAssignees.filter(user => selectedStep.assignees.includes(user.id)).map(user => (
                                                            <span key={user.id}>
                                                                <UserWithProfilePic
                                                                    textSize="text-sm"
                                                                    prefix={`- ${getUserTypeLabelShort(user.type)}`}
                                                                    name={user.name}
                                                                    profileImage={user.profilePicture}
                                                                />
                                                            </span>
                                                        ))}
                                                    </div>
                                                </div>
                                            )}

                                            <hr className="my-4 h-[4px] bg-mti-purple-ultralight rounded-full w-full" />

                                            <textarea
                                                value={comments}
                                                onChange={(e) => setComments(e.target.value)}
                                                placeholder="Input comments here"
                                                className="w-full h-80 p-2 border-2 rounded-xl shadow-lg focus:border-mti-purple focus:outline-none mt-4"
                                            />
                                            <button onClick={saveComments} className="mt-4 px-6 py-2 bg-mti-purple-dark text-white rounded-full">
                                                Save Comments
                                            </button>

                                        </div>
                                    </motion.div>
                                )}
                            </section>
                        </LayoutGroup>
                    </AnimatePresence>
                </Layout>
            )}
        </>
    );
}
