import React, { createContext, useContext, useState, useEffect } from 'react';
import {
  User,
  Role,
  Course,
  StudentApplication,
  GradeItem,
  AttendanceRecord,
  FeePayment,
  StudyMaterial,
  Assignment,
  Message,
  CollegeEvent,
  NotificationItem,
} from '../types';
import {
  COLLEGE_INFO,
  INITIAL_COURSES,
  INITIAL_USERS,
  INITIAL_APPLICATIONS,
  INITIAL_GRADES,
  INITIAL_ATTENDANCE,
  INITIAL_FEES,
  INITIAL_STUDY_MATERIALS,
  INITIAL_ASSIGNMENTS,
  INITIAL_MESSAGES,
  INITIAL_EVENTS,
  INITIAL_NOTIFICATIONS,
} from '../data/mockData';

interface CollegeContextType {
  // Current user & auth
  currentUser: User;
  setCurrentUser: (user: User) => void;
  switchRole: (role: Role, specificUserId?: string) => void;
  loginWithEmail: (email: string) => boolean;
  allUsers: User[];
  
  // Teacher Account Approval & Permissions
  approveTeacherAccount: (
    userId: string,
    permissions: {
      canPrepareExams: boolean;
      canCreateClasswork: boolean;
      canEnterGrades: boolean;
      canUploadMaterials: boolean;
      assignedCourses: string[];
      department?: string;
      title?: string;
      employmentType?: User['employmentType'];
    }
  ) => void;
  rejectTeacherAccount: (userId: string, reason: string) => void;
  updateTeacherPermissions: (userId: string, permissions: Partial<User>) => void;
  registerTeacherAccount: (teacherData: Omit<User, 'id'>) => User;
  suspendTeacherAccount: (userId: string, reason?: string) => void;
  reactivateTeacherAccount: (userId: string) => void;

  // Data arrays
  courses: Course[];
  applications: StudentApplication[];
  grades: GradeItem[];
  attendance: AttendanceRecord[];
  fees: FeePayment[];
  studyMaterials: StudyMaterial[];
  assignments: Assignment[];
  messages: Message[];
  events: CollegeEvent[];
  notifications: NotificationItem[];
  
  // Actions
  submitApplication: (application: Omit<StudentApplication, 'id' | 'refNumber' | 'applicationDate' | 'status'>) => StudentApplication;
  approveApplication: (appId: string, assignedStudentId?: string) => void;
  rejectApplication: (appId: string, reason?: string) => void;
  
  // Attendance
  markAttendance: (record: Omit<AttendanceRecord, 'id'>) => void;
  bulkMarkAttendance: (records: Omit<AttendanceRecord, 'id'>[]) => void;
  
  // Grades
  saveGrade: (grade: Omit<GradeItem, 'id'> | GradeItem) => void;
  publishGradesForCourse: (courseCode: string) => void;
  
  // Financials & Exam Result clearance
  isResultsLocked: (studentId: string) => { isLocked: boolean; balanceDue: number; feeRecord?: FeePayment };
  submitBankDepositSlip: (studentId: string, slipData: { amount: number; bankRefNumber: string; depositDate: string; bankName: string; serviceCentre: string; notes?: string }) => void;
  verifyBankDepositSlip: (feeId: string, slipId: string, approve: boolean, notes?: string) => void;
  quickClearFeeBalance: (studentId: string) => void;
  
  // Assignments & Materials
  submitAssignmentWork: (assignmentId: string, submission: { fileName: string; fileSize: string; notes: string }) => void;
  gradeAssignmentWork: (assignmentId: string, score: number, feedback: string) => void;
  addNewAssignment: (assignment: Omit<Assignment, 'id' | 'submissionsCount'>) => void;
  uploadMaterial: (material: Omit<StudyMaterial, 'id' | 'uploadDate'>) => void;
  
  // Messaging
  sendMessage: (msg: Omit<Message, 'id' | 'timestamp' | 'read'>) => void;
  markMessageRead: (messageId: string) => void;
  
  // Events
  addCollegeEvent: (event: Omit<CollegeEvent, 'id'>) => void;
  deleteCollegeEvent: (eventId: string) => void;
  
  // Notifications & Push
  broadcastUrgentAlert: (title: string, message: string, targetRole?: Role | 'all') => void;
  markNotificationRead: (id: string) => void;
  clearAllNotifications: () => void;
  unreadCount: number;
}

const CollegeContext = createContext<CollegeContextType | undefined>(undefined);

const LOCAL_STORAGE_KEY = 'stc_college_management_state_v1';

export const CollegeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  // Users state with local storage persistence
  const [allUsers, setAllUsers] = useState<User[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_users`);
    if (saved) {
      try {
        const parsed: User[] = JSON.parse(saved);
        // Merge with any newly added initial users if missing
        const existingIds = new Set(parsed.map(u => u.id));
        const missing = INITIAL_USERS.filter(u => !existingIds.has(u.id));
        return [...parsed, ...missing];
      } catch (e) {
        return INITIAL_USERS;
      }
    }
    return INITIAL_USERS;
  });

  // Load initial state from local storage if available
  const [currentUser, setCurrentUser] = useState<User>(() => {
    return allUsers[0] || INITIAL_USERS[0]; // Default to Admin
  });
  
  const [courses, setCourses] = useState<Course[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_courses`);
    return saved ? JSON.parse(saved) : INITIAL_COURSES;
  });

  const [applications, setApplications] = useState<StudentApplication[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_applications`);
    return saved ? JSON.parse(saved) : INITIAL_APPLICATIONS;
  });

  const [grades, setGrades] = useState<GradeItem[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_grades`);
    return saved ? JSON.parse(saved) : INITIAL_GRADES;
  });

  const [attendance, setAttendance] = useState<AttendanceRecord[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_attendance`);
    return saved ? JSON.parse(saved) : INITIAL_ATTENDANCE;
  });

  const [fees, setFees] = useState<FeePayment[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_fees`);
    return saved ? JSON.parse(saved) : INITIAL_FEES;
  });

  const [studyMaterials, setStudyMaterials] = useState<StudyMaterial[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_materials`);
    return saved ? JSON.parse(saved) : INITIAL_STUDY_MATERIALS;
  });

  const [assignments, setAssignments] = useState<Assignment[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_assignments`);
    return saved ? JSON.parse(saved) : INITIAL_ASSIGNMENTS;
  });

  const [messages, setMessages] = useState<Message[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_messages`);
    return saved ? JSON.parse(saved) : INITIAL_MESSAGES;
  });

  const [events, setEvents] = useState<CollegeEvent[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_events`);
    return saved ? JSON.parse(saved) : INITIAL_EVENTS;
  });

  const [notifications, setNotifications] = useState<NotificationItem[]>(() => {
    const saved = localStorage.getItem(`${LOCAL_STORAGE_KEY}_notifications`);
    return saved ? JSON.parse(saved) : INITIAL_NOTIFICATIONS;
  });

  // Sync to LocalStorage
  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_users`, JSON.stringify(allUsers));
  }, [allUsers]);

  // Sync to LocalStorage
  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_courses`, JSON.stringify(courses));
  }, [courses]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_applications`, JSON.stringify(applications));
  }, [applications]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_grades`, JSON.stringify(grades));
  }, [grades]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_attendance`, JSON.stringify(attendance));
  }, [attendance]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_fees`, JSON.stringify(fees));
  }, [fees]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_materials`, JSON.stringify(studyMaterials));
  }, [studyMaterials]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_assignments`, JSON.stringify(assignments));
  }, [assignments]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_messages`, JSON.stringify(messages));
  }, [messages]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_events`, JSON.stringify(events));
  }, [events]);

  useEffect(() => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY}_notifications`, JSON.stringify(notifications));
  }, [notifications]);

  // Role switching
  const switchRole = (role: Role, specificUserId?: string) => {
    if (specificUserId) {
      const match = allUsers.find(u => u.id === specificUserId) || INITIAL_USERS.find(u => u.id === specificUserId);
      if (match) {
        setCurrentUser(match);
        return;
      }
    }
    const defaultForRole = allUsers.find(u => u.role === role) || INITIAL_USERS.find(u => u.role === role);
    if (defaultForRole) {
      setCurrentUser(defaultForRole);
    }
  };

  const loginWithEmail = (email: string): boolean => {
    const cleanEmail = email.trim().toLowerCase();
    const match = allUsers.find(u => u.email.toLowerCase() === cleanEmail) || INITIAL_USERS.find(u => u.email.toLowerCase() === cleanEmail);
    if (match) {
      setCurrentUser(match);
      return true;
    }
    // If not found in default users, try creating a session or matching student
    const studentApp = applications.find(a => a.guardianEmail?.toLowerCase() === cleanEmail);
    if (studentApp) {
      setCurrentUser({
        id: `parent-${studentApp.id}`,
        name: studentApp.guardianName,
        email: cleanEmail,
        role: 'parent',
        studentId: studentApp.assignedStudentId || 'STC/2026/ICT-108',
        title: `Guardian of ${studentApp.firstNames} ${studentApp.surname}`,
      });
      return true;
    }
    return false;
  };

  // Teacher Account Approval & Permission Management
  const approveTeacherAccount = (
    userId: string,
    permissions: {
      canPrepareExams: boolean;
      canCreateClasswork: boolean;
      canEnterGrades: boolean;
      canUploadMaterials: boolean;
      assignedCourses: string[];
      department?: string;
      title?: string;
      employmentType?: User['employmentType'];
    }
  ) => {
    setAllUsers(prev =>
      prev.map(u => {
        if (u.id === userId) {
          const updatedUser: User = {
            ...u,
            status: 'active',
            canPrepareExams: permissions.canPrepareExams,
            canCreateClasswork: permissions.canCreateClasswork,
            canEnterGrades: permissions.canEnterGrades,
            canUploadMaterials: permissions.canUploadMaterials,
            assignedCourses: permissions.assignedCourses,
            department: permissions.department || u.department || 'Academic Faculty',
            title: permissions.title || u.title || 'Accredited College Lecturer',
            employmentType: permissions.employmentType || u.employmentType || 'Full-Time Lecturer',
            approvedBy: currentUser.name || 'Dr. Eddie Njunga (Principal & Registrar)',
            approvedAt: new Date().toISOString(),
            rejectionReason: undefined,
          };
          return updatedUser;
        }
        return u;
      })
    );

    // If the approved teacher is the currently logged in user, refresh their session
    if (currentUser.id === userId) {
      setCurrentUser(prev => ({
        ...prev,
        status: 'active',
        canPrepareExams: permissions.canPrepareExams,
        canCreateClasswork: permissions.canCreateClasswork,
        canEnterGrades: permissions.canEnterGrades,
        canUploadMaterials: permissions.canUploadMaterials,
        assignedCourses: permissions.assignedCourses,
        department: permissions.department || prev.department || 'Academic Faculty',
        title: permissions.title || prev.title || 'Accredited College Lecturer',
        employmentType: permissions.employmentType || prev.employmentType || 'Full-Time Lecturer',
        approvedBy: currentUser.name || 'Dr. Eddie Njunga (Principal & Registrar)',
        approvedAt: new Date().toISOString(),
      }));
    }

    const targetUser = allUsers.find(u => u.id === userId);
    const lecturerName = targetUser?.name || 'Lecturer';

    // Broadcast audit and notification
    const approvalNotif: NotificationItem = {
      id: `NOTIF-TEACHER-APPR-${Date.now()}`,
      title: 'Teacher Account Commissioned & Approved',
      message: `${lecturerName} has been approved by the Principal with authorizations: [${permissions.canPrepareExams ? 'Exams' : ''} ${permissions.canCreateClasswork ? 'Classworks' : ''} ${permissions.canEnterGrades ? 'Grading' : ''}].`,
      type: 'urgent',
      timestamp: 'Just now',
      targetRole: 'all',
      read: false,
    };
    setNotifications(prev => [approvalNotif, ...prev]);
  };

  const rejectTeacherAccount = (userId: string, reason: string) => {
    setAllUsers(prev =>
      prev.map(u => {
        if (u.id === userId) {
          return {
            ...u,
            status: 'rejected',
            rejectionReason: reason,
          };
        }
        return u;
      })
    );

    if (currentUser.id === userId) {
      setCurrentUser(prev => ({
        ...prev,
        status: 'rejected',
        rejectionReason: reason,
      }));
    }

    const targetUser = allUsers.find(u => u.id === userId);
    const rejNotif: NotificationItem = {
      id: `NOTIF-TEACHER-REJ-${Date.now()}`,
      title: 'Teacher Application Review Update',
      message: `Application for ${targetUser?.name || 'Lecturer'} was reviewed: ${reason}`,
      type: 'urgent',
      timestamp: 'Just now',
      targetRole: 'admin',
      read: false,
    };
    setNotifications(prev => [rejNotif, ...prev]);
  };

  const updateTeacherPermissions = (userId: string, permissions: Partial<User>) => {
    setAllUsers(prev =>
      prev.map(u => {
        if (u.id === userId) {
          return {
            ...u,
            ...permissions,
          };
        }
        return u;
      })
    );

    if (currentUser.id === userId) {
      setCurrentUser(prev => ({
        ...prev,
        ...permissions,
      }));
    }
  };

  const registerTeacherAccount = (teacherData: Omit<User, 'id'>): User => {
    const newId = `user-teacher-${Date.now()}`;
    const newTeacher: User = {
      ...teacherData,
      id: newId,
      role: 'teacher',
      status: teacherData.status || 'pending_approval',
      registrationDate: new Date().toISOString().split('T')[0],
      canPrepareExams: teacherData.canPrepareExams ?? false,
      canCreateClasswork: teacherData.canCreateClasswork ?? false,
      canEnterGrades: teacherData.canEnterGrades ?? false,
      canUploadMaterials: teacherData.canUploadMaterials ?? false,
    };

    setAllUsers(prev => [newTeacher, ...prev]);

    const notif: NotificationItem = {
      id: `NOTIF-NEW-TEACHER-${Date.now()}`,
      title: 'New Teacher Registration Submitted',
      message: `${newTeacher.name} registered for ${newTeacher.department || 'Academic Department'} and is awaiting Principal approval.`,
      type: 'urgent',
      timestamp: 'Just now',
      targetRole: 'admin',
      read: false,
    };
    setNotifications(prev => [notif, ...prev]);

    return newTeacher;
  };

  const suspendTeacherAccount = (userId: string, reason?: string) => {
    setAllUsers(prev =>
      prev.map(u => {
        if (u.id === userId) {
          return {
            ...u,
            status: 'suspended',
            rejectionReason: reason || 'Account temporarily suspended by Principal / Registry.',
          };
        }
        return u;
      })
    );

    if (currentUser.id === userId) {
      setCurrentUser(prev => ({
        ...prev,
        status: 'suspended',
        rejectionReason: reason || 'Account temporarily suspended by Principal / Registry.',
      }));
    }
  };

  const reactivateTeacherAccount = (userId: string) => {
    setAllUsers(prev =>
      prev.map(u => {
        if (u.id === userId) {
          return {
            ...u,
            status: 'active',
            rejectionReason: undefined,
          };
        }
        return u;
      })
    );

    if (currentUser.id === userId) {
      setCurrentUser(prev => ({
        ...prev,
        status: 'active',
        rejectionReason: undefined,
      }));
    }
  };

  // Submit Application
  const submitApplication = (appData: Omit<StudentApplication, 'id' | 'refNumber' | 'applicationDate' | 'status'>): StudentApplication => {
    const nextIndex = applications.length + 1;
    const refNum = `STC/APPLFORM/01/2025/${String(nextIndex).padStart(3, '0')}`;
    const newApp: StudentApplication = {
      ...appData,
      id: `APP-2026-${String(nextIndex).padStart(3, '0')}`,
      refNumber: refNum,
      applicationDate: new Date().toISOString().split('T')[0],
      status: 'Pending Verification',
    };

    setApplications(prev => [newApp, ...prev]);

    // Send notification to Admin & Parent
    const adminNotif: NotificationItem = {
      id: `NOTIF-APP-${Date.now()}`,
      title: 'New Student Application Submitted',
      message: `${appData.firstNames} ${appData.surname} submitted registration form for course ${appData.firstChoiceCourseCode}. Bank ref: ${appData.depositSlipRef}`,
      type: 'urgent',
      timestamp: 'Just now',
      targetRole: 'admin',
      read: false,
    };
    setNotifications(prev => [adminNotif, ...prev]);

    return newApp;
  };

  const approveApplication = (appId: string, assignedStudentId?: string) => {
    const app = applications.find(a => a.id === appId);
    if (!app) return;

    const course = courses.find(c => c.code === app.firstChoiceCourseCode);
    const tuition = course ? course.tuitionFee : 180000;
    const generatedStudentId = assignedStudentId || `STC/2026/${app.firstChoiceCourseCode}-${Math.floor(100 + Math.random() * 900)}`;

    setApplications(prev =>
      prev.map(a =>
        a.id === appId
          ? {
              ...a,
              status: 'Approved',
              assignedStudentId: generatedStudentId,
              accountsOfficerStamp: `APPROVED & REGISTERED - ${currentUser.name}`,
            }
          : a
      )
    );

    // Also create Fee Ledger Record
    const existingFee = fees.find(f => f.studentId === generatedStudentId);
    if (!existingFee) {
      const initialPaid = app.registrationFeePaid ? app.registrationFeeAmount : 0;
      const totalDue = tuition + app.registrationFeeAmount + (app.boardingRequested ? 450000 : 0);
      const newFeeRecord: FeePayment = {
        id: `FEE-2026-${Math.floor(1000 + Math.random() * 9000)}`,
        studentId: generatedStudentId,
        studentName: `${app.firstNames} ${app.surname}`,
        courseName: course ? course.name : 'Technical Diploma',
        totalTuitionDue: tuition,
        registrationFee: app.registrationFeeAmount,
        boardingFeeDue: app.boardingRequested ? 450000 : 0,
        totalAmountDue: totalDue,
        totalPaid: initialPaid,
        balanceDue: totalDue - initialPaid,
        currency: 'MWK',
        lastPaymentDate: app.depositSlipDate || new Date().toISOString().split('T')[0],
        status: initialPaid >= totalDue ? 'Fully Cleared' : 'Unpaid Balance',
        bankDepositSlips: [
          {
            id: `SLIP-INIT-${Date.now()}`,
            amount: initialPaid,
            depositDate: app.depositSlipDate || new Date().toISOString().split('T')[0],
            bankRefNumber: app.depositSlipRef,
            bankName: app.bankName,
            serviceCentre: 'Customs Road',
            status: 'Verified',
            receiptNumber: `STC-REC-2026-${Math.floor(1000 + Math.random() * 9000)}`,
            notes: 'Registration fee confirmed during admission approval.',
            uploadedAt: new Date().toISOString().replace('T', ' ').slice(0, 16),
          },
        ],
      };
      setFees(prev => [newFeeRecord, ...prev]);
    }
  };

  const rejectApplication = (appId: string, reason?: string) => {
    setApplications(prev =>
      prev.map(a =>
        a.id === appId
          ? {
              ...a,
              status: 'Rejected',
              accountsNotes: reason || 'Application rejected due to incomplete academic qualifications or missing bank deposit slip.',
            }
          : a
      )
    );
  };

  // Attendance
  const markAttendance = (record: Omit<AttendanceRecord, 'id'>) => {
    const newRecord: AttendanceRecord = {
      ...record,
      id: `ATT-${Date.now()}-${Math.floor(Math.random() * 1000)}`,
    };

    setAttendance(prev => [newRecord, ...prev]);

    // If absent or late, trigger automatic parent notification
    if (record.status === 'Absent' || record.status === 'Late') {
      const parentNotif: NotificationItem = {
        id: `NOTIF-ATT-${Date.now()}`,
        title: record.status === 'Absent' ? 'Student Absence Alert' : 'Late Arrival Notice',
        message: `Student (${record.studentId}) was marked ${record.status} for ${record.sessionName} on ${record.date}.`,
        type: 'attendance',
        timestamp: 'Just now',
        targetRole: 'parent',
        read: false,
      };
      setNotifications(prev => [parentNotif, ...prev]);
    }
  };

  const bulkMarkAttendance = (records: Omit<AttendanceRecord, 'id'>[]) => {
    const newRecords: AttendanceRecord[] = records.map((r, idx) => ({
      ...r,
      id: `ATT-${Date.now()}-${idx}`,
    }));
    setAttendance(prev => [...newRecords, ...prev]);
  };

  // Grades
  const saveGrade = (gradeData: Omit<GradeItem, 'id'> | GradeItem) => {
    if ('id' in gradeData && gradeData.id) {
      setGrades(prev => prev.map(g => (g.id === gradeData.id ? (gradeData as GradeItem) : g)));
    } else {
      const newGrade: GradeItem = {
        ...gradeData,
        id: `GRD-${Date.now()}`,
      };
      setGrades(prev => [newGrade, ...prev]);
    }
  };

  const publishGradesForCourse = (courseCode: string) => {
    setGrades(prev =>
      prev.map(g => (g.courseCode === courseCode ? { ...g, isPublished: true } : g))
    );
    const notif: NotificationItem = {
      id: `NOTIF-PUB-${Date.now()}`,
      title: 'Official Grades Published',
      message: `Grades for course ${courseCode} have been verified and published by the academic office.`,
      type: 'grade',
      timestamp: 'Just now',
      targetRole: 'all',
      read: false,
    };
    setNotifications(prev => [notif, ...prev]);
  };

  // Fee Restriction logic
  const isResultsLocked = (studentId: string) => {
    const feeRecord = fees.find(f => f.studentId === studentId);
    if (!feeRecord) {
      return { isLocked: false, balanceDue: 0 };
    }
    const isLocked = feeRecord.balanceDue > 0;
    return { isLocked, balanceDue: feeRecord.balanceDue, feeRecord };
  };

  const submitBankDepositSlip = (
    studentId: string,
    slipData: { amount: number; bankRefNumber: string; depositDate: string; bankName: string; serviceCentre: string; notes?: string }
  ) => {
    const newSlipId = `SLIP-${Date.now()}`;
    const formattedSlip = {
      id: newSlipId,
      amount: slipData.amount,
      depositDate: slipData.depositDate,
      bankRefNumber: slipData.bankRefNumber,
      bankName: slipData.bankName,
      serviceCentre: slipData.serviceCentre,
      status: 'Pending Review' as const,
      notes: slipData.notes,
      uploadedAt: new Date().toISOString().replace('T', ' ').slice(0, 16),
    };

    setFees(prev => {
      const exists = prev.find(f => f.studentId === studentId);
      if (exists) {
        return prev.map(f =>
          f.studentId === studentId
            ? {
                ...f,
                status: 'Pending Bank Slip Review',
                bankDepositSlips: [formattedSlip, ...f.bankDepositSlips],
              }
            : f
        );
      }
      return prev;
    });

    // Alert Admin & Accounts
    const notif: NotificationItem = {
      id: `NOTIF-SLIP-${Date.now()}`,
      title: 'Bank Deposit Slip Uploaded',
      message: `Student ${studentId} uploaded deposit slip (Ref: ${slipData.bankRefNumber}, Amount: MK ${slipData.amount.toLocaleString()}) for verification.`,
      type: 'fee',
      timestamp: 'Just now',
      targetRole: 'admin',
      read: false,
    };
    setNotifications(prev => [notif, ...prev]);
  };

  const verifyBankDepositSlip = (feeId: string, slipId: string, approve: boolean, notes?: string) => {
    setFees(prev =>
      prev.map(f => {
        if (f.id !== feeId) return f;

        const updatedSlips = f.bankDepositSlips.map(slip => {
          if (slip.id !== slipId) return slip;
          return {
            ...slip,
            status: approve ? ('Verified' as const) : ('Rejected' as const),
            receiptNumber: approve ? `STC-REC-2026-${Math.floor(1000 + Math.random() * 9000)}` : undefined,
            notes: notes || slip.notes,
          };
        });

        if (approve) {
          const verifiedSlip = f.bankDepositSlips.find(s => s.id === slipId);
          const addedAmount = verifiedSlip ? verifiedSlip.amount : 0;
          const newTotalPaid = f.totalPaid + addedAmount;
          const newBalance = Math.max(0, f.totalAmountDue - newTotalPaid);
          const newStatus =
            newBalance <= 0
              ? 'Fully Cleared'
              : newTotalPaid >= f.totalAmountDue * 0.7
              ? 'Partial (70% Paid)'
              : 'Unpaid Balance';

          return {
            ...f,
            totalPaid: newTotalPaid,
            balanceDue: newBalance,
            status: newStatus,
            lastPaymentDate: new Date().toISOString().split('T')[0],
            bankDepositSlips: updatedSlips,
          };
        }

        return {
          ...f,
          bankDepositSlips: updatedSlips,
        };
      })
    );

    // Send confirmation alert to student and parent
    const targetFee = fees.find(f => f.id === feeId);
    if (targetFee) {
      const alertMsg: NotificationItem = {
        id: `NOTIF-VERIFY-${Date.now()}`,
        title: approve ? 'Payment Slip Verified - Fee Cleared' : 'Payment Slip Rejected',
        message: approve
          ? `Your bank deposit slip for ${targetFee.studentName} has been verified by the Accounts Office. Examination results and transcripts are now unlocked.`
          : `Your bank deposit slip for ${targetFee.studentName} could not be verified. Please contact the Accounts Office at Customs Road.`,
        type: 'fee',
        timestamp: 'Just now',
        targetRole: 'all',
        read: false,
      };
      setNotifications(prev => [alertMsg, ...prev]);
    }
  };

  const quickClearFeeBalance = (studentId: string) => {
    setFees(prev =>
      prev.map(f => {
        if (f.studentId !== studentId) return f;
        return {
          ...f,
          totalPaid: f.totalAmountDue,
          balanceDue: 0,
          status: 'Fully Cleared',
          lastPaymentDate: new Date().toISOString().split('T')[0],
          bankDepositSlips: [
            {
              id: `SLIP-SIM-${Date.now()}`,
              amount: f.balanceDue,
              depositDate: new Date().toISOString().split('T')[0],
              bankRefNumber: `NB-AUTO-${Math.floor(100000 + Math.random() * 900000)}`,
              bankName: 'National Bank of Malawi',
              serviceCentre: 'Customs Road',
              status: 'Verified',
              receiptNumber: `STC-REC-2026-${Math.floor(1000 + Math.random() * 9000)}`,
              notes: 'Full balance settlement confirmed by Bursar.',
              uploadedAt: new Date().toISOString().replace('T', ' ').slice(0, 16),
            },
            ...f.bankDepositSlips,
          ],
        };
      })
    );
  };

  // Assignments
  const submitAssignmentWork = (assignmentId: string, submission: { fileName: string; fileSize: string; notes: string }) => {
    setAssignments(prev =>
      prev.map(a => {
        if (a.id !== assignmentId) return a;
        return {
          ...a,
          submissionsCount: a.submissionsCount + 1,
          mySubmission: {
            submittedAt: new Date().toISOString().replace('T', ' ').slice(0, 16),
            fileName: submission.fileName,
            fileSize: submission.fileSize,
            notes: submission.notes,
            status: 'Submitted',
          },
        };
      })
    );
  };

  const gradeAssignmentWork = (assignmentId: string, score: number, feedback: string) => {
    setAssignments(prev =>
      prev.map(a => {
        if (a.id !== assignmentId || !a.mySubmission) return a;
        return {
          ...a,
          mySubmission: {
            ...a.mySubmission,
            score,
            feedback,
            status: 'Graded',
          },
        };
      })
    );
  };

  const addNewAssignment = (assignment: Omit<Assignment, 'id' | 'submissionsCount'>) => {
    const newAsn: Assignment = {
      ...assignment,
      id: `ASN-${Date.now()}`,
      submissionsCount: 0,
    };
    setAssignments(prev => [newAsn, ...prev]);

    const notif: NotificationItem = {
      id: `NOTIF-ASN-${Date.now()}`,
      title: `New Assignment: ${assignment.title}`,
      message: `Course ${assignment.courseCode} assignment has been posted. Due on ${assignment.dueDate}.`,
      type: 'grade',
      timestamp: 'Just now',
      targetRole: 'student',
      read: false,
    };
    setNotifications(prev => [notif, ...prev]);
  };

  const uploadMaterial = (material: Omit<StudyMaterial, 'id' | 'uploadDate'>) => {
    const newMat: StudyMaterial = {
      ...material,
      id: `MAT-${Date.now()}`,
      uploadDate: new Date().toISOString().split('T')[0],
    };
    setStudyMaterials(prev => [newMat, ...prev]);
  };

  // Messaging
  const sendMessage = (msg: Omit<Message, 'id' | 'timestamp' | 'read'>) => {
    const newMsg: Message = {
      ...msg,
      id: `MSG-${Date.now()}`,
      timestamp: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + ', Today',
      read: false,
    };
    setMessages(prev => [...prev, newMsg]);

    const notif: NotificationItem = {
      id: `NOTIF-MSG-${Date.now()}`,
      title: `New Message from ${msg.senderName}`,
      message: msg.subject,
      type: 'message',
      timestamp: 'Just now',
      targetRole: msg.receiverRole,
      read: false,
    };
    setNotifications(prev => [notif, ...prev]);
  };

  const markMessageRead = (messageId: string) => {
    setMessages(prev => prev.map(m => (m.id === messageId ? { ...m, read: true } : m)));
  };

  // Events
  const addCollegeEvent = (event: Omit<CollegeEvent, 'id'>) => {
    const newEvt: CollegeEvent = {
      ...event,
      id: `EVT-${Date.now()}`,
    };
    setEvents(prev => [...prev, newEvt]);

    if (event.isImportant) {
      broadcastUrgentAlert(`New Event: ${event.title}`, `${event.description} (Date: ${event.date})`);
    }
  };

  const deleteCollegeEvent = (eventId: string) => {
    setEvents(prev => prev.filter(e => e.id !== eventId));
  };

  // Notifications
  const broadcastUrgentAlert = (title: string, message: string, targetRole: Role | 'all' = 'all') => {
    const urgentNotif: NotificationItem = {
      id: `NOTIF-URGENT-${Date.now()}`,
      title,
      message,
      type: 'urgent',
      timestamp: 'Just now',
      targetRole,
      read: false,
    };
    setNotifications(prev => [urgentNotif, ...prev]);
  };

  const markNotificationRead = (id: string) => {
    setNotifications(prev => prev.map(n => (n.id === id ? { ...n, read: true } : n)));
  };

  const clearAllNotifications = () => {
    setNotifications(prev => prev.map(n => ({ ...n, read: true })));
  };

  const unreadCount = notifications.filter(n => !n.read).length;

  return (
    <CollegeContext.Provider
      value={{
        currentUser,
        setCurrentUser,
        switchRole,
        loginWithEmail,
        allUsers,
        approveTeacherAccount,
        rejectTeacherAccount,
        updateTeacherPermissions,
        registerTeacherAccount,
        suspendTeacherAccount,
        reactivateTeacherAccount,
        courses,
        applications,
        grades,
        attendance,
        fees,
        studyMaterials,
        assignments,
        messages,
        events,
        notifications,
        submitApplication,
        approveApplication,
        rejectApplication,
        markAttendance,
        bulkMarkAttendance,
        saveGrade,
        publishGradesForCourse,
        isResultsLocked,
        submitBankDepositSlip,
        verifyBankDepositSlip,
        quickClearFeeBalance,
        submitAssignmentWork,
        gradeAssignmentWork,
        addNewAssignment,
        uploadMaterial,
        sendMessage,
        markMessageRead,
        addCollegeEvent,
        deleteCollegeEvent,
        broadcastUrgentAlert,
        markNotificationRead,
        clearAllNotifications,
        unreadCount,
      }}
    >
      {children}
    </CollegeContext.Provider>
  );
};

export const useCollege = () => {
  const context = useContext(CollegeContext);
  if (!context) {
    throw new Error('useCollege must be used within a CollegeProvider');
  }
  return context;
};
