// Next.js page to show all locations in the database with a link to the location page
import { useSession } from "next-auth/react";
import { useEffect, useState, useRef, use } from "react";
// import { getSession } from 'next-auth/client'
// import { NextAuth } from 'next-auth/client'
import { Publisher, UserRole } from "@prisma/client";
import Layout from "../../../components/layout";
import PublisherCard from "../../../components/publisher/PublisherCard";
import axiosInstance from "../../../src/axiosSecure";
import axiosServer from '../../../src/axiosServer';
const common = require("../../../src/helpers/common");
import toast from "react-hot-toast";

import { levenshteinEditDistance } from "levenshtein-edit-distance";
import ProtectedRoute from '../../../components/protectedRoute';
import ConfirmationModal from '../../../components/ConfirmationModal';
import { relative } from "path";
import { set } from "lodash";



interface IProps {
  initialItems: Publisher[];
}

function PublishersPage({ publishers = [] }: IProps) {
  const [shownPubs, setShownPubs] = useState(publishers);

  const [filter, setFilter] = useState("");
  const [showZeroShiftsOnly, setShowZeroShiftsOnly] = useState(false);
  const [filterIsImported, setFilterIsImported] = useState({
    checked: false,
    indeterminate: true,
  });

  // const cbRefFilterTraining = useRef<HTMLInputElement>(null);

  // const getCheckboxState = (currentState: boolean | null) => {
  //   if (currentState === true) return 'unchecked';
  //   if (currentState === false) return 'checked';
  //   return 'indeterminate';
  // };
  // const cbRefFilterTraining = useRef<HTMLInputElement>(null);
  // const [cbFilterTrainingState, setcbFilterTrainingState] = useState<boolean | null>(null);
  // useEffect(() => {
  //   if (cbRefFilterTraining.current) {
  //     cbRefFilterTraining.current.indeterminate = cbFilterTrainingState === null;
  //   }
  // }, [cbFilterTrainingState]);
  const [flterNoTraining, setFilterNoTraining] = useState(false);

  const [isDeleting, setIsDeleting] = useState(false);
  const [isModalOpenDeleteAllVisible, setIsModalOpenDeleteAllVisible] = useState(false);
  const [isModalOpenDeleteAllAvaillabilities, setIsModalOpenDeleteAllAvaillabilities] = useState(false);

  const handleDeleteAllVisible = async () => {
    setIsDeleting(true);

    for (const publisher of shownPubs) {
      try {
        await axiosInstance.delete(`/api/data/publishers/${publisher.id}`);
        setShownPubs(shownPubs.filter(p => p.id !== publisher.id));
      } catch (error) {
        console.log(JSON.stringify(error));
      }
    }

    setIsDeleting(false);
    setIsModalOpenDeleteAllVisible(false);
  };

  const handleDeleteAllAvailabilities = async () => {
    setIsDeleting(true);

    try {
      const today = new Date();
      const targetDate = new Date(today.setDate(today.getDate() - 35));
      await axiosInstance.post('/api/?action=deleteAllAvailabilities', { date: targetDate });
    } catch (error) {
      console.error(JSON.stringify(error)); // Log the error
    }

    setIsDeleting(false);
    setIsModalOpenDeleteAllAvaillabilities(false);
  };

  useEffect(() => {
    // const filteredPublishers = publishers.filter((publisher) => {
    //   return publisher.firstName.toLowerCase().includes(filter.toLowerCase())
    //     || publisher.lastName.toLowerCase().includes(filter.toLowerCase());
    // });

    //name filter
    let filteredPublishersByName = publishers
      .filter((publisher) => {
        const fullName = publisher.firstName.toLowerCase() + " " + publisher.lastName.toLowerCase();
        const distance = levenshteinEditDistance(fullName, filter.toLowerCase());
        const lenDiff = Math.max(fullName.length, filter.length) - Math.min(fullName.length, filter.length);

        let similarity;
        if (distance === 0) {
          similarity = 1; // Exact match
        } else {
          similarity = 1 - (distance - lenDiff) / distance;
        }
        //console.log("distance: " + distance + "; lenDiff: " + lenDiff + " similarity: " + similarity + "; " + fullName + " =? " + filter + "")
        return similarity >= 0.95;
      });

    // Email filter
    let filteredPublishersByEmail = publishers.filter(publisher =>
      publisher.email.toLowerCase().includes(filter.toLowerCase())
    );

    // Combine name and email filters, removing duplicates
    let filteredPublishers = [...new Set([...filteredPublishersByName, ...filteredPublishersByEmail])];

    // inactive publishers filter
    filteredPublishers = showZeroShiftsOnly
      ? filteredPublishers.filter(p => p.assignments.length === 0)
      : filteredPublishers;

    // trained filter
    if (flterNoTraining) {
      filteredPublishers = filteredPublishers.filter(p => p.isTrained === false);
    }

    setShownPubs(filteredPublishers);
  }, [filter, showZeroShiftsOnly, flterNoTraining]);



  const renderPublishers = () => {
    if (shownPubs.length === 0) {
      return (
        <div className="flex justify-center">
          <button
            className="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
            onClick={() => {
              setFilter("");  // Assuming setFilter directly updates the filter state
              if (typeof handleFilterChange === 'function') {
                handleFilterChange({ target: { value: "" } }); // If needed for additional logic
              }
            }}
          >
            Clear filters
          </button>
        </div>
      );
    } else {
      return shownPubs.map((publisher) => (
        <PublisherCard key={publisher.id} publisher={publisher} />
      ));
    }
  };

  const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value, type, checked } = event.target;

    // setFilter(event.target.value);
    if (type === 'text') {
      setFilter(value);
    } else if (type === 'checkbox') {
      if (name === 'filterIsImported') {
        setFilterIsImported({ checked, indeterminate: false });
      }
      if (name === 'filterTrained') {
        // const nextState = cbFilterTrainingState === false ? null : cbFilterTrainingState === null ? true : false;
        // setcbFilterTrainingState(nextState);
        setFilterNoTraining(checked);
      }
    }
  };

  return (
    <Layout>
      <ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]}>
        <div className="mx-auto ">
          <div className="flex items-center justify-center space-x-4 m-4">
            <div className="flex justify-center m-4">
              <a href="/cart/publishers/new" className="btn">Добави вестител</a>
            </div>

            <button className="button m-2 btn btn-danger" onClick={() => setIsModalOpenDeleteAllVisible(true)} disabled={isDeleting}>
              {isDeleting ? "Изтриване..." : "Изтрий показаните вестители"}
            </button>
            <ConfirmationModal
              isOpen={isModalOpenDeleteAllVisible}
              onClose={() => setIsModalOpenDeleteAllVisible(false)}
              onConfirm={handleDeleteAllVisible}
              message="Сигурни ли сте, че искате да изтриете всички показани в момента вестители?"
            />

            <button className="button m-2 btn btn-danger" onClick={() => setIsModalOpenDeleteAllAvaillabilities(true)} disabled={isDeleting}>
              {isDeleting ? "Изтриване..." : "Изтрий ВСИЧКИ предпочитания"}
            </button>
            <ConfirmationModal
              isOpen={isModalOpenDeleteAllAvaillabilities}
              onClose={() => setIsModalOpenDeleteAllAvaillabilities(false)}
              onConfirm={handleDeleteAllAvailabilities}
              message="Сигурни ли сте, че искате да изтриете предпочитанията на ВСИЧКИ вестители?"
            />

            <div className="flex justify-center m-4">
              <a href="/cart/publishers/import" className="btn">Import publishers</a>
            </div>
          </div>

          <div className="z-60 sticky top-0" style={{ zIndex: 60, position: relative }}>
            <div name="filters" className="flex items-center justify-center space-x-4 m-4 bg-gray-100 p-2" >
              <label htmlFor="filter">Filter:</label>
              <input type="text" id="filter" name="filter" value={filter} onChange={handleFilterChange}
                className="border border-gray-300 rounded-md px-2 py-1"
              />

              <label htmlFor="zeroShiftsOnly" className="ml-4 inline-flex items-center">
                <input type="checkbox" id="zeroShiftsOnly" checked={showZeroShiftsOnly}
                  onChange={e => setShowZeroShiftsOnly(e.target.checked)}
                  className="form-checkbox text-indigo-600"
                />
                <span className="ml-2">само без смени</span>
              </label>

              <label htmlFor="filterTrained" className="ml-4 inline-flex items-center">
                <input type="checkbox" id="filterTrained" name="filterTrained"
                  // support intermediate state if checkboxState is null
                  checked={flterNoTraining}
                  onChange={handleFilterChange}
                  className="form-checkbox text-indigo-600"
                />
                <span className="ml-2">без обучение</span>
              </label>

              <span id="filter-info" className="ml-4">{shownPubs.length} от {publishers.length} вестителя</span>
            </div>
          </div>
          <div className="grid gap-4 grid-cols-1 md:grid-cols-4 z-0">
            {renderPublishers()}
          </div>
        </div>
      </ProtectedRoute>
    </Layout>
  );
}

export default PublishersPage;

//import { set } from "date-fns";

export const getServerSideProps = async (context) => {
  // const axios = await axiosServer(context);
  // //ToDo: refactor all axios calls to use axiosInstance and this URL
  // const { data: publishers } = await axios.get('/api/data/publishers?select=id,firstName,lastName,email,isActive,isTrained,isImported,assignments.shift.startTime,availabilities.startTime&dev=fromuseefect');
  //use prisma instead of axios
  const prisma = common.getPrismaClient();
  let publishers = await prisma.publisher.findMany({
    select: {
      id: true,
      firstName: true,
      lastName: true,
      email: true,
      isActive: true,
      isTrained: true,
      isImported: true,
      assignments: {
        select: {
          shift: {
            select: {
              startTime: true,
            },
          },
        },
      },
      availabilities: {
        select: {
          startTime: true,
        },
      },
    }
  });
  publishers = JSON.parse(JSON.stringify(publishers));


  return {
    props: {
      publishers,
    },
  };
};

