import InputWithChips, { UserChip } from "@components/InputWithChips";
import SimpleDivider from "@components/SimpleDivider";
import { Transition, Dialog } from "@headlessui/react";
import { PaperAirplaneIcon } from "@heroicons/react/20/solid";
import { Button, Typography } from "@material-tailwind/react";
import React, { Fragment, useEffect, useState } from "react";
import { Formik } from "formik";
import { AccessPermissions, AccessType } from "@prisma/client";
import AccessPermissionsPicker from "@components/AccessPermissionsPicker";

interface ShareTwineProps {
  open: boolean;
  accessPermissions?: AccessPermissions;
  onBackClicked: () => void;
  onSend: (users: string[], accessType?: AccessType) => void;
}

const initializeUsers = (users?: string[]) => {
  if (!users) return [];

  return users.map((user) => {
    return { username: user, img: "" };
  });
};

function useUsers(initialUsers?: string[]): [UserChip[], (user: string) => void, (index: number) => void] {
  const [users, setUsers] = useState<UserChip[]>(initializeUsers(initialUsers));

  const addUser = (username: string) => {
    if (users.some(user => user.username === username)) return;
    setUsers([...users, { username, img: "" }]);
  };

  const removeUser = (index: number) => {
    setUsers(users => users.filter((_, i) => i !== index)); 
  };

  return [users, addUser, removeUser];
}

const ShareTwine: React.FC<ShareTwineProps> = (props) => {
  const { open, onBackClicked, onSend, accessPermissions } = props;
  const [isOpen, setIsOpen] = useState(false);
  
  const [users, addUser, removeUser] = useUsers(accessPermissions?.sharedWith);
  const [selectedAccessType, setSelectedAccessType] = useState<AccessType>(
    AccessType.PUBLIC
  );

  useEffect(() => {
    setIsOpen(open);
  }, [open]);

  return (
    <Transition.Root show={isOpen} as={Fragment}>
      <Dialog as="div" onClose={() => null}>
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed lg:z-40 inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
        </Transition.Child>

        <div className="fixed inset-0 z-50 overflow-y-auto">
          <div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
              enterTo="opacity-100 translate-y-0 sm:scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 translate-y-0 sm:scale-100"
              leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
            >
              <Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white dark:bg-blue-gray-900 px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-6">
                <Dialog.Title
                  as="h2"
                  className="text-base font-semibold leading-6 text-gray-900 dark:text-blue-gray-300 mb-2"
                >
                  <div className="flex justify-between gap-2">
                    <Typography variant="h5">Share Your Twine</Typography>
                  </div>
                </Dialog.Title>
                <Typography
                  variant="small"
                  className="dark:text-blue-gray-400 text-sm font-light"
                >
                  Press enter/spacebar/comma to add a user
                </Typography>
                <Formik
                  initialValues={{ users, accessPermissions }}
                  onSubmit={async (values, { setSubmitting }) => {
                    setSubmitting(true);
                  }}
                >
                  {() => (
                    <>
                      <div className="mt-4 mb-2 flex flex-col gap-3">
                        <div className="flex flex-col">
                          <InputWithChips
                            users={users}
                            label="Add People"
                            variant="outlined"
                            name="users"
                            onUserRemoved={removeUser}
                            onUserAdded={addUser}
                          />
                        </div>
                        <AccessPermissionsPicker
                          name="accessPermissions"
                          accessType={accessPermissions?.access}
                          onPermissionsChange={(accessType: AccessType) =>
                            setSelectedAccessType(accessType)
                          }
                        />
                      </div>
                      <SimpleDivider />
                      <div className="mt-7 sm:mt- flex justify-between">
                        <Button
                          color="red"
                          className="dark:bg-red-400"
                          onClick={onBackClicked}
                        >
                          Back
                        </Button>
                        <Button
                          className="flex gap-2 items-center dark:bg-indigo-400"
                          color="indigo"
                          disabled={users.length === 0}
                          onClick={() => {
                            onSend(users.map(u => u.username.toLowerCase()), selectedAccessType);
                            setIsOpen(false);
                          }}
                        >
                          Send
                          <PaperAirplaneIcon className="h-5 w-5 self-center flex-none text-white" />
                        </Button>
                      </div>
                    </>
                  )}
                </Formik>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition.Root>
  );
};

export default ShareTwine;