import { create } from 'zustand';
import type { AttendanceRecord, AttendanceStats } from '@/types';
import { format } from 'date-fns';
import { attendanceApi } from '@/lib/apiClient';

interface AttendanceState {
  records: AttendanceRecord[];
  selectedDate: string;
  selectedBatch: number;
  stats: AttendanceStats;
  isMarking: boolean;
  isHoliday: boolean;
  holidayReason: string;
  markAttendance: (records: AttendanceRecord[]) => Promise<void>;
  markHoliday: (date: string, batchId: number, reason?: string) => Promise<void>;
  removeHoliday: (date: string, batchId: number) => void;
  fetchAttendance: (date: string, batchId: number) => Promise<void>;
  toggleStudentStatus: (studentId: number) => void;
  setSelectedDate: (date: string) => void;
  setSelectedBatch: (batchId: number) => void;
}

const today = format(new Date(), 'yyyy-MM-dd');

function mapApiRecord(r: Record<string, unknown>): AttendanceRecord {
  return {
    studentId: Number(r.student_id ?? r.studentId ?? 0),
    batchId: Number(r.batch_id ?? r.batchId ?? 1),
    date: String(r.date ?? ''),
    status: (r.status ?? 'absent') as 'present' | 'absent' | 'holiday',
  };
}

export const useAttendanceStore = create<AttendanceState>((set, get) => ({
  records: [],
  selectedDate: today,
  selectedBatch: 1,
  stats: { total: 0, present: 0, absent: 0, holiday: 0, percentage: 0 },
  isMarking: false,
  isHoliday: false,
  holidayReason: '',

  markAttendance: async (newRecords) => {
    set({ isMarking: true });
    try {
      for (const rec of newRecords) {
        await attendanceApi.mark({
          studentId: rec.studentId,
          date: rec.date,
          status: rec.status,
          markedBy: 1,
        });
      }
    } catch { /* offline */ }

    const state = get();
    const otherRecords = state.records.filter(r =>
      !(newRecords.some(nr => nr.studentId === r.studentId && nr.date === r.date))
    );
    const allRecords = [...otherRecords, ...newRecords];
    const filtered = allRecords.filter(r => r.date === state.selectedDate && r.batchId === state.selectedBatch);
    const present = filtered.filter(r => r.status === 'present').length;
    const holiday = filtered.filter(r => r.status === 'holiday').length;

    set({
      records: allRecords,
      isHoliday: holiday > 0,
      stats: { total: filtered.length, present, absent: filtered.length - present - holiday, holiday, percentage: filtered.length ? Math.round((present / filtered.length) * 100) : 0 },
      isMarking: false,
    });
  },

  markHoliday: async (date, batchId, reason = 'Holiday') => {
    try {
      await attendanceApi.mark({
        studentId: 0, // 0 = holiday marker for all
        date,
        status: 'holiday',
        batchId,
        markedBy: 1,
        reason,
      });
    } catch { /* offline */ }

    set(state => {
      const updated = state.records.map(r =>
        r.date === date && r.batchId === batchId
          ? { ...r, status: 'holiday' as const }
          : r
      );
      const filtered = updated.filter(r => r.date === date && r.batchId === batchId);
      return {
        records: updated,
        isHoliday: true,
        holidayReason: reason,
        stats: { total: filtered.length, present: 0, absent: 0, holiday: filtered.length, percentage: 0 },
      };
    });
  },

  removeHoliday: (date, batchId) => {
    set(state => {
      const updated = state.records.map(r =>
        r.date === date && r.batchId === batchId
          ? { ...r, status: 'absent' as const }
          : r
      );
      const filtered = updated.filter(r => r.date === date && r.batchId === batchId);
      const present = filtered.filter(r => r.status === 'present').length;
      return {
        records: updated,
        isHoliday: false,
        holidayReason: '',
        stats: { total: filtered.length, present, absent: filtered.length - present, holiday: 0, percentage: filtered.length ? Math.round((present / filtered.length) * 100) : 0 },
      };
    });
  },

  fetchAttendance: async (date, batchId) => {
    try {
      const data = await attendanceApi.getByDate(date);
      if (Array.isArray(data)) {
        const mapped = data.map(mapApiRecord);
        const state = get();
        const otherRecords = state.records.filter(r => r.date !== date);
        const allRecords = [...otherRecords, ...mapped];
        const filtered = allRecords.filter(r => r.date === date && r.batchId === batchId);
        const present = filtered.filter(r => r.status === 'present').length;
        const holiday = filtered.filter(r => r.status === 'holiday').length;
        set({
          records: allRecords,
          selectedDate: date,
          selectedBatch: batchId,
          isHoliday: holiday > 0,
          stats: { total: filtered.length, present, absent: filtered.length - present - holiday, holiday, percentage: filtered.length ? Math.round((present / filtered.length) * 100) : 0 },
        });
        return;
      }
    } catch { /* offline */ }
    set({ records: [], selectedDate: date, selectedBatch: batchId, isHoliday: false, stats: { total: 0, present: 0, absent: 0, holiday: 0, percentage: 0 } });
  },

  toggleStudentStatus: (studentId) => {
    set(state => {
      const updated = state.records.map(r =>
        r.studentId === studentId && r.date === state.selectedDate
          ? { ...r, status: r.status === 'present' ? 'absent' as const : 'present' as const }
          : r
      );
      const filtered = updated.filter(r => r.date === state.selectedDate && r.batchId === state.selectedBatch);
      const present = filtered.filter(r => r.status === 'present').length;
      const holiday = filtered.filter(r => r.status === 'holiday').length;
      return {
        records: updated,
        isHoliday: holiday > 0,
        stats: { total: filtered.length, present, absent: filtered.length - present - holiday, holiday, percentage: filtered.length ? Math.round((present / filtered.length) * 100) : 0 },
      };
    });
  },

  setSelectedDate: (date) => set({ selectedDate: date }),
  setSelectedBatch: (batchId) => set({ selectedBatch: batchId }),
}));
