import Layout from "@/components/High/Layout";
import Button from "@/components/Low/Button";
import Select from "@/components/Low/Select";
import useApprovalWorkflows from "@/hooks/useApprovalWorkflows";
import { Module, ModuleTypeLabels } from "@/interfaces";
import { ApprovalWorkflow, ApprovalWorkflowStatus, ApprovalWorkflowStatusLabel, StepTypeLabel } from "@/interfaces/approval.workflow";
import { Entity, EntityWithRoles } from "@/interfaces/entity";
import { TeacherUser, User } from "@/interfaces/user";
import { sessionOptions } from "@/lib/session";
import { redirect, serialize } from "@/utils";
import { requestUser } from "@/utils/api";
import { getEntities } from "@/utils/entities.be";
import { shouldRedirectHome } from "@/utils/navigation.disabled";
import { getUsers } from "@/utils/users.be";
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import axios from "axios";
import clsx from "clsx";
import { withIronSessionSsr } from "iron-session/next";
import Head from "next/head";
import Link from "next/link";
import { useEffect, useState } from "react";
import { BsTrash } from "react-icons/bs";
import { FaRegEdit } from "react-icons/fa";
import { IoIosAddCircleOutline } from "react-icons/io";
import { toast, ToastContainer } from "react-toastify";

const columnHelper = createColumnHelper<ApprovalWorkflow>();

export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
    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 entityIDS = mapBy(user.entities, "id");
    const entities = await getEntitiesWithRoles(isAdmin(user) ? undefined : entityIDS);
    const allowedEntities = findAllowedEntities(user, entities, "view_approval_workflows"); */

    return {
        props: serialize({
            user,
            userEntitiesWithLabel: await getEntities(user.entities.map(entity => entity.id)),
        }),
    };
}, sessionOptions);

const StatusClassNames: { [key in ApprovalWorkflowStatus]: string } = {
    approved: "bg-green-100 text-green-800 border border-green-300 before:content-[''] before:w-2 before:h-2 before:bg-green-500 before:rounded-full before:inline-block before:mr-2",
    pending: "bg-orange-100 text-orange-800 border border-orange-300 before:content-[''] before:w-2 before:h-2 before:bg-orange-500 before:rounded-full before:inline-block before:mr-2",
    rejected: "bg-red-100 text-red-800 border border-red-300 before:content-[''] before:w-2 before:h-2 before:bg-red-500 before:rounded-full before:inline-block before:mr-2",
};

type CustomStatus = ApprovalWorkflowStatus | "all";
type CustomEntity = EntityWithRoles | "all";

const STATUS_OPTIONS = [
    {
        label: "All",
        value: "all",
        filter: (x: ApprovalWorkflow) => true,
    },
    {
        label: "Approved",
        value: "approved",
        filter: (x: ApprovalWorkflow) => x.status === "approved",
    },
    {
        label: "Pending",
        value: "pending",
        filter: (x: ApprovalWorkflow) => x.status === "pending",
    },
    {
        label: "Rejected",
        value: "rejected",
        filter: (x: ApprovalWorkflow) => x.status === "rejected",
    },
];

interface Props {
    user: User,
    teachers: TeacherUser[],
    userEntitiesWithLabel: Entity[],
}

export default function ApprovalWorkflows({ user, teachers, userEntitiesWithLabel }: Props) {

    const ENTITY_OPTIONS = [
        {
            label: "All",
            value: "all",
            filter: (x: ApprovalWorkflow) =>
                userEntitiesWithLabel.some(entity => entity.id === x.entityId),
        },
        ...userEntitiesWithLabel
            .map(entity => ({
                label: entity.label,
                value: entity.id,
                filter: (x: ApprovalWorkflow) => x.entityId === entity.id,
            }))
            .sort((a, b) => a.label.localeCompare(b.label)),
    ];

    const [filteredApprovalWorkflows, setFilteredApprovalWorkflows] = useState<ApprovalWorkflow[]>([]);

    const [statusFilter, setStatusFilter] = useState<CustomStatus>("all");
    const [entityFilter, setEntityFilter] = useState<CustomEntity>("all");

    const { approvalWorkflows/* , reload */ } = useApprovalWorkflows();

    useEffect(() => {
        const filters = [];
        if (statusFilter) {
            const filter = STATUS_OPTIONS.find((x) => x.value === statusFilter)?.filter;
            if (filter) filters.push(filter);
        }
        if (entityFilter) {
            const filter = ENTITY_OPTIONS.find((x) => x.value === entityFilter)?.filter;
            if (filter) filters.push(filter);
        }

        setFilteredApprovalWorkflows([...filters.reduce((d, f) => d.filter(f), approvalWorkflows)]);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [approvalWorkflows, statusFilter, entityFilter]);

    const deleteApprovalWorkflow = (id: string, name: string) => {
        if (!confirm(`Are you sure you want to delete this Approval Workflow?`)) return;

        axios
            .delete(`/api/approval-workflows/${id}`)
            .then(() => toast.success(`Deleted ${name} Approval Workflow.`))
            .catch((reason) => {
                if (reason.response.status === 404) {
                    toast.error("Approval Workflow not found!");
                    return;
                }

                if (reason.response.status === 403) {
                    toast.error("You do not have permission to delete an Approval Workflow!");
                    return;
                }

                toast.error("Something went wrong, please try again later.");
            })
        /* .finally(reload); */
    };

    const editApprovalWorkflow = (id: string) => {

    };

    const columns = [
        /* columnHelper.accessor("id", {
            header: "ID",
            cell: (info) => info.getValue(),
        }), */
        columnHelper.accessor("name", {
            header: "NAME",
            cell: (info) => (
                <span className="font-medium">
                    {info.getValue()}
                </span>
            ),
        }),
        columnHelper.accessor("modules", {
            header: "MODULES",
            cell: (info) => (
                <div className="flex flex-wrap gap-2">
                    {info.getValue().map((module: Module, index: number) => (
                        <span
                            key={index}
                            className="inline-block rounded-full px-3 py-1 text-sm font-medium bg-indigo-100 border border-indigo-300 text-indigo-900"
                        >
                            {ModuleTypeLabels[module]}
                        </span>
                    ))}
                </div>
            ),
        }),
        columnHelper.accessor("status", {
            header: "STATUS",
            cell: (info) => (
                <span className={clsx("inline-block rounded-full px-3 py-1 text-sm font-medium text-left w-[110px]", StatusClassNames[info.getValue()])}>
                    {ApprovalWorkflowStatusLabel[info.getValue()]}
                </span>
            ),
        }),
        columnHelper.accessor("entityId", {
            header: "ENTITY",
            cell: (info) => (
                <span className="font-medium">
                    {userEntitiesWithLabel.find((entity) => entity.id === info.getValue())?.label}
                </span>
            ),
        }),
        columnHelper.accessor("steps", {
            id: "currentApprovers",
            header: "CURRENT APPROVERS",
            cell: (info) => {
                const steps = info.row.original.steps;
                const currentStep = steps.find((step) => !step.completed);
                const approvers = currentStep?.assignees || [];

                return (
                    <div className="flex flex-wrap gap-2">
                        {approvers.map((approver: string | null | undefined, index: number) => (
                            <span
                                key={index}
                                className="inline-block rounded-full px-3 py-1 text-sm font-medium bg-gray-100 border border-gray-300 text-gray-900"
                            >
                                {approver}
                            </span>
                        ))}
                    </div>
                );
            },
        }),
        columnHelper.accessor("steps", {
            id: "currentStep",
            header: "CURRENT STEP",
            cell: (info) => {
                const steps = info.row.original.steps;
                const currentStep = steps.find((step) => !step.completed);

                return (
                    <span className="font-medium">
                        {currentStep
                            ? `Step ${currentStep.stepNumber}: ${StepTypeLabel[currentStep.stepType!]}`
                            : "Completed"}
                    </span>
                );
            },
        }),
        {
            header: "ACTIONS",
            id: "actions",
            cell: ({ row }: { row: { original: ApprovalWorkflow } }) => {
                return (
                    <div className="flex gap-4">
                        <Link data-tip="Edit" href={`/approval-workflows/${row.original.id}`} className="cursor-pointer tooltip">
                            <FaRegEdit className="hover:text-mti-purple-light transition ease-in-out duration-300" />
                        </Link>
                        <button data-tip="Delete" className="cursor-pointer tooltip" onClick={() => deleteApprovalWorkflow(row.original.id, row.original.name)}>
                            <BsTrash className="hover:text-mti-purple-light transition ease-in-out duration-300" />
                        </button>
                    </div>
                );
            },
        },
    ];

    const table = useReactTable({
        data: filteredApprovalWorkflows,
        columns: columns,
        getCoreRowModel: getCoreRowModel(),
    });

    return (
        <>
            <Head>
                <title>Approval Workflows Panel | 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">
                    <h1 className="text-2xl font-semibold">Approval Workflows</h1>

                    <Link href={"/approval-workflows/create"}>
                        <Button
                            color="purple"
                            variant="solid"
                            className="max-w-fit text-lg font-medium flex items-center gap-2 text-left"
                        >
                            <IoIosAddCircleOutline className="size-6" />
                            Configure New Workflows
                        </Button>
                    </Link>

                    <div className="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={STATUS_OPTIONS}
                                value={STATUS_OPTIONS.find((x) => x.value === statusFilter)}
                                onChange={(value) => setStatusFilter((value?.value as ApprovalWorkflowStatus) ?? undefined)}
                                isClearable
                                placeholder="Status..."
                            />
                        </div>
                        <div className="flex w-full flex-col gap-3">
                            <label className="text-mti-gray-dim text-base font-normal">Entity</label>
                            <Select
                                options={ENTITY_OPTIONS}
                                value={ENTITY_OPTIONS.find((x) => x.value === entityFilter)}
                                onChange={(value) => setEntityFilter((value?.value as CustomEntity) ?? undefined)}
                                isClearable
                                placeholder="Entity..."
                            />
                        </div>
                    </div>

                    <div className="px-6 pb-4 bg-purple-100 rounded-2xl">
                        <table
                            className="w-full table-auto border-separate border-spacing-y-2"
                            style={{ tableLayout: "auto" }}
                        >
                            <thead>
                                {table.getHeaderGroups().map((headerGroup) => (
                                    <tr key={headerGroup.id}>
                                        {headerGroup.headers.map((header) => (
                                            <th key={header.id} className="px-2 py-3 text-left text-purple-900">
                                                {header.isPlaceholder
                                                    ? null
                                                    : flexRender(
                                                        header.column.columnDef.header,
                                                        header.getContext()
                                                    )}
                                            </th>
                                        ))}
                                    </tr>
                                ))}
                            </thead>
                            <tbody>
                                {table.getRowModel().rows.map((row) => (
                                    <tr
                                        key={row.id}
                                        onClick={() => window.location.href = `/approval-workflows/${row.original.id}`}
                                        style={{ cursor: "pointer" }}
                                        className="hover:bg-purple-100"
                                    >
                                        {row.getVisibleCells().map((cell, cellIndex) => {
                                            const lastCellIndex = row.getVisibleCells().length - 1;

                                            let cellClasses = "px-4 py-2 bg-purple-50 border-y-2 border-purple-300";
                                            if (cellIndex === 0) {
                                                cellClasses += " border-l-2 rounded-l-2xl";
                                            }
                                            if (cellIndex === lastCellIndex) {
                                                cellClasses += " border-r-2 rounded-r-2xl";
                                            }

                                            return (
                                                <td key={cellIndex} className={cellClasses}>
                                                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                                                </td>
                                            );
                                        })}
                                    </tr>
                                ))}
                            </tbody>

                        </table>
                    </div>




                </Layout>
            )}
        </>
    );
}
