// 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 { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
import dayjs from 'dayjs';
// 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";

import { utils, write } from 'xlsx';
import { saveAs } from 'file-saver';


interface IProps {
  initialItems: Publisher[];
}

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

  const [filter, setFilter] = useState("");
  const [showZeroShiftsOnly, setShowZeroShiftsOnly] = useState(false);
  const [selectedDate, setSelectedDate] = useState<dayjs.Dayjs | null>(null);
  const [filterIsImported, setFilterIsImported] = useState({
    checked: false,
    indeterminate: true,
  });

  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])];

    // Zero shifts (inactive) and date filter
    if (showZeroShiftsOnly && selectedDate) {
      filteredPublishers = publishers.filter(publisher => {
        // If no assignments at all, include in results
        if (publisher.assignments.length === 0) return true;

        // Only include publishers who don't have any assignments after the selected date
        return !publisher.assignments.some(assignment => {
          const shiftDate = dayjs(assignment.shift.startTime);
          return shiftDate.isAfter(selectedDate);
        });
      });
    } else if (showZeroShiftsOnly) {
      // If checkbox is checked but no date selected, show publishers with no assignments
      filteredPublishers = publishers.filter(publisher => publisher.assignments.length === 0);
    }

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

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


  // Separate effect to handle date reset when checkbox is unchecked
  useEffect(() => {
    if (!showZeroShiftsOnly) {
      setSelectedDate(null);
    }
  }, [showZeroShiftsOnly]);

  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);
      }
    }
  };

  const exportPublishers = async () => {
    try {
      const response = await axiosInstance.get('/api/?action=exportPublishersExcel', { responseType: 'arraybuffer' });

      // Get filename from Content-Disposition header
      const contentDisposition = response.headers['content-disposition'];
      let filename = 'publishers.xlsx'; // default fallback
      if (contentDisposition) {
        const filenameMatch = contentDisposition.match(/filename=(.*?)(;|$)/);
        if (filenameMatch) {
          filename = decodeURI(filenameMatch[1]);
        }
      }

      const blob = new Blob([response.data], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(url); // Clean up
    } catch (error) {
      console.error(JSON.stringify(error));
      toast.error("Грешка при експорт на данни");
    }
  }


  // Add this function to your component

  const exportFilteredPublishers = () => {
    try {
      // Calculate total statistics
      const formatDateBG = (date) => {
        if (!date) return '';
        return new Date(date).toLocaleDateString('bg-BG', {
          day: '2-digit',
          month: '2-digit',
          year: 'numeric'
        });
      };
      const stats = {
        totalPublishers: shownPubs.length,
        activePublishers: shownPubs.filter(p => p.isActive).length,
        trainedPublishers: shownPubs.filter(p => p.isTrained).length,
        totalAssignments: shownPubs.reduce((sum, p) => sum + p.assignments.length, 0),
        totalAvailabilities: shownPubs.reduce((sum, p) => sum + p.availabilities.length, 0),
        subscribedToReminders: shownPubs.filter(p => p.isSubscribedToReminders).length,
        subscribedToCoverMe: shownPubs.filter(p => p.isSubscribedToCoverMe).length,
        familyHeads: shownPubs.filter(p => p.familyHeadId).length,
        avgAssignments: (shownPubs.reduce((sum, p) => sum + p.assignments.length, 0) / shownPubs.length).toFixed(2),
        avgAvailabilities: (shownPubs.reduce((sum, p) => sum + p.availabilities.length, 0) / shownPubs.length).toFixed(2)
      };

      // Format the publishers data for Excel
      const publishersData = shownPubs.map(publisher => ({
        'First Name': publisher.firstName,
        'Last Name': publisher.lastName,
        'Email': publisher.email,
        'Phone': publisher.phone || '',
        'Active': publisher.isActive ? 'Yes' : 'No',
        'Trained': publisher.isTrained ? 'Yes' : 'No',
        'Role': publisher.role ? 'Yes' : 'No',
        'Last Login': publisher.lastLogin ? formatDateBG(publisher.lastLogin) : 'Never',
        'Subscribed to Reminders': publisher.isSubscribedToReminders ? 'Yes' : 'No',
        'Subscribed to CoverMe': publisher.isSubscribedToCoverMe ? 'Yes' : 'No',
        'Family Head ID': publisher.familyHeadId || '',
        'Assignments Count': publisher.assignments.length,
        'Availabilities Count': publisher.availabilities.length,
        'Last Assignment': publisher.assignments.length > 0
          ? formatDateBG(Math.max(...publisher.assignments.map(a => new Date(a.shift.startTime)))) : 'Never',
      }));

      // Create workbook
      const wb = utils.book_new();

      // Create publishers worksheet
      const ws_data = utils.json_to_sheet(publishersData);

      // Set column widths for publishers sheet
      const colWidths = [
        { wch: 15 }, // First Name
        { wch: 15 }, // Last Name
        { wch: 30 }, // Email
        { wch: 15 }, // Phone
        { wch: 10 }, // Active
        { wch: 10 }, // Trained
        { wch: 10 }, // Role
        { wch: 15 }, // Last Login
        { wch: 20 }, // Subscribed to Reminders
        { wch: 20 }, // Subscribed to CoverMe
        { wch: 15 }, // Family Head ID
        { wch: 15 }, // Assignments Count
        { wch: 15 }, // Availabilities Count
        { wch: 15 }, // Last Assignment
      ];
      ws_data['!cols'] = colWidths;

      // Create summary worksheet
      const summary_data = [
        ['Summary Statistics', ''],
        ['Total Publishers', stats.totalPublishers],
        ['Active Publishers', stats.activePublishers],
        ['Trained Publishers', stats.trainedPublishers],
        ['Total Assignments', stats.totalAssignments],
        ['Average Assignments per Publisher', stats.avgAssignments],
        ['Total Availabilities', stats.totalAvailabilities],
        ['Average Availabilities per Publisher', stats.avgAvailabilities],
        ['Subscribed to Reminders', stats.subscribedToReminders],
        ['Subscribed to CoverMe', stats.subscribedToCoverMe],
        ['Family Heads', stats.familyHeads],
        ['Export Date', formatDateBG(new Date())],
        [''],
        ['Applied Filters:', ''],
        ['Name Filter', filter || 'None'],
        ['Zero Shifts Only', showZeroShiftsOnly ? 'Yes' : 'No'],
        ['No Training', flterNoTraining ? 'Yes' : 'No'],
      ];

      const ws_summary = utils.aoa_to_sheet(summary_data);

      // Set column widths for summary sheet
      ws_summary['!cols'] = [
        { wch: 30 }, // Label
        { wch: 15 }, // Value
      ];

      // Add sheets to workbook
      utils.book_append_sheet(wb, ws_summary, 'Summary');
      utils.book_append_sheet(wb, ws_data, 'Publishers');

      // Generate buffer
      const excelBuffer = write(wb, { bookType: 'xlsx', type: 'array' });

      // Create blob and save file
      const blob = new Blob([excelBuffer], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      });

      // Generate filename with current date and filter indication
      const date = formatDateBG(new Date()).replace(/\./g, '-');
      const isFiltered = filter || showZeroShiftsOnly || flterNoTraining;
      const filename = `publishers-${isFiltered ? 'filtered-' : ''}${date}.xlsx`;

      saveAs(blob, filename);

      toast.success("Експортът е успешен");
    } catch (error) {
      console.error('Export error:', error);
      toast.error("Грешка при експорт на данни");
    }
  };

  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>
            {/* export by calling excel helper .ExportPublishersToExcel() */}
            {/* <div className="flex justify-center m-4">
              <button className="button m-2 btn btn-primary" onClick={exportPublishers}>Export to Excel</button>
            </div> */}
            <div className="flex justify-center m-4">
              <button className="button m-2 btn btn-primary" onClick={exportPublishers}>
                Export All XLSX
              </button>
              <button className="button m-2 btn btn-primary" onClick={exportFilteredPublishers}>
                Export Filtered XLSX
              </button>
            </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>
              {showZeroShiftsOnly && (
                <div className="flex items-center space-x-2 ml-2">
                  <span className="whitespace-nowrap">след:</span>
                  <DatePicker
                    value={selectedDate}
                    onChange={(newDate) => setSelectedDate(newDate)}
                    slotProps={{
                      textField: {
                        size: "small",
                        sx: {
                          width: '140px',
                          '& .MuiInputBase-input': {
                            padding: '4px 8px',
                            fontSize: '0.875rem'
                          }
                        }
                      },
                      mobileWrapper: {
                        sx: {
                          '& .MuiPickersLayout-root': {
                            minWidth: 'unset'
                          }
                        }
                      }
                    }}
                    format="DD.MM.YYYY"
                    className="min-w-[120px]"
                  />
                </div>
              )}

              <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,
      lastLogin: true,
      phone: true,
      isSubscribedToReminders: true,
      isSubscribedToCoverMe: true,
      familyHeadId: true,
      role: true,
      assignments: {
        select: {
          shift: {
            select: {
              startTime: true,
            },
          },
        },
      },
      availabilities: {
        select: {
          startTime: true,
        },
      },
    }
  });
  publishers = JSON.parse(JSON.stringify(publishers));


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

