import React, { useEffect, useState } from 'react';
import _ from 'lodash';
import { useFieldArray, useForm, useWatch } from 'react-hook-form';

import { Banner, StepsModal, ProgressSteps } from 'src/components';
import { Select, TextArea } from 'src/components/Form';
import { MultipleUsersData, UserRole, useUsers } from 'src/services/users';
import { allAppAccessList } from 'src/components/UserModal/consts';
import { ProgressStepInfo, ProgressStepStatus } from 'src/components/ProgressSteps/types';
import { initialMultipleUsersForm, MultipleUsersModalProps } from './types';

export const MultipleUsersModal = ({ open, onClose }: MultipleUsersModalProps) => {
  const [steps, setSteps] = useState<ProgressStepInfo[]>([]);
  const [isAdminRoleSelected, setAdminRoleSelected] = useState(false);
  const { createUsers, userModalLoading } = useUsers();

  const { control, handleSubmit } = useForm<MultipleUsersData>({
    defaultValues: initialMultipleUsersForm,
  });

  const { fields, update } = useFieldArray({
    control,
    name: 'appRoles',
  });

  const dashboardRole = useWatch({
    control,
    name: 'appRoles.0.role',
  });

  const csvDataWatch = useWatch({
    control,
    name: 'csvUserData',
  });

  useEffect(() => {
    const isAdminDashboardRoleSelected = dashboardRole === UserRole.Admin;
    setAdminRoleSelected(isAdminDashboardRoleSelected);
    if (isAdminDashboardRoleSelected) {
      fields.forEach((field, index) => update(index, { name: field.name, role: UserRole.Admin }));
    } else {
      fields.forEach((field, index) => update(index, { name: field.name, role: UserRole.User }));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dashboardRole]);

  const renderUsersCsvDataInput = () => {
    return (
      <div>
        <div className="mt-8">
          <h3 className="text-lg leading-6 font-medium text-gray-900">CSV data</h3>
        </div>
        <div className="mt-6">
          <TextArea
            control={control}
            name="csvUserData"
            placeholder={`Please paste users in CSV format: email, name\nuser1@example.com,User One\nuser2@example.com,User Two`}
            rows={15}
            required
          />
        </div>
      </div>
    );
  };

  const renderAppAccess = () => {
    return (
      <div>
        <div className="mt-8">
          <h3 className="text-lg leading-6 font-medium text-gray-900">App Access</h3>
        </div>

        {isAdminRoleSelected && (
          <div className="sm:col-span-6">
            <Banner title="Admin users automatically have admin-level access to all apps." titleSm="Admin user" />
          </div>
        )}

        <div>
          <div className="flow-root mt-6">
            <ul className="-my-5 divide-y divide-gray-200">
              {fields
                .filter((field) => field.name === 'dashboard')
                .map((item, index) => (
                  <li className="py-4" key={item.name}>
                    <div className="flex items-center space-x-4">
                      <div className="flex-shrink-0 flex-1 flex items-center">
                        <img
                          className="h-10 w-10 rounded-md overflow-hidden"
                          src={_.find(allAppAccessList, ['name', item.name!])?.image}
                          alt={item.name ?? 'Image'}
                        />
                        <h3 className="ml-4 text-md leading-6 font-medium text-gray-900">
                          {_.find(allAppAccessList, ['name', item.name!])?.label}
                        </h3>
                      </div>
                      <div className="sm:col-span-2">
                        <Select
                          key={item.id}
                          control={control}
                          name={`appRoles.${index}.role`}
                          options={[
                            { value: UserRole.User, name: 'User' },
                            { value: UserRole.Admin, name: 'Admin' },
                          ]}
                        />
                      </div>
                    </div>
                  </li>
                ))}
              {!isAdminRoleSelected &&
                fields.map((item, index) => {
                  if (item.name === 'dashboard') {
                    return null;
                  }

                  return (
                    <li className="py-4" key={item.name}>
                      <div className="flex items-center space-x-4">
                        <div className="flex-shrink-0 flex-1 flex items-center">
                          <img
                            className="h-10 w-10 rounded-md overflow-hidden"
                            src={_.find(allAppAccessList, ['name', item.name!])?.image}
                            alt={item.name ?? 'Image'}
                          />
                          <h3 className="ml-4 text-md leading-6 font-medium text-gray-900">
                            {_.find(allAppAccessList, ['name', item.name!])?.label}
                          </h3>
                        </div>
                        <div className="sm:col-span-2">
                          <Select
                            key={item.id}
                            control={control}
                            name={`appRoles.${index}.role`}
                            disabled={isAdminRoleSelected}
                            options={[
                              { value: UserRole.NoAccess, name: 'No Access' },
                              { value: UserRole.User, name: 'User' },
                              { value: UserRole.Admin, name: 'Admin' },
                            ]}
                          />
                        </div>
                      </div>
                    </li>
                  );
                })}
            </ul>
          </div>
        </div>
      </div>
    );
  };

  useEffect(() => {
    setSteps([
      {
        id: 'Step 1',
        name: 'Enter CSV user data',
        status: ProgressStepStatus.Current,
      },
      {
        id: 'Step 2',
        name: 'Define app access roles',
        status: ProgressStepStatus.Upcoming,
      },
    ]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  const handleSave = async () => {
    try {
      await handleSubmit((data) => createUsers(data))();
    } catch (e: any) {
      // Continue
    }

    onClose();
  };

  const handleClose = () => {
    onClose();
  };

  const getActiveStepIndex = () => _.findIndex(steps, { status: ProgressStepStatus.Current });

  const updateStepsStatus = (nextIndex: number) => {
    const updatedSteps = [...steps];
    _.forEach(updatedSteps, (step, index) => {
      if (index < nextIndex) {
        step.status = ProgressStepStatus.Complete;
      } else if (index === nextIndex) {
        step.status = ProgressStepStatus.Current;
      } else {
        step.status = ProgressStepStatus.Upcoming;
      }
    });
    setSteps(updatedSteps);
  };

  const handleStepClick = (stepId: string) => {
    const activeStepIndex = _.findIndex(steps, { id: stepId });
    updateStepsStatus(activeStepIndex);
  };

  const handleNext = () => {
    const nextIndex = getActiveStepIndex() + 1;
    updateStepsStatus(nextIndex);
  };

  const handlePrevious = () => {
    const nextIndex = getActiveStepIndex() - 1;
    updateStepsStatus(nextIndex);
  };

  const activeStepIndex = getActiveStepIndex();
  const showSave = !_.some(steps, { status: ProgressStepStatus.Upcoming });
  const showPrevious = _.some(steps, { status: ProgressStepStatus.Complete });

  return (
    <StepsModal
      onClose={handleClose}
      open={open}
      onSave={handleSave}
      onNext={handleNext}
      onPrevious={handlePrevious}
      showPreviousButton={showPrevious}
      isLoading={userModalLoading}
      useCancelButton
      showSaveButton={showSave}
      saveButtonDisabled={_.isEmpty(csvDataWatch)}
    >
      <div className="bg-white px-4">
        <div className="space-y-10 divide-y divide-gray-200">
          <div>
            <div>
              <h3 className="text-lg leading-6 font-medium text-gray-900">Add new users</h3>
            </div>
            <div className="sm:px-6 pt-6">
              <ProgressSteps steps={steps} onStepClick={handleStepClick}>
                {activeStepIndex === 0 ? renderUsersCsvDataInput() : renderAppAccess()}
              </ProgressSteps>
            </div>
          </div>
        </div>
      </div>
    </StepsModal>
  );
};
