/**
 * Student Medical Records — Zustand store
 *
 * Covers student_medical_profiles, student_medication_logs, student_medical_history,
 * sanatorium_visits, student_immunizations, student_medical_documents, dining_hall_alerts,
 * dining hall DTOs, and teacher class roster flags.
 */

import { create } from 'zustand';
import { api } from './api';
import { createAxiosUploadProgressHandler } from '../lib/uploadProgress';

export interface MedicalProfile {
  id?: number;
  uid?: string;
  student_id?: number;
  blood_group?: string;
  allergies?: string;
  dietary_restrictions?: string;
  contraindications?: string;
  chronic_conditions?: string;
  emergency_instructions?: string;
  warning?: string;       // attached on POST /logs response
}

export interface MedicationLog {
  id?: number;
  uid?: string;
  student_id?: number;
  medication_name: string;
  dosage: string;
  administered_at: string;
  administered_by?: number;
  reason?: string;
  notes?: string;
  warning?: string;
}

export interface MedicalHistoryEvent {
  id?: number;
  uid?: string;
  student_id?: number;
  event_type: 'illness' | 'injury' | 'hospitalization';
  description: string;
  severity?: 'mild' | 'moderate' | 'severe';
  title?: string;
  onset_date?: string;
  resolution_date?: string;
  treatment_details?: string;
  doctor_notes?: string;
  is_visible_to_teachers?: 0 | 1;
  reported_by?: number;
}

export interface SanatoriumVisit {
  id?: number;
  uid?: string;
  student_id: number;
  student_uid?: string;
  student_first_name?: string;
  student_last_name?: string;
  id_number?: string;
  class_name?: string;
  nurse_id?: number;
  nurse_first_name?: string;
  nurse_last_name?: string;
  visit_date: string;
  chief_complaint: string;
  vitals_json?: string;
  treatment_administered?: string;
  disposition: 'discharged' | 'admitted' | 'sent_home' | 'referred_hospital';
  bed_number?: number;
  parent_notified: number;
  notes?: string;
}

export interface ImmunizationRecord {
  id?: number;
  uid?: string;
  student_id: number;
  vaccine_name: string;
  dose_number: number;
  administered_date: string;
  administered_by?: string;
  batch_number?: string;
  notes?: string;
}

export interface MedicalDocument {
  id: number;
  uid: string;
  student_id: number;
  file_name: string;
  file_url: string;
  file_type: string;
  document_type: 'lab_report' | 'doctor_note' | 'prescription' | 'vaccination_cert' | 'ingested_record' | 'other';
  notes?: string;
  uploader_first_name?: string;
  uploader_last_name?: string;
  created_at: string;
}

export interface StudentSearchResult {
  id: number;
  uid: string;
  id_number?: string;
  first_name: string;
  last_name: string;
  email: string;
  phone?: string;
  emergency_contact?: string;
  emergency_phone?: string;
  class_name?: string;
}

export interface DiningAlertRow {
  student_uid: string;
  student_id: number;
  name: string;
  class: string;
  blood_group?: string;
  allergies?: string;
  dietary_restrictions?: string;
  emergency_instructions?: string;
  alert_id?: number;
  severity?: 'mild' | 'severe' | 'life_threatening';
  special_instructions?: string;
  alert_status?: 'normal' | 'active' | 'acknowledged';
  alert_created_at?: string;
}

export interface ClassFlagRow {
  student_uid: string;
  student_id: number;
  name: string;
  blood_group?: string;
  allergies?: string;
  chronic_conditions?: string;
  emergency_instructions?: string;
  active_med_count: number;
  active_history_count: number;
}

export interface MedicalStore {
  // State
  currentProfile: MedicalProfile | null;
  medicationLogs: MedicationLog[];
  medicalHistory: MedicalHistoryEvent[];
  sanatoriumVisits: SanatoriumVisit[];
  immunizations: ImmunizationRecord[];
  medicalDocuments: MedicalDocument[];
  searchResults: StudentSearchResult[];
  diningAlerts: DiningAlertRow[];
  classFlags: ClassFlagRow[];

  // UI flags
  loading: boolean;
  error: string | null;

  // Upload progress (0-100) while a medical document upload is in flight
  uploadProgress: number | null;

  // Student Search Autocomplete
  searchStudents: (query: string) => Promise<StudentSearchResult[]>;

  // Profile (per-student)
  fetchProfile: (studentUid: string) => Promise<void>;
  saveProfile: (studentUid: string, profile: Partial<MedicalProfile>) => Promise<MedicalProfile | null>;

  // Medication logs
  fetchMedicationLogs: (studentUid: string) => Promise<void>;
  addMedicationLog: (studentUid: string, log: Partial<MedicationLog>) => Promise<MedicationLog | null>;
  deleteMedicationLog: (id: number) => Promise<boolean>;

  // Medical history
  fetchMedicalHistory: (studentUid: string) => Promise<void>;
  addHistoryEvent: (studentUid: string, event: Partial<MedicalHistoryEvent>) => Promise<MedicalHistoryEvent | null>;
  updateHistoryEvent: (id: number, event: Partial<MedicalHistoryEvent>) => Promise<boolean>;
  deleteHistoryEvent: (id: number) => Promise<boolean>;

  // Sanatorium Visits
  fetchSanatoriumVisits: (params?: { disposition?: string; student_uid?: string }) => Promise<void>;
  addSanatoriumVisit: (visit: Partial<SanatoriumVisit>) => Promise<SanatoriumVisit | null>;
  updateSanatoriumVisit: (id: number, visit: Partial<SanatoriumVisit>) => Promise<SanatoriumVisit | null>;

  // Immunizations
  fetchImmunizations: (studentUid: string) => Promise<void>;
  addImmunization: (immunization: Partial<ImmunizationRecord>) => Promise<ImmunizationRecord | null>;

  // Documents & Record Ingestion
  fetchMedicalDocuments: (studentUid: string) => Promise<void>;
  uploadMedicalDocument: (studentUid: string, file: File, documentType: string, notes?: string) => Promise<MedicalDocument | null>;
  ingestMedicalJSON: (records: any[]) => Promise<{ count: number } | null>;
  deleteMedicalDocument: (id: number) => Promise<boolean>;

  // Dining Hall Kitchen Allergy Alerts
  sendDiningHallAlert: (studentUid: string, allergyDetails: string, severity: string, specialInstructions?: string) => Promise<boolean>;
  acknowledgeDiningAlert: (alertId: number) => Promise<boolean>;

  // Parent Alert
  notifyParent: (studentUid: string, subject: string, body: string) => Promise<boolean>;

  // Dining hall roster
  fetchDiningAlerts: () => Promise<void>;

  // Teacher: per-class flags
  fetchClassFlags: (classId: number) => Promise<void>;

  // Reset helpers
  reset: () => void;
}

export const useMedicalStore = create<MedicalStore>((set, get) => ({
  currentProfile: null,
  medicationLogs: [],
  medicalHistory: [],
  sanatoriumVisits: [],
  immunizations: [],
  medicalDocuments: [],
  searchResults: [],
  diningAlerts: [],
  classFlags: [],

  loading: false,
  error: null,
  uploadProgress: null,

  searchStudents: async (query) => {
    if (!query.trim()) {
      set({ searchResults: [] });
      return [];
    }
    try {
      const r = await api.get('/medical/students/search', { params: { q: query } });
      const results = r.data || [];
      set({ searchResults: results });
      return results;
    } catch (e: any) {
      set({ searchResults: [] });
      return [];
    }
  },

  fetchProfile: async (studentUid) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/profiles/${studentUid}`);
      set({ currentProfile: r.data, loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
    }
  },

  saveProfile: async (studentUid, profile) => {
    try {
      set({ loading: true, error: null });
      let r;
      try {
        const current = get().currentProfile;
        if (current?.uid) {
          r = await api.put(`/medical/profiles/${current.uid}`, profile);
        } else {
          r = await api.post('/medical/profiles', { student_uid: studentUid, ...profile });
        }
      } catch (e: any) {
        if (e?.response?.status === 404 || e?.response?.status === 409) {
          r = await api.post('/medical/profiles', { student_uid: studentUid, ...profile });
        } else {
          throw e;
        }
      }
      set({ currentProfile: r.data, loading: false });
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  fetchMedicationLogs: async (studentUid) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/logs/${studentUid}`);
      set({ medicationLogs: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), medicationLogs: [], loading: false });
    }
  },

  addMedicationLog: async (studentUid, log) => {
    try {
      set({ loading: true, error: null });
      const r = await api.post('/medical/logs', { student_uid: studentUid, ...log });
      const data = r.data;
      set((state) => ({
        medicationLogs: [{ ...data, warning: data.warning }, ...state.medicationLogs],
        loading: false,
      }));
      return data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  deleteMedicationLog: async (id) => {
    try {
      await api.delete(`/medical/logs/${id}`);
      set((state) => ({
        medicationLogs: state.medicationLogs.filter((m) => m.id !== id),
      }));
      return true;
    } catch (e) {
      return false;
    }
  },

  fetchMedicalHistory: async (studentUid) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/history/${studentUid}`);
      set({ medicalHistory: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), medicalHistory: [], loading: false });
    }
  },

  addHistoryEvent: async (studentUid, event) => {
    try {
      set({ loading: true, error: null });
      const r = await api.post('/medical/history', { student_uid: studentUid, ...event });
      set((state) => ({
        medicalHistory: [r.data, ...state.medicalHistory],
        loading: false,
      }));
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  updateHistoryEvent: async (id, event) => {
    try {
      set({ loading: true, error: null });
      const r = await api.put(`/medical/history/${id}`, event);
      set((state) => ({
        medicalHistory: state.medicalHistory.map((h) => (h.id === id ? r.data : h)),
        loading: false,
      }));
      return true;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return false;
    }
  },

  deleteHistoryEvent: async (id) => {
    try {
      await api.delete(`/medical/history/${id}`);
      set((state) => ({
        medicalHistory: state.medicalHistory.filter((h) => h.id !== id),
      }));
      return true;
    } catch (e) {
      return false;
    }
  },

  fetchSanatoriumVisits: async (params) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get('/medical/visits', { params });
      set({ sanatoriumVisits: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), sanatoriumVisits: [], loading: false });
    }
  },

  addSanatoriumVisit: async (visit) => {
    try {
      set({ loading: true, error: null });
      const r = await api.post('/medical/visits', visit);
      set((state) => ({
        sanatoriumVisits: [r.data, ...state.sanatoriumVisits],
        loading: false,
      }));
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  updateSanatoriumVisit: async (id, visit) => {
    try {
      set({ loading: true, error: null });
      const r = await api.put(`/medical/visits/${id}`, visit);
      set((state) => ({
        sanatoriumVisits: state.sanatoriumVisits.map((v) => (v.id === id ? { ...v, ...r.data } : v)),
        loading: false,
      }));
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  fetchImmunizations: async (studentUid) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/immunizations/${studentUid}`);
      set({ immunizations: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), immunizations: [], loading: false });
    }
  },

  addImmunization: async (immunization) => {
    try {
      set({ loading: true, error: null });
      const r = await api.post('/medical/immunizations', immunization);
      set((state) => ({
        immunizations: [r.data, ...state.immunizations],
        loading: false,
      }));
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  fetchMedicalDocuments: async (studentUid) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/documents/${studentUid}`);
      set({ medicalDocuments: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), medicalDocuments: [], loading: false });
    }
  },

  uploadMedicalDocument: async (studentUid, file, documentType, notes) => {
    try {
      set({ loading: true, error: null, uploadProgress: 0 });
      const formData = new FormData();
      formData.append('file', file);
      formData.append('student_uid', studentUid);
      formData.append('document_type', documentType);
      if (notes) formData.append('notes', notes);

      const onUploadProgress = createAxiosUploadProgressHandler((percent) => {
        if (percent == null) return;
        set({ uploadProgress: percent });
      });

      const r = await api.post('/medical/documents/upload', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
        onUploadProgress,
      });
      set((state) => ({
        medicalDocuments: [r.data, ...state.medicalDocuments],
        loading: false,
        uploadProgress: null,
      }));
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false, uploadProgress: null });
      return null;
    }
  },

  ingestMedicalJSON: async (records) => {
    try {
      set({ loading: true, error: null });
      const r = await api.post('/medical/documents/ingest-json', { records });
      set({ loading: false });
      return r.data;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return null;
    }
  },

  deleteMedicalDocument: async (id) => {
    try {
      await api.delete(`/medical/documents/${id}`);
      set((state) => ({
        medicalDocuments: state.medicalDocuments.filter((d) => d.id !== id),
      }));
      return true;
    } catch (e) {
      return false;
    }
  },

  sendDiningHallAlert: async (studentUid, allergyDetails, severity, specialInstructions) => {
    try {
      set({ loading: true, error: null });
      await api.post('/medical/dining-alerts', {
        student_uid: studentUid,
        allergy_details: allergyDetails,
        severity,
        special_instructions: specialInstructions,
      });
      set({ loading: false });
      get().fetchDiningAlerts();
      return true;
    } catch (e: any) {
      set({ error: e?.message || String(e), loading: false });
      return false;
    }
  },

  acknowledgeDiningAlert: async (alertId) => {
    try {
      await api.put(`/medical/dining-alerts/${alertId}/acknowledge`);
      get().fetchDiningAlerts();
      return true;
    } catch (e) {
      return false;
    }
  },

  notifyParent: async (studentUid, subject, body) => {
    try {
      await api.post('/medical/notify-parent', { student_uid: studentUid, subject, body });
      return true;
    } catch (e) {
      return false;
    }
  },

  fetchDiningAlerts: async () => {
    try {
      set({ loading: true, error: null });
      const r = await api.get('/medical/dining/allergies');
      set({ diningAlerts: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), diningAlerts: [], loading: false });
    }
  },

  fetchClassFlags: async (classId) => {
    try {
      set({ loading: true, error: null });
      const r = await api.get(`/medical/class/${classId}/flags`);
      set({ classFlags: r.data || [], loading: false });
    } catch (e: any) {
      set({ error: e?.message || String(e), classFlags: [], loading: false });
    }
  },

  reset: () => set({
    currentProfile: null,
    medicationLogs: [],
    medicalHistory: [],
    sanatoriumVisits: [],
    immunizations: [],
    medicalDocuments: [],
    searchResults: [],
    diningAlerts: [],
    classFlags: [],
    loading: false,
    error: null,
    uploadProgress: null,
  }),
}));

// Helpers shared by pages
export const severityColor = (severity?: string): string => {
  switch (severity) {
    case 'life_threatening': return '#9333ea';
    case 'severe': return '#dc2626';
    case 'moderate': return '#f59e0b';
    case 'mild': return '#10b981';
    default: return '#6b7280';
  }
};

export const eventTypeIcon = (type?: string): string => {
  switch (type) {
    case 'illness': return '🤒';
    case 'injury': return '🩹';
    case 'hospitalization': return '🏥';
    default: return '📋';
  }
};

export const formatDate = (iso?: string): string => {
  if (!iso) return '—';
  try {
    return new Date(iso).toLocaleDateString();
  } catch {
    return iso;
  }
};

export default useMedicalStore;
