/**
 * Create a pre-assignment pairing (student + group number)
 * @author Gabe Abrams
 */

// Import React
import React, { useReducer } from 'react';

// Import shared types
import User from '../../shared/types/User';

/*------------------------------------------------------------------------*/
/* -------------------------------- Types ------------------------------- */
/*------------------------------------------------------------------------*/

// Props definition
type Props = {
  // List of students to choose from
  students: User[],
  // Handler to call if the user cancels
  onCancel: () => void,
  /**
   * Handler to call when user is done creating the pre-assignment
   * @param studentId the id of the student to assign
   * @param groupNum the group number to assign the student to
   */
  onDone: (studentId: number, groupNum: number) => void,
};

/*------------------------------------------------------------------------*/
/* -------------------------------- Style ------------------------------- */
/*------------------------------------------------------------------------*/

const style = `
  .CreatePreAssignment-scrollable-container {
    /* Choose a height that cuts off one of the items (for mac scroll visibility) */
    max-height: 20rem;
    overflow-y: auto;
    overflow-x: hidden;
  }
`;

/*------------------------------------------------------------------------*/
/* -------------------------------- State ------------------------------- */
/*------------------------------------------------------------------------*/

/* -------------- Views ------------- */

enum View {
  // Choose a student
  ChooseStudent = 'ChooseStudent',
  // Choose a group number
  ChooseGroup = 'ChooseGroup',
}

/* -------- State Definition -------- */

type State = (
  | {
    // Current view
    view: View.ChooseStudent,
  }
  | {
    // Current view
    view: View.ChooseGroup,
    // Chosen student
    student: User,
  }
);

/* ------------- Actions ------------ */

// Types of actions
enum ActionType {
  // Choose a student
  ChooseStudent = 'ChooseStudent',
}

// Action definitions
type Action = (
  | {
    // Action type
    type: ActionType.ChooseStudent,
    // Chosen student
    student: User,
  }
);

/**
 * Reducer that executes actions
 * @author Gabe Abrams
 * @param state current state
 * @param action action to execute
 */
const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case ActionType.ChooseStudent: {
      return {
        view: View.ChooseGroup,
        student: action.student,
      };
    }
    default: {
      return state;
    }
  }
};

/*------------------------------------------------------------------------*/
/* ------------------------------ Component ----------------------------- */
/*------------------------------------------------------------------------*/

const CreatePreAssignment: React.FC<Props> = (props) => {
  /*------------------------------------------------------------------------*/
  /* -------------------------------- Setup ------------------------------- */
  /*------------------------------------------------------------------------*/

  /* -------------- Props ------------- */

  // Destructure all props
  const {
    students,
    onCancel,
    onDone,
  } = props;

  /* -------------- State ------------- */

  // Initial state
  const initialState: State = {
    view: View.ChooseStudent,
  };

  // Initialize state
  const [state, dispatch] = useReducer(reducer, initialState);

  // Destructure common state
  const {
    view,
  } = state;

  /*------------------------------------------------------------------------*/
  /* ------------------------------- Render ------------------------------- */
  /*------------------------------------------------------------------------*/

  /*----------------------------------------*/
  /* ---------------- Views --------------- */
  /*----------------------------------------*/

  // Body that will be filled with the current view
  let body: React.ReactNode;

  /* --------- Choose Student --------- */

  if (view === View.ChooseStudent) {
    // Create body
    // TODO: make list of students scrollable
    // TODO: v2: add back your search bar
    body = (
      <div className="DCHUI-CreatePreAssignment-choose-student-container">
        <h3>
          Choose the student to assign to a group:
        </h3>
        <div className="DCHUI-CreatePreAssignment-students-container CreatePreAssignment-scrollable-container">
          {
            students.map((student) => {
              return (
                <div
                  key={student.userId}
                  className="DCHUI-CreatePreAssignment-student-choice alert alert-secondary mb-1 p-2 d-flex align-items-center"
                >
                  <button
                    type="button"
                    className="DCHUI-CreatePreAssignment-student-choice-button btn btn-secondary m-0 flex-grow-1 text-start"
                    aria-label={`select student ${student.userFirstName} ${student.userLastName}`}
                    onClick={() => {
                      dispatch({
                        type: ActionType.ChooseStudent,
                        student,
                      });
                    }}
                  >
                    {student.userFirstName}
                    {' '}
                    {student.userLastName}
                  </button>
                </div>
              );
            })
          }
        </div>
        {/* TODO: make nicer cancel button */}
        <button
          id="DCHUI-cancel-student-assignment-button"
          type="button"
          className="btn btn-dark"
          aria-label="cancel assigning student to group"
          onClick={onCancel}
        >
          Cancel
        </button>
      </div>
    );
  }

  /* ---------- Choose Group ---------- */

  if (view === View.ChooseGroup) {
    // Destructure state
    const {
      student,
    } = state;

    // Create a list of groups
    const groupNums: number[] = [];
    for (let i = 1; i <= 50; i++) {
      groupNums.push(i);
    }

    // Create body
    body = (
      <div className="DCHUI-CreatePreAssignment-choose-group-container">
        <h3>
          What group do you want to put
          {' '}
          {student.userFirstName}
          {' '}
          in?
        </h3>
        <div className="DCHUI-CreatePreAssignment-group-choice-container CreatePreAssignment-scrollable-container">
          {
            groupNums.map((groupNum) => {
              return (
                <div
                  key={groupNum}
                  className="DCHUI-CreatePreAssignment-group-choice alert alert-secondary mb-1 p-2 d-flex align-items-center"
                >
                  <button
                    type="button"
                    className="DCHUI-CreatePreAssignment-group-choice-button btn btn-secondary m-0 flex-grow-1 text-start"
                    aria-label={`choose group ${groupNum}`}
                    onClick={() => {
                      onDone(student.userId, groupNum);
                    }}
                  >
                    Group
                    {' '}
                    {groupNum}
                  </button>
                </div>
              );
            })
          }
        </div>
        {/* TODO: make nicer cancel button */}
        <button
          id="DCHUI-CreatePreAssignment-cancel-group-choice-button"
          type="button"
          className="btn btn-dark"
          aria-label="cancel assigning student to group"
          onClick={onCancel}
        >
          Cancel
        </button>
      </div>
    );
  }

  /*----------------------------------------*/
  /* --------------- Main UI -------------- */
  /*----------------------------------------*/

  return (
    <div className="DCHUI-CreatePreAssignment-outer-container">
      {/* Style */}
      <style>
        {style}
      </style>

      {/* Body */}
      {body}
    </div>
  );
};

/*------------------------------------------------------------------------*/
/* ------------------------------- Wrap Up ------------------------------ */
/*------------------------------------------------------------------------*/

// Export component
export default CreatePreAssignment;
