import { useEffect, useState } from "react";
import { Stack, Tab, Table, Tabs } from "react-bootstrap";
import { fetchFromEndpoint } from "../../api/fetchFromEndpoint";

const TableRenderPane = ({ token, section, majorId, mean, distribution }) => {
  const [majorQuestions, setMajorQuestions] = useState(null);


  useEffect(() => {
    const trySetMajorQuestions = async () => {
      let semester = await fetchFromEndpoint(`/sections/${section}/`, token).then(response => response.json()).then(data => data);
      semester = semester.semester;

      const major_questions = await fetchFromEndpoint(
        `/major_questions/${majorId}/${semester}/`,
        token
      ).then((response) => response.json()).then((data) => data);

      if (major_questions)
        setMajorQuestions(major_questions);
    };

    trySetMajorQuestions();
  }, [section, majorId, token]);

  return (
    <Table
      striped
      hover
      style={{
        letterSpacing: ".05rem",
        fontSize: 18,
        backgroundColor: "#F8F8F8",
      }}
    >
      {majorQuestions ? (
        majorQuestions.questions.map((question, id) => (
          <tbody key={id}>
            <tr>
              <th colSpan={5}>
                <strong style={{ display: "flex", justifyContent: "center" }}>
                  {question}
                </strong>
              </th>
            </tr>
            <tr>
              <td>
                <Stack>
                  <strong>I agree strongly</strong>
                  <strong>
                    {distribution[majorId][id][5]
                      ? Math.round(
                        (distribution[majorId][id][5] /
                          distribution[majorId].responsesCount) *
                        100
                      )
                      : 0}
                    %
                  </strong>
                </Stack>
              </td>
              <td>
                <Stack>
                  <strong>I agree moderately</strong>
                  <strong>
                    {distribution[majorId][id][4]
                      ? Math.round(
                        (distribution[majorId][id][4] /
                          distribution[majorId].responsesCount) *
                        100
                      )
                      : 0}
                    %
                  </strong>
                </Stack>
              </td>
              <td>
                <Stack>
                  <strong>I am not sure</strong>
                  <strong>
                    {distribution[majorId][id][3]
                      ? Math.round(
                        (distribution[majorId][id][3] /
                          distribution[majorId].responsesCount) *
                        100
                      )
                      : 0}
                    %
                  </strong>
                </Stack>
              </td>
              <td>
                <Stack>
                  <strong>I disagree moderately</strong>
                  <strong>
                    {distribution[majorId][id][2]
                      ? Math.round(
                        (distribution[majorId][id][2] /
                          distribution[majorId].responsesCount) *
                        100
                      )
                      : 0}
                    %
                  </strong>
                </Stack>
              </td>
              <td>
                <Stack>
                  <strong>I disagree strongly</strong>
                  <strong>
                    {distribution[majorId][id][1]
                      ? Math.round(
                        (distribution[majorId][id][1] /
                          distribution[majorId].responsesCount) *
                        100
                      )
                      : 0}
                    %
                  </strong>
                </Stack>
              </td>
            </tr>
            <tr>
              <td>
                <strong>
                  Average responses {Math.round(mean[majorId][id] * 100) / 100}
                </strong>
              </td>
            </tr>
          </tbody>
        ))
      ) : (
        <></>
      )}
    </Table>
  );
};

const MajorQuestionsReport = ({ responsesByFilter, token }) => {
  const [majors, setMajors] = useState([]);
  const [responsesPerMajor, setResponsesPerMajor] = useState(null);
  const [sectionsPerMajor, setSectionsPerMajor] = useState(null);

  const [mean, setMean] = useState(null);
  const [distribution, setDistribution] = useState(null);

  useEffect(() => {
    const trySetMajors = async (urls) => {
      Promise.all(urls.map((url) => fetchFromEndpoint(url, token)))
        .then((responses) =>
          Promise.all(responses.map((response) => response.json()))
        )
        .then((data) => setMajors(data));
    };

    if (responsesByFilter) {
      const urls = new Set();
      const organizedResponses = {};
      const organizedSections = {};

      for (const response of responsesByFilter) {
        urls.add(`/majors/${response.major}/`);
        // sections.add(response.section)

        // organize responses per major
        if (organizedResponses[response.major])
          organizedResponses[response.major].push(response.major_answers);
        else organizedResponses[response.major] = [response.major_answers];

        // organize sections per major
        if (organizedSections[response.major])
          organizedSections[response.major].push(response.section);
        else organizedSections[response.major] = [response.section];
      }

      trySetMajors([...urls]);
      setResponsesPerMajor(organizedResponses);
      setSectionsPerMajor(organizedSections);
    }
  }, [responsesByFilter, token]);

  // generate report
  useEffect(() => {
    const generateReport = () => {
      const majorMean = {};
      const majorDistribution = {};

      // loop through each major
      for (const [major, responses] of Object.entries(responsesPerMajor)) {
        // calculate mean and distribution for all the answers

        majorMean[major] = [];
        majorDistribution[major] = {};
        // i = each question
        for (let i = 0; i < responses[0].length; i++) {
          let sum = 0;
          // j = each response
          majorDistribution[major][i] = {};
          for (let j = 0; j < responses.length; j++) {
            sum += responses[j][i];

            if (majorDistribution[major][i][responses[j][i]])
              majorDistribution[major][i][responses[j][i]] =
                majorDistribution[major][i][responses[j][i]] + 1;
            else majorDistribution[major][i][responses[j][i]] = 1;
          }

          majorMean[major].push(sum / responses.length);
        }
        majorDistribution[major].responsesCount = responses.length;
      }

      setMean(majorMean);
      setDistribution(majorDistribution);
    };

    if (responsesPerMajor) generateReport();
  }, [responsesPerMajor]);

  return majors.length !== 0 && responsesPerMajor && sectionsPerMajor ? (
    <Tabs
      id="majors-tabs"
      style={{
        letterSpacing: ".05rem",
        fontSize: 18,
      }}
      fill
    >
      {majors.map((major, id) => (
        <Tab eventKey={major.id} key={id} title={major.subject_area} style={{
          letterSpacing: ".05rem",
          fontSize: 18,
        }}>
          {sectionsPerMajor[major.id][0] ? (<TableRenderPane
            majorId={major.id}
            mean={mean}
            distribution={distribution}
            token={token}
            section={sectionsPerMajor[major.id][0]}
          />) : <></>}
        </Tab>
      ))}
    </Tabs>
  ) : (
    <></>
  );
};

export default MajorQuestionsReport;
