import RosterCard from './RosterCard';
import ProfileCard from '../shared/ProfileCard';
import React, { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { Button, Form, Modal } from 'react-bootstrap';

import AddProfileButton from './AddProfileButton';
import NewAdminForm from './NewAdminForm';

import {
  User,
  getUsers,
  getStudents,
  getUser,
  getInstructors,
} from '../../api/Users';
import LockerInputGroup from './LockerInputGroup';
import { getFormattedTeamName, getTeam, getTeams, Team } from '../../api/Teams';
import { useAuth } from '../../auth/AuthProvider';
import TeamNameForm from '../team/TeamNameForm';
import { createNotification, Notification } from '../../api/Notifications';
import { useToast } from '../Toast/ToastContext';
import { useMediaQuery } from 'react-responsive';
import { breakpoints } from '../../utils/BootstrapHelper';
import { Icon } from '../shared/Icon';

const RosterGrid: React.FC<{
  roster: any[];
  showInstructorsOnly?: boolean;
  isStudentView?: boolean;
  isStudentAdmins?: boolean;
  isStudentViewTeamNum?: number;
  onTriggerRefresh?: () => void;
  updateBreadcrumbs?: (newItems: { label: string; href: string }[]) => void;
}> = ({
  roster,
  showInstructorsOnly = false,
  isStudentView = false,
  isStudentAdmins = false,
  isStudentViewTeamNum,
  onTriggerRefresh,
  updateBreadcrumbs,
}) => {
  const navigate = useNavigate();
  const location = useLocation();
  const path = location.pathname;

  const { sectionId, teamId } = useParams();
  const [showAdminForm, setShowAdminForm] = useState(false); // modal
  const [showNameForm, setShowNameForm] = useState(false); // modal

  const [selectedSection, setSelectedSection] = useState<number | null>(
    sectionId ? parseInt(sectionId) : null
  );

  const [selectedTeam, setSelectedTeam] = useState<number | null>(null);
  const [selectedTeamName, setSelectedTeamName] = useState('');

  const [activeTeam, setActiveTeam] = useState<Team | null>(null); // team object
  const [teams, setTeams] = useState<any[]>([]);
  const [instructors, setInstructors] = useState<User[]>([]);
  const [users, setUsers] = useState<any[]>([]); // state for holding user profiles

  const [loading, setLoading] = useState(false); // to handle asynchronous state changes

  const { user } = useAuth();
  const [isAdminCurrent, setIsAdminCurrent] = useState(false);

  const [selectedUser, setSelectedUser] = useState<User | undefined>(undefined); // for custom messages
  const [customMessage, setCustomMessage] = useState('');
  const [showMessageForm, setShowMessageForm] = useState(false);
  const { addToast } = useToast();

  // URL change update
  useEffect(() => {
    setLoading(true);
    if (!isStudentView) {
      if (sectionId) {
        fetchTeams(parseInt(sectionId));
        setSelectedSection(parseInt(sectionId));
        // Fetch fresh team data instead of using the initial roster data
      } else {
        setSelectedSection(null);
        setTeams([]);
      }

      if (!teamId) {
        setSelectedTeam(null);
      }
    } else {
      if (!isStudentAdmins) {
        if (!isStudentViewTeamNum) return;

        setSelectedTeam(isStudentViewTeamNum);
        fetchUpdatedTeam();
      }
    }
  }, [sectionId, teamId, roster]);

  // team selection changes
  useEffect(() => {
    if (selectedSection && selectedTeam) {
      // Update only the required data for the selected team
      setLoading(true);
      fetchUpdatedTeam(); // Ensure you fetch data only when the team is selected
      //breadcrumbHelper(selectedSection, selectedTeam);
    } else {
      setActiveTeam(null); // Clear any active team when none is selected
      setUsers([]); // Clear users if no team is selected
      setLoading(false);
      //breadcrumbHelper(selectedSection, -1);
    }
    if (!isStudentView) {
      if (!selectedSection && !selectedTeam) breadcrumbHelper(-1, -1);
      else if (selectedSection && !selectedTeam)
        breadcrumbHelper(selectedSection, -1);
      else if (selectedSection && selectedTeam)
        breadcrumbHelper(selectedSection, selectedTeam);
    }
  }, [selectedSection, selectedTeam]);

  // load users initially
  useEffect(() => {
    fetchUpdatedAdmin();
    if (user?.type === 'instructor') {
      determineInstructorStatus();
    }
  }, [user]);

  useEffect(() => {
    const initializeTeamFromURL = async (num: string, sectionId: string) => {
      const t = await getTeams(parseInt(sectionId));
      const matchedTeam = t.find(
        (team) =>
          team.team_num === parseInt(num) &&
          team.section_id === parseInt(sectionId)
      );
      if (matchedTeam) setSelectedTeam(matchedTeam.team_id || null);
    };

    if (teamId && sectionId) {
      initializeTeamFromURL(teamId, sectionId);
    }
  }, [teamId, sectionId]);

  const breadcrumbHelper = (section: number, team: number) => {
    if (section === -1) {
      updateBreadcrumbs([{ label: 'Roster', href: '/roster' }]);
    } else if (team === -1) {
      updateBreadcrumbs([
        //{ label: 'Home', href: '/' },
        { label: 'Roster', href: '/roster' },
        {
          label: `Section ${section}`,
          href: `/roster/section/${section}`,
        },
      ]);
    } else {
      updateBreadcrumbs([
        //{ label: 'Home', href: '/' },
        { label: 'Roster', href: '/roster' },
        {
          label: `Section ${section}`,
          href: `/roster/section/${section}`,
        },
        {
          label: `Team ${teamId}`,
          href: `/roster/section/${section}/team/${teamId}`,
        },
      ]);
    }
  };

  const determineInstructorStatus = async () => {
    try {
      const instructors = await getInstructors();
      const currInstructor = instructors.find(
        (inst) => inst.user_id === user?.user_id
      );

      if (currInstructor?.is_admin === 'true') {
        setIsAdminCurrent(true);
      }
    } catch (error) {
    } finally {
      //console.log(user?.user_id);
      //console.log(isAdminCurrent);
    }
  };

  const fetchTeams = async (sectionId: number) => {
    try {
      const sectionData = roster.find((r) => r.id === sectionId);
      if (!sectionData) return;

      // Fetch updated teams with student data
      const updatedTeams = await Promise.all(
        sectionData.teams.map(async (team: { team_id: number | undefined }) => {
          const students = await getStudents(team.team_id);
          return { ...team, students };
        })
      );

      setTeams(updatedTeams);
    } catch (error) {
      console.error('Error fetching teams:', error);
    }
  };

  const handleSectionClick = (roster: Roster) => {
    if (selectedSection === roster.id) {
      navigate('/roster');
      setSelectedSection(null); // Clear the selected section
    } else {
      navigate(`/roster/section/${roster.id}`);
      setSelectedSection(selectedSection);
    }
  };

  const handleTeamClick = (teamId: number) => {
    setSelectedTeam(null);
    if (selectedTeam === teamId) {
      navigate(`/roster/section/${selectedSection}`);
      //setSelectedTeam(null); // Ensure selectedTeam is null
    } else {
      //setSelectedTeam(teamId); // Update the selectedTeam
      navigate(`/roster/section/${selectedSection}/team/${teamId}`);
    }
  };

  // Fetching users from the API or initial data
  const fetchUpdatedAdmin = async () => {
    try {
      // Fetch TAs
      const tas = await getUsers('ta');

      // Fetch Instructors
      const instructors = await getUsers('instructor');

      // Combine both lists into one
      const adminData = [...tas, ...instructors];

      // Update state
      setInstructors(adminData);
      return adminData;
    } catch (error) {
      console.error('Error fetching admins:', error);
      setInstructors([]); // Ensure state is updated even if an error occurs
    }
  };

  const fetchUpdatedTeam = async () => {
    if (selectedTeam != undefined) {
      try {
        const u = await getStudents(selectedTeam);

        // Fetch detailed information for each student by user_id
        const d = await Promise.all(
          u.map(async (student) => {
            const d = await getUser(student.user_id);
            return { ...student, ...d };
          })
        );
        setUsers([]);
        setUsers(d);

        const teamData = await getTeam(selectedTeam);
        if (!teamData) return;
        setSelectedTeamName(getFormattedTeamName(teamData));
        setActiveTeam(teamData);

        // Update the specific team's students list, ensuring the student count stays updated
        setTeams((prevTeams) =>
          prevTeams.map(
            (team) =>
              team.team_id === selectedTeam
                ? { ...team, students: d } // Update students list only for the selected team
                : team // Leave other teams unchanged
          )
        );
      } catch (error) {
        console.error('Error fetching users in team:', error);
        setUsers([]); // Ensure state is updated even if an error occurs
      } finally {
        setLoading(false); // Stop loading
      }
    }
  };

  const getSectionColor = (sectionId: number) => {
    const selectedSectionColor =
      roster.find((section) => section.id === sectionId)?.color || '#000000'; // Default to black if not found
    return selectedSectionColor;
  };

  const sendCustomNotification = async () => {
    if (!customMessage.trim()) {
      addToast('Please enter a message.', 'danger');
      return;
    }

    const customNotification: Notification = {
      team_id: selectedTeam as number,
      generated_message: `Message from ${user?.first_name} ${user?.last_name}:`,
      free_text: customMessage,
      for_instructor: false,
    };

    await createNotification(customNotification);
    addToast('Message sent to team.', 'success');

    // Reset form
    setSelectedUser(undefined);
    setCustomMessage('');
    setShowMessageForm(false);
  };

  const isMobile = useMediaQuery({ maxWidth: breakpoints.sm - 1 });

  const [submitAdminForm, setSubmitAdminForm] = useState(false);
  const submitAdminFormButton = useRef<HTMLButtonElement | null>(null);
  const [submitNameForm, setSubmitNameForm] = useState(false);
  const submitNameFormButton = useRef<HTMLButtonElement | null>(null);
  useEffect(() => {
    const handleKey = (event: { key: string }) => {
      if (event.key === 'Enter') {
        submitAdminFormButton.current?.click();
      }
    };

    if (showAdminForm) {
      window.addEventListener('keydown', handleKey);
    } else {
      window.removeEventListener('keydown', handleKey);
    }
  }, [showAdminForm]);
  useEffect(() => {
    const handleKey = (event: { key: string }) => {
      if (event.key === 'Enter') {
        submitNameFormButton.current?.click();
      }
    };

    if (showNameForm) {
      window.addEventListener('keydown', handleKey);
    } else {
      window.removeEventListener('keydown', handleKey);
    }
  }, [showNameForm]);

  if (showInstructorsOnly) {
    return (
      <>
        {/* Show the "Add Admin" Button */}
        {isAdminCurrent && (
          <div
            className={`d-flex justify-content-start align-items-center mb-3`}
          >
            <AddProfileButton
              onClick={() => setShowAdminForm(true)}
              type='Faculty'
            />
            <Modal show={showAdminForm} onHide={() => setShowAdminForm(false)}>
              <Modal.Header closeButton>
                <Modal.Title>Add Faculty User</Modal.Title>
              </Modal.Header>
              <Modal.Body>
                <div className='mb-3'>
                  Enter the new faculty user's information and select a user
                  type.
                </div>
                <hr />
                <div className='mb-2'>
                  <NewAdminForm
                    onClose={() => setShowAdminForm(false)}
                    onAdminAdded={() => {
                      setShowAdminForm(false); // Close the form
                      fetchUpdatedAdmin(); // Refresh the users list
                    }}
                    submit={submitAdminForm}
                    setSubmit={setSubmitAdminForm}
                  />
                </div>
              </Modal.Body>
              <Modal.Footer>
                <Button
                  variant='secondary'
                  onClick={() => setShowAdminForm(false)}
                >
                  Cancel
                </Button>

                <Button
                  ref={submitAdminFormButton}
                  variant='primary'
                  onClick={() => setSubmitAdminForm(true)}
                >
                  Add User
                </Button>
              </Modal.Footer>
            </Modal>
          </div>
        )}

        <div className='grid-container'>
          <div
            className='flex gap-3 justify-center relative'
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
              gap: '20px', // Spacing between cards
              //padding: '16px',
            }}
          >
            {instructors.map((instructor) => (
              <ProfileCard
                key={instructor.user_id}
                id={instructor.user_id ?? 0} // Ensure valid ID
                first={instructor.first_name}
                last={instructor.last_name}
                email={instructor.email_address}
                type={instructor.type}
                isSelected={false}
                onClick={() => {}}
                className={
                  instructor.type === 'ta'
                    ? 'ta-card cursor-pointer transition-all duration-500 ease-in-out'
                    : 'instructor-card cursor-pointer transition-all duration-500 ease-in-out'
                }
                rosterData={roster}
                onDelete={() => {}}
                fetchUpdatedTeam={fetchUpdatedTeam}
                fetchUpdatedAdmin={fetchUpdatedAdmin}
              />
            ))}
          </div>
        </div>
      </>
    );
  }

  if (!isStudentView) {
    return (
      <div className='grid-container'>
        {!loading && selectedTeam && (
          <div className='d-flex align-items-center gap-3 mb-3'>
            <Button
              variant='success'
              onClick={() => setShowMessageForm(true)}
              className={`${isMobile ? 'flex-grow-1' : ''}`}
              disabled={
                !teams.find((team) => team.team_id === selectedTeam)?.students
                  .length
              }
            >
              Send Message
            </Button>
            {/* Modal for sending custom notification */}
            <Modal
              show={showMessageForm}
              onHide={() => {
                setShowMessageForm(false);
                setSelectedUser(undefined);
              }}
            >
              <Form
                onSubmit={(event) => {
                  event.preventDefault();

                  if (event.currentTarget.checkValidity()) {
                    sendCustomNotification();
                  } else {
                    event.currentTarget.classList.add('was-validated');
                  }
                }}
                noValidate
              >
                <Modal.Header closeButton>
                  <Modal.Title>Send Custom Notification</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                  <div>
                    <p className='mb-2'>
                      <strong>Selected Team:</strong> {selectedTeamName}
                    </p>
                    <div className='mb-2'>
                      <Form.Control
                        as='textarea'
                        rows={3}
                        placeholder='Enter notification message...'
                        value={customMessage}
                        onChange={(e) => setCustomMessage(e.target.value)}
                        required
                      />
                      <Form.Control.Feedback type='invalid'>
                        Please enter a message.
                      </Form.Control.Feedback>
                    </div>
                  </div>
                </Modal.Body>
                <Modal.Footer>
                  <Button
                    variant='secondary'
                    onClick={() => {
                      setShowMessageForm(false);
                      setSelectedUser(undefined);
                    }}
                  >
                    Close
                  </Button>
                  <Button type='submit' variant='primary'>
                    Send Notification
                  </Button>
                </Modal.Footer>
              </Form>
            </Modal>
            <div style={{ minWidth: '55px' }}>
              <LockerInputGroup
                //key={team?.locker_num} // Forces re-mount when locker changes
                team_id={activeTeam?.team_id}
                locker={activeTeam?.locker_num}
                onClick={() => {}}
              />
            </div>
          </div>
        )}
        <div
          className='flex gap-3 justify-center relative'
          style={{
            display:
              selectedTeam !== null &&
              activeTeam !== null &&
              !teams.find((team) => team.team_id === activeTeam.team_id)
                ?.students.length
                ? undefined
                : 'grid',
            gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
            gap: '20px', // Spacing between cards
            //padding: '16px',
          }}
        >
          {/* Display all sections */}
          {roster.map((roster) =>
            selectedSection === null ? (
              <RosterCard
                key={roster.id}
                id={roster.id}
                num={null}
                count={roster.count}
                name={''}
                isSelected={selectedSection === roster.id}
                onClick={() => handleSectionClick(roster)}
                className='cursor-pointer transition-all duration-500 ease-in-out'
                color={roster.color}
              />
            ) : null
          )}
          {/* Display the teams within the same grid layout as the section cards */}
          {selectedSection !== null &&
            teams.length > 0 &&
            teams[0].section_id === selectedSection &&
            teams
              .sort((a, b) => a.team_num - b.team_num)
              .map((team) => (
                <React.Fragment key={team.team_id}>
                  {selectedTeam === null && (
                    <RosterCard
                      id={team.team_id}
                      num={team.team_num}
                      count={team.students.length}
                      name={getFormattedTeamName(team, true)}
                      isSelected={selectedTeam === team.team_num}
                      onClick={() => handleTeamClick(team.team_num)}
                      className='team-card cursor-pointer transition-all duration-500 ease-in-out'
                      color={getSectionColor(selectedSection)}
                    />
                  )}

                  {/* Display Locker Assignment Input Group When Team Clicked Into */}
                  {selectedTeam !== null &&
                    activeTeam !== null &&
                    activeTeam.team_id === team.team_id &&
                    !loading && (
                      <>
                        {/* Student Profile Cards (only if the team is selected) */}
                        {team.students &&
                        selectedTeam === team.team_id &&
                        !loading &&
                        users.length > 0 ? (
                          users.map((student) =>
                            student.user_id !== undefined ? ( // Ensure user_id is defined
                              <ProfileCard
                                key={student.user_id}
                                id={student.user_id}
                                first={student.first_name}
                                last={student.last_name}
                                email={student.email_address}
                                type={student.type}
                                isSelected={false}
                                onClick={() => {}}
                                className='student-card cursor-pointer transition-all duration-500 ease-in-out'
                                color={getSectionColor(selectedSection)}
                                rosterData={roster}
                                onDelete={() => {}}
                                fetchUpdatedTeam={fetchUpdatedTeam}
                                fetchUpdatedAdmin={fetchUpdatedAdmin}
                              />
                            ) : null
                          )
                        ) : (
                          <div className='d-flex flex-column justify-content-center align-items-center mt-5'>
                            <Icon
                              iconName='BackpackFill'
                              size={64}
                              className='text-warning mb-3'
                            />
                            <p className='lead text-center mb-0'>
                              No students assigned to team!
                            </p>
                          </div>
                        )}
                      </>
                    )}
                </React.Fragment>
              ))}
        </div>
      </div>
    );
  }
  if (isStudentView && (selectedTeam || isStudentAdmins)) {
    return (
      <div className='grid-container'>
        {!isStudentAdmins && (
          <div className='d-flex align-items-center gap-3 mb-3'>
            <Button
              variant='success'
              onClick={() => setShowNameForm(true)}
              className={`${isMobile ? 'flex-grow-1' : ''}`}
            >
              Change Name
            </Button>
            <Modal show={showNameForm} onHide={() => setShowNameForm(false)}>
              <Modal.Header closeButton>
                <Modal.Title>Change Team Name</Modal.Title>
              </Modal.Header>
              <Modal.Body>
                <div className='mb-3'>
                  Enter a new team name. This change will be visible to your
                  course instructors.
                </div>
                <hr />
                <div className='mb-2'>
                  <TeamNameForm
                    currName={selectedTeamName}
                    setCurrName={setSelectedTeamName}
                    team_id={selectedTeam}
                    onClose={() => setShowNameForm(false)}
                    onAdminAdded={() => {
                      setShowNameForm(false); // Close the form
                      onTriggerRefresh();
                      //fetchUpdatedTeam(); // Refresh the users list
                    }}
                    submit={submitNameForm}
                    setSubmit={setSubmitNameForm}
                  />
                </div>
              </Modal.Body>
              <Modal.Footer>
                <Button
                  variant='secondary'
                  onClick={() => setShowNameForm(false)}
                >
                  Cancel
                </Button>

                <Button
                  ref={submitNameFormButton}
                  variant='primary'
                  onClick={() => setSubmitNameForm(true)}
                >
                  Change Name
                </Button>
              </Modal.Footer>
            </Modal>
            <div style={{ minWidth: '55px' }}>
              <LockerInputGroup
                //key={team?.locker_num} // Forces re-mount when locker changes
                team_id={selectedTeam}
                locker={null}
                onClick={() => {}}
              />
            </div>
          </div>
        )}
        <div
          className='flex gap-4 justify-center relative'
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
            gap: '20px', // Spacing between cards
            //padding: '16px',
          }}
        >
          {roster.map((student) => (
            //student.user_id !== undefined ? ( // Ensure user_id is defined
            <ProfileCard
              key={student.user_id}
              id={student.user_id}
              first={student.first_name}
              last={student.last_name}
              email={student.email_address}
              type={student.type}
              isSelected={false}
              onClick={() => {}}
              className='student-card cursor-pointer transition-all duration-500 ease-in-out'
              color={student.type === 'student' ? '#cfb991' : undefined}
              rosterData={roster}
              onDelete={() => {}}
              fetchUpdatedTeam={fetchUpdatedTeam}
              fetchUpdatedAdmin={fetchUpdatedAdmin}
              isStudentView={true}
            />
          ))}
        </div>
      </div>
    );
  }
};

export default RosterGrid;
