import { useQuery } from '@tanstack/react-query';
import { useMemo, useState } from 'react';
import {
  listCampusAttendanceConfigs,
  listCampusAttendanceSummaries,
  saveCampusAttendanceConfig,
  saveCampusAttendanceSummary,
} from '@/shared/api/campusAttendance';
import { useCampusCatalog } from '@/business/campuses/hooks';
import { CAMPUS_ATTENDANCE_QUERY_KEYS } from '@/shared/constants/campusAttendance';
import { findCampusByNameOrCode } from '@/shared/constants/campusDisplay';
import { UI_FEEDBACK_CLEAR_DELAY_MS } from '@/shared/constants/ui';
import type {
  CampusAttendanceCampusKey,
  CampusAttendanceListFilter,
} from '@/shared/types/campusAttendance';
import {
  toCampusAttendanceConfigViewModel,
  toCampusAttendanceSummaryMutationDto,
  toCampusAttendanceSummaryViewModel,
} from '@/business/campus-attendance/mappers';
import {
  buildAttendanceEntryInput,
  buildCampusAttendanceStats,
  buildOverallAttendanceStats,
  getToday,
  getTodayPercentage,
  getWeeklyAverage,
  getWeekEnd,
  getWeekStart,
} from '@/business/campus-attendance/selectors';
import {
  CAMPUS_ATTENDANCE_PRINT_POPUP_BLOCKED_MESSAGE,
  openCampusAttendancePrintReport,
} from '@/business/campus-attendance/printReport';
import type {
  CampusAttendanceEntryDraft,
  CampusAttendanceEntryInput,
} from '@/business/campus-attendance/types';
import type { CampusId, UserRole } from '@/shared/types/app';
import { getOptionalErrorMessage } from '@/shared/errors/errorMessages';
import { mapApiListRows } from '@/shared/business/apiListRows';
import { useInvalidatingMutation } from '@/shared/business/queryMutations';

const EMPTY_CONFIGS: ReturnType<typeof toCampusAttendanceConfigViewModel>[] = [];
const EMPTY_SUMMARIES: ReturnType<typeof toCampusAttendanceSummaryViewModel>[] = [];

export function useCampusAttendanceConfigs(campusKey?: CampusAttendanceCampusKey, enabled = true) {
  return useQuery({
    queryKey: [CAMPUS_ATTENDANCE_QUERY_KEYS.configs, campusKey],
    enabled,
    queryFn: () => mapApiListRows(
      listCampusAttendanceConfigs(campusKey ? { campusKey } : undefined),
      toCampusAttendanceConfigViewModel,
    ),
  });
}

export function useSaveCampusAttendanceConfig() {
  return useInvalidatingMutation({
    mutationFn: (input: { campusKey: CampusAttendanceCampusKey; attendanceLink: string | null }) => (
      saveCampusAttendanceConfig(input.campusKey, { attendance_link: input.attendanceLink })
    ),
    invalidateQueryKey: [CAMPUS_ATTENDANCE_QUERY_KEYS.configs],
  });
}

export function useCampusAttendanceSummaries(filter?: CampusAttendanceListFilter, enabled = true) {
  return useQuery({
    queryKey: [CAMPUS_ATTENDANCE_QUERY_KEYS.summaries, filter],
    enabled,
    queryFn: () => mapApiListRows(
      listCampusAttendanceSummaries(filter),
      toCampusAttendanceSummaryViewModel,
    ),
  });
}

export function useSaveCampusAttendanceSummary() {
  return useInvalidatingMutation({
    mutationFn: (input: CampusAttendanceEntryInput) => saveCampusAttendanceSummary(
      input.campusId,
      input.date,
      toCampusAttendanceSummaryMutationDto(input),
    ),
    invalidateQueryKey: [CAMPUS_ATTENDANCE_QUERY_KEYS.summaries],
  });
}

type UseCampusAttendancePageInput = {
  readonly userRole: UserRole;
  readonly userCampus: string;
  readonly userName: string;
};

const emptyEntryDraft = (date: string): CampusAttendanceEntryDraft => ({
  date,
  enrolled: '',
  present: '',
  absent: '',
  tardy: '',
  notes: '',
});

export function useCampusAttendancePage({
  userRole,
  userCampus,
  userName,
}: UseCampusAttendancePageInput) {
  const roleAccess = {
    isSuperintendent: userRole === 'superintendent',
    isDirector: userRole === 'director',
    isOfficeManager: userRole === 'office_manager',
    canSeeAllCampuses: userRole === 'superintendent',
    canEnterData: userRole === 'office_manager',
    canPrint: userRole === 'superintendent' || userRole === 'director' || userRole === 'office_manager',
  };
  const campusCatalog = useCampusCatalog();
  const campusInfo = findCampusByNameOrCode(campusCatalog.campuses, userCampus);
  const campusId = campusInfo?.id ?? null;
  const today = getToday();
  const weekStart = getWeekStart(new Date());
  const weekEnd = getWeekEnd(new Date());

  const hasCampusScope = roleAccess.canSeeAllCampuses || Boolean(campusId);
  const configsQuery = useCampusAttendanceConfigs(
    roleAccess.canSeeAllCampuses || !campusId ? undefined : campusId,
    hasCampusScope,
  );
  const summariesQuery = useCampusAttendanceSummaries(
    roleAccess.canSeeAllCampuses || !campusId ? undefined : { campusKey: campusId },
    hasCampusScope,
  );
  const saveConfigMutation = useSaveCampusAttendanceConfig();
  const saveSummaryMutation = useSaveCampusAttendanceSummary();

  const configs = configsQuery.data ?? EMPTY_CONFIGS;
  const attendanceData = summariesQuery.data ?? EMPTY_SUMMARIES;
  const loading = campusCatalog.isLoading || configsQuery.isLoading || summariesQuery.isLoading;
  const saving = saveConfigMutation.isPending || saveSummaryMutation.isPending;
  const loadError = campusCatalog.error ?? configsQuery.error ?? summariesQuery.error;
  const saveError = saveConfigMutation.error ?? saveSummaryMutation.error;
  const [successMessage, setSuccessMessage] = useState('');
  const [printError, setPrintError] = useState<string | null>(null);
  const errorMessage = printError ?? getOptionalErrorMessage(loadError ?? saveError);
  const [editingLink, setEditingLink] = useState<CampusId | null>(null);
  const [linkValue, setLinkValue] = useState('');
  const [showEntryForm, setShowEntryForm] = useState(false);
  const [expandedCampus, setExpandedCampus] = useState<CampusId | null>(null);
  const [entryDraft, setEntryDraft] = useState<CampusAttendanceEntryDraft>(() => emptyEntryDraft(today));
  const [entryError, setEntryError] = useState<string | null>(null);

  const campusStats = useMemo(
    () => buildCampusAttendanceStats(campusCatalog.campuses, configs, attendanceData, today, weekStart, weekEnd),
    [attendanceData, campusCatalog.campuses, configs, today, weekEnd, weekStart],
  );
  const overallStats = useMemo(
    () => buildOverallAttendanceStats(attendanceData, today, weekStart, weekEnd),
    [attendanceData, today, weekEnd, weekStart],
  );
  const myCampusConfig = campusId ? configs.find((config) => config.campus_id === campusId) : undefined;
  const myCampusData = campusId ? attendanceData.filter((record) => record.campus_id === campusId) : [];
  const myTodayPct = campusId ? getTodayPercentage(attendanceData, campusId, today) : null;
  const myWeekAvg = campusId ? getWeeklyAverage(attendanceData, campusId, weekStart, weekEnd) : null;

  const showSuccess = (message: string) => {
    setPrintError(null);
    setSuccessMessage(message);
    window.setTimeout(() => setSuccessMessage(''), UI_FEEDBACK_CLEAR_DELAY_MS);
  };

  const updateEntryDraft = (patch: Partial<CampusAttendanceEntryDraft>) => {
    setEntryDraft((currentDraft) => ({ ...currentDraft, ...patch }));
    setEntryError(null);
  };

  const handleSaveLink = async (targetCampusId: CampusId) => {
    setPrintError(null);
    await saveConfigMutation.mutateAsync({
      campusKey: targetCampusId,
      attendanceLink: linkValue.trim() || null,
    });
    showSuccess('Link saved successfully!');
    setEditingLink(null);
  };

  const handleSubmitEntry = async () => {
    setPrintError(null);

    if (!campusId) {
      setEntryError('Campus is unavailable. Refresh the campus catalog before saving attendance.');
      return;
    }

    const input = buildAttendanceEntryInput(entryDraft, campusId);

    if (!input) {
      setEntryError('Enter enrolled, present, and absent counts before saving.');
      return;
    }

    await saveSummaryMutation.mutateAsync(input);
    showSuccess('Attendance data saved!');
    setShowEntryForm(false);
    setEntryDraft(emptyEntryDraft(today));
  };

  const handlePrint = () => {
    const campusesToPrint = roleAccess.canSeeAllCampuses
      ? campusStats
      : campusStats.filter((campus) => campus.id === campusId);
    const reportTitle = roleAccess.canSeeAllCampuses
      ? 'All Campuses Attendance Report'
      : `${campusInfo?.fullName || userCampus} Attendance Report`;
    const printTodayRecords = roleAccess.canSeeAllCampuses
      ? overallStats.todayRecords
      : attendanceData.filter((record) => record.campus_id === campusId && record.date === today);
    const printWeekRecords = roleAccess.canSeeAllCampuses
      ? overallStats.weekRecords
      : attendanceData.filter((record) => record.campus_id === campusId && record.date >= weekStart && record.date <= weekEnd);

    const printResult = openCampusAttendancePrintReport({
      input: {
        reportTitle,
        generatedByName: userName,
        generatedByRole: `${userRole.charAt(0).toUpperCase()}${userRole.slice(1)}`,
        today,
        weekStart,
        campusesToPrint,
        printTodayRecords,
        printWeekRecords,
      },
    });

    if (!printResult.ok) {
      setPrintError(CAMPUS_ATTENDANCE_PRINT_POPUP_BLOCKED_MESSAGE);
      return;
    }

    setPrintError(null);
  };

  return {
    state: {
      roleAccess,
      campusInfo,
      campusId,
      today,
      weekStart,
      weekEnd,
      configs,
      attendanceData,
      loading,
      saving,
      errorMessage,
      successMessage,
      editingLink,
      linkValue,
      showEntryForm,
      expandedCampus,
      entryDraft,
      entryError,
      campusStats,
      overallStats,
      myCampusConfig,
      myCampusData,
      myTodayPct,
      myWeekAvg,
      userCampus,
    },
    actions: {
      setEditingLink,
      setLinkValue,
      setShowEntryForm,
      setExpandedCampus,
      updateEntryDraft,
      handleSaveLink,
      handleSubmitEntry,
      handlePrint,
    },
  };
}
