'use client';
import React, { useEffect, useState } from 'react';
import Image from 'next/image';
import adminimg from '@images/pro2.png';
import * as XLSX from 'xlsx';
import { useMemo, useCallback } from 'react';
import { utils, writeFile } from 'xlsx';
import { useMutation } from 'react-query';
import { useQueryClient } from 'react-query';
import Reacentuser from '@/components/Reacentuser';
import dropdownImagee from '@images/dropdown.png';
// import { toast } from 'react-toastify';

import toast, { Toaster } from 'react-hot-toast';
import { useContext } from 'react';
import { MyContext } from '@/components/MyContext';
import 'react-toastify/dist/ReactToastify.css';
// import DropdownImage from '@/assets/images/dropdown.png';
import { useRouter } from 'next/router';
import {
  date,
  employee,
  time,
  storeCurrentDays,
  getInitials,
  getCurrentDateOfMonth,
  getInitials2,
  storeTotalDays,
  datesInRange,
} from '../../data';
// import { useQuery } from "@tanstack/react-query";

import { FaBeer } from 'react-icons/fa';
import { useQuery } from 'react-query';
import { type } from 'os';

//prisma for gettinga database data
// type handler
type Item = {
  userid: number;
  email: string;
  firstname: string;
  initials: string;
  phone: string;
  surname: string;
};

// type handler
type calendar_data = {
  userid: number;
  year: number;
  id: number;
  month: number;
  day: number;
  date: Date;
  start_time: number;
  presenter_id: number;
  presenter_initials: string;
};

// type handler
interface updateInitialsValue {
  userId: number;
  Initials: string;
}

// type hadler for nested object Day wise in nested object
interface DayWise {
  Currentday: number;
  slots: slot[];
}
interface slot {
  time: number;
  initials: string;
  uniqueId: number;
}

// type handler for tart time
interface slotTime {
  id: number;
  start_time: number;
}

// function which create a Table data into Excel Sheet
const exportToExcel = () => {
  const workbook = XLSX.utils.book_new();
  const worksheet = XLSX.utils.table_to_sheet(
    document.getElementById('tableId')
  );
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
  XLSX.writeFile(workbook, 'data.xlsx');
};

// taking data as argumnet than printing excel sheet
// const exportToExcel = (tableData) => {
//   // Create a new workbook
//   const workbook = XLSX.utils.book_new();

//   // Convert table data to a worksheet
//   const worksheet = XLSX.utils.json_to_sheet(tableData);

//   // Add the worksheet to the workbook
//   XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');

//   // Save the workbook to an Excel file
//   XLSX.writeFile(workbook, 'table_data.xlsx');
// };

// Define an interface for the object
interface objectForEmploye {
  selectValue: string;
  currentDate: string;
  time: string;
}
interface getUpdatedInitialCall {
  handleClick: () => void; // Define the prop type as a function that takes no arguments and returns void
}

// Our total Employee schedule list info
export const TotalEmployeInfo: objectForEmploye[] = [];

const TableData: React.FC<getUpdatedInitialCall> = ({ handleClick }) => {
  // accessing a context api
  const { formValues, setFormValues, isAdmin, setIsAdmin } =
    useContext(MyContext);

  const queryClient = useQueryClient();
  const [dataa, setData] = useState<Item[]>([]);
  const [startTime, SetStartTime] = useState<slotTime[]>([]);
  const [flag, setFlag] = useState(true);
  const [calendarData, setCalendarData] = useState<calendar_data[]>([]);
  const [selectedOption, setSelectedOption] = useState('');
  const [selectValue, setSelectValue] = useState('');
  const [DayWiseData, setDayWiseData] = useState<DayWise[]>([]);
  const imageUrl = '';
  function hadleOptionChange(e: any) {
    setSelectedOption(e.target.value);
  }
  const router = useRouter();
  const { pathname } = router;

  function CheckIsAdmin(user: boolean) {
    setIsAdmin(user);
  }

  // A function returing async function
  function fetchPresenter() {
    return async () => {
      const response = await fetch('api/presenterdata');
      const data = await response.json();
      setData(data);
    };
  }

  // A function returing async function
  async function getCalendarData(year: number, month: number) {
    const response = await fetch('api/presentercalendar');
    const data = await response.json();

    setCalendarData(data);
    // here perforning post request for storing user data
    // const res = await fetch('api/presentercalendarbyfilter', {
    //   method: 'POST',
    //   headers: { 'Content-Type': 'application/json' },
    //   body: JSON.stringify({ year: year, month: month }),
    // });
    // const data = await res.json();
    // setCalendarData(data);
  }

  // a function which give Total calendar data
  async function CalendardataByFilter(year: number, month: number) {
    // here perforning post request for storing user data
    const res = await fetch('api/presentercalendarbyfilter', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ year: year, month: month }),
    });
    const data = await res.json();
    // this part creating error of filter month and year
    setCalendarData(data);

    // setCalendarData(data);
  }

  useEffect(() => {
    if (typeof window !== 'undefined') {
      const checkUser = localStorage.getItem('isAdminUser');
      if (checkUser === 'admin') {
        CheckIsAdmin(true);
      } else {
        CheckIsAdmin(false);
      }

      // if(userInfoFromlocal){
      //   setUserInfo(JSON.parse(userInfoFromlocal));
      // }
      // if (storedState) {
      //   setMyState(storedState);
      // }
    }
  }, [CheckIsAdmin, isAdmin, router]);

  useEffect(() => {
    // formValues :  {month: '', year: '2023'}
    if (formValues.month != '' && formValues.year != '') {
      CalendardataByFilter(
        parseInt(formValues.year),
        parseInt(formValues.month)
      );
    }
  }, [formValues]);

  // const {
  //   data: userData,
  //   isLoading: isUserLoading,
  //   error: userError,
  // } = useQuery('calendarData', getCalendarData);
  // handling refetch the data
  const handleCalendarfetchData = () => {
    queryClient.invalidateQueries('calendarData');
  };

  let checkData = 0;

  // get slot data
  // A function returing async function
  function getInitialSlot() {
    return async () => {
      const response = await fetch('api/getslotdata');
      const data = await response.json();
      SetStartTime(data);
    };
  }
  // using react query
  const { data: slotData } = useQuery('slotData', getInitialSlot);
  // a function which update initials
  async function updateInitials(data: object) {
    const res = await fetch('api/updateinitials', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: { 'Content-Type': 'application/json' },
    });

    if (pathname === '/show_schedule') {
      if (res.ok) {
        toast.success('Successfully Added!');
      }
    } else {
      if (res.ok) {
        toast.success('Successfully Added!');
        handleClick();
      }
    }
  }
  // updating the value using useMutation
  const mutation = useMutation(updateInitials, {
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries('user');
    },
  });

  // TABLE login part Start from here

  // a function which help to update Initials value in server
  function getUniqueId({ InitialTime, getSlot }: any) {
    const getId = [];
    for (let i = 0; i < getSlot.length; i++) {
      if (parseInt(getSlot[i].time) === InitialTime) {
        getId.push(getSlot.uniqueId);
        return getSlot[i].uniqueId;
        break;
      }
    }
    return 8;
  }

  // Brute force approach for getting all data
  // creating a dynamically funtion for getting all data
  // step 1 @getting how many initials
  let getInitialsCount = 0;
  for (let i = 0; i < calendarData.length; i++) {
    if (calendarData[i].day != 1) {
      break;
    }
    getInitialsCount++;
  }

  // step 2 @creating object then push in array @using IIFE function for self call
  function getAllCalendarData() {
    // total Day Wise data
    let DayWiseData1 = [];
    let k = 0;
    for (let i = 0; i < calendarData.length; i++) {
      // our main object
      const Sorting: DayWise = {
        Currentday: calendarData[i].day,
        slots: [],
      };

      for (let j = 0; j < getInitialsCount; j++) {
        const checkobj: slot = {
          // time: getInitials(calendarData[j]?.start_time), //1970-01-01T06:00:00.000Z => return =>06
          time: getInitials(calendarData[k]?.start_time), //1970-01-01T06:00:00.000Z => return =>06
          initials: calendarData[k]?.presenter_initials,
          uniqueId: calendarData[k]?.id,
        };
        Sorting.slots.push(checkobj);
        k++;
      }
      i = i + getInitialsCount - 1;
      // i = i + 12;
      DayWiseData1.push(Sorting);
    }

    setDayWiseData(DayWiseData1);
  }

  console.time('answer time');
  //getAllCalendarData();
  console.timeEnd('answer time');

  // handle fetch
  const handleFetchInitials = () => {
    queryClient.invalidateQueries('user');
  };

  // optimize code

  interface Slot {
    time: string;
    initials: string;
    uniqueId: number;
  }

  // checking data
  useEffect(() => {
    if (formValues.month === '' && formValues.year === '2023') {
      // alert('getCalendarData(2023, 7);');
      getCalendarData(2023, 7);
    }
  }, []);

  // paresh sir code
  useEffect(() => {
    // alert('getAllCalendarData();');
    getAllCalendarData();
  }, [calendarData, formValues]);

  // using react query
  // using react query
  const { isLoading, error, data, refetch } = useQuery(
    'presenterData',
    fetchPresenter
  );
  // const { isLoading, error, data } = useQuery({
  //   queryKey: ['presenterData'],
  //   queryFn: fetchPresenter,
  // });

  if (isLoading) {
    return <div>Loading....</div>;
  }

  // Type handler
  type SlotTypeHandler = {
    time: string;
    initials: string;
    uniqueId: number;
  };
  // take useState for value
  const InitialArray: string[] = [];
  function setOptionValue(SlotArray: any[], start_time: number) {
    const optionArray = [];
    for (let i = 0; i < SlotArray.length; i++) {
      if (parseInt(SlotArray[i].time) === getInitials2(start_time)) {
        if (SlotArray[i].initials != null) {
          optionArray.push(SlotArray[i].initials);
          if (!InitialArray.includes(SlotArray[i].initials)) {
            InitialArray.push(SlotArray[i].initials);
          }
          break;
        }
      }
    }
    if (optionArray.length != 0) {
      return <option>{optionArray[0]}</option>;
    }
    return <option>⮟</option>;
  }

  // this code give current date for show scheduled section page
  const currentDate = new Date();
  const currentDay = currentDate.getDate();

  return (
    <>
      <div className="px-2">
        <div className="flex flex-col">
          <div className="inline-block min-w-full py-6 rounded-lg shadow-xl">
            <table
              className="min-w-full text-sm font-light text-left"
              id="tableId"
            >
              <thead className="font-medium border-b dar">
                <tr className="bg-[#c1a3e1]">
                  <th scope="col" className="px-1 py-4"></th>
                  {storeTotalDays.map((datedata, i) => (
                    <th key={i} scope="col" className="px-1 py-4">
                      {datedata}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {startTime &&
                  startTime.map((Time) => (
                    <tr
                      key={Time.id}
                      className="transition duration-300 ease-in-out border-b hover:bg-neutral-100"
                    >
                      <td className="px-1 py-4 font-medium whitespace-nowrap">
                        {Time.start_time && getInitials2(Time.start_time)}:00{' '}
                        {getInitials2(Time.start_time) < 12 ? 'Am' : 'Pm'}
                      </td>

                      {/* {pathname === "/presenter_rota" ? "true" : "false"} */}
                      {pathname === '/show_schedule'
                        ? DayWiseData &&
                          DayWiseData.slice(0, new Date().getDate()).map(
                            (item, i) => (
                              <td key={i} className="py-3 whitespace-nowrap">
                                <select
                                  className="outline-none appearance-none"
                                  id="singleSelection"
                                  data-te-select-init
                                  onChange={(e) => {
                                    // getCalendarData();
                                    const data: updateInitialsValue = {
                                      userId: getUniqueId({
                                        getSlot: item.slots,
                                        InitialTime: getInitials2(
                                          Time.start_time
                                        ),
                                      }),
                                      Initials: e.target.value,
                                    };
                                    updateInitials(data);
                                    CalendardataByFilter(2024, 13);
                                  }}
                                >
                                  {/*  conditional Rendering of option tag... */}
                                  {setOptionValue(item.slots, Time.start_time)}
                                  {/* <option>⮟</option> */}
                                  {isAdmin &&
                                    dataa.map((singleData) => (
                                      <option
                                        key={singleData.userid}
                                        value={singleData.initials}
                                      >
                                        {singleData.initials}
                                      </option>
                                    ))}
                                  {/* {flag &&
                                    dataa.map((singleData) => (
                                      <option
                                        key={singleData.userid}
                                        value={singleData.initials}
                                      >
                                        {singleData.initials}
                                      </option>
                                    ))} */}
                                </select>
                              </td>
                            )
                          )
                        : DayWiseData &&
                          DayWiseData.map((item, i) => (
                            <>
                              <td key={i} className="py-3 whitespace-nowrap">
                                <select
                                  className="outline-none appearance-none"
                                  id="singleSelection"
                                  data-te-select-init
                                  onChange={(e) => {
                                    const data: updateInitialsValue = {
                                      userId: getUniqueId({
                                        getSlot: item.slots,
                                        InitialTime: getInitials2(
                                          Time.start_time
                                        ),
                                      }),
                                      Initials: e.target.value,
                                    };
                                    updateInitials(data);
                                    // handleFetchInitials()

                                    // this help to resolve memory lekage
                                    if (formValues.month != '') {
                                      setTimeout(() => {
                                        CalendardataByFilter(2023, 11);
                                      }, 1000);
                                      setTimeout(() => {
                                        CalendardataByFilter(
                                          parseInt(formValues.year),
                                          parseInt(formValues.month)
                                        );
                                      }, 2000);
                                    }

                                    // handleClick();
                                  }}
                                >
                                  {/*  conditional Rendering of option tag... */}
                                  {setOptionValue(item.slots, Time.start_time)}
                                  {/* <option>⮟</option> */}

                                  {isAdmin &&
                                    flag &&
                                    dataa.map((singleData) => (
                                      <option
                                        key={singleData.userid}
                                        value={singleData.initials}
                                      >
                                        {singleData.initials}
                                      </option>
                                    ))}
                                </select>
                              </td>
                            </>
                          ))}
                    </tr>
                  ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="flex justify-end my-5">
          <button
            type="submit"
            className="text-white bg-red rounded-[5px] mx-5 p-2"
            onClick={() => {
              // CalendardataByFilter(
              //   parseInt(formValues.year),
              //   parseInt(formValues.month)
              // );
              toast.success('Successfully Save!');
            }}
            style={{
              backgroundColor: '#8C2EE8',
            }}
          >
            Save Changes
          </button>
          <button
            type="submit"
            className="text-black border-[1px] border-solid border-black bg-white rounded-[5px] p-2"
            onClick={() => {
              // getCalendarData();
              setFlag(false);
              setTimeout(() => {
                exportToExcel();
              }, 1000);
              setTimeout(() => {
                setFlag(true);
              }, 2000);
            }}
          >
            Print sheet
          </button>
        </div>
      </div>
    </>
  );
};

// To fetch an updated value from a database using an ID in Next.js with Prisma

export default TableData;
