import { create} from "zustand";
import api from "../api";
import { toast } from "react-hot-toast";

const useStore = create((set, get) => ({
    isLoggedIn: false,
    authUser: null,
    authRole: null,

    patients: [],
    doctors: [],
    appointments: [],
    medicalReports: [],
    overallReports: [],

    checkAuth: async() => {
        try {
            const res = await api.get("/auth/check");
            if(res.status == 200) {
                set({ isLoggedIn: true, authUser: res.data.user, authRole: res.data.role });
            }else{
                set({ isLoggedIn: false, authUser: null, authRole: null });
            }
        } catch (error) {
            set({ isLoggedIn: false, authUser: null, authRole: null });
            console.log(error)
        }
    },
    login: async(username, password) => {
        try {
            const res = await api.post("/auth/login", { username, password });
            if(res.status === 200) {
                await get().checkAuth();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    register: async(username, password, creationCode) => {
        try {
            const res = await api.post("/auth/register", { username, password, creationCode });
            if(res.status === 201) {
                await get().checkAuth();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    logout: async() => {
        const res = await api.post("/auth/logout");
        if(res.status == 200) {
            set({ isLoggedIn: false, authUser: null, authRole: null });
            toast.success(res.data.message);
        }else{
            toast.error(res.data.message);
        }
    },

    getPatients: async() => {
        try {
            const res = await api.get("/patient/all");
            if(res.status == 200) {
                set({ patients: res.data.results });
            } else if(res.status === 204) {
                set({ patients: [] });
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    getAppointments: async() => {
        try {
            const res = await api.get("/appointment/all");
            if(res.status == 200) {
                // backend returns an array directly for /appointment/all
                // but other endpoints may return { results: [...] }
                const payload = res.data;
                const list = Array.isArray(payload) ? payload : (payload?.results ?? []);
                set({ appointments: list });
            } else if(res.status === 204) {
                set({ appointments: [] });
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    getMedicalReports: async() => {
        const res = await api.get("/medical-report/all");
        if(res.status == 200) {
            set({ medicalReports: res.data });
        }else{
            toast.error(res.data.message);
        }
    },

    getOverallReports: async(startDate, endDate) => {
        try {
            const params = new URLSearchParams();
            if (startDate) params.append("startDate", startDate);
            if (endDate) params.append("endDate", endDate);
            const queryString = params.toString();
            const url = queryString ? `/report/generate?${queryString}` : "/report/generate";
            const res = await api.get(url);
            if(res.status === 200) {
                set({ overallReports: res.data });
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    updatePatient: async(id, fullName, gender, dateOfBirth, phoneNumber, address) => {
        try {
            const res = await api.put("/patient/update/" + id, { full_name: fullName, gender, date_of_birth: dateOfBirth, phone_number: phoneNumber, address });
            if(res.status == 200) {
                await get().getPatients();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    deletePatient: async(id) => {
        try {
            const res = await api.delete("/patient/delete/" + id);
            if(res.status == 200) {
                await get().getPatients();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },
    createPatient: async(fullName, gender, dateOfBirth, phoneNumber, address) => {
        try {
            const res = await api.post("/patient/create", { full_name: fullName, gender, date_of_birth: dateOfBirth, phone_number: phoneNumber, address });
            if(res.status == 201) {
                await get().getPatients();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    createAppointment: async(patient_id, doctor_id, appointment_date, appointment_time, status) => {
        try {
            const res = await api.post("/appointment/create", { patient_id, doctor_id, appointment_date, appointment_time, status });
            if(res.status === 201) {
                await get().getAppointments();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    deleteAppointment: async(id) => {
        try {
            const res = await api.delete("/appointment/delete/" + id);
            if(res.status === 200) {
                await get().getAppointments();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    updateAppointment: async(id, patientId, doctorId, appointmentDate, appointmentTime, status) => {
        try {
            const res = await api.put("/appointment/update/" + id, { patient_id: patientId, doctor_id: doctorId, appointment_date: appointmentDate, appointment_time: appointmentTime, status });
            if(res.status === 200) {
                await get().getAppointments();
                toast.success(res.data.message);
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    getReports: async() => {
        try {
            const res = await api.get("/report/generate");
            if(res.status === 200) {
                set({ overallReports: res.data });
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    createReport: async(appointmentId, diagnosis, prescription) => {
        try {
            // backend expects `perscription` (typo). send both for compatibility.
            const res = await api.post("/medical-report/create", { appointmentId, diagnosis, prescription, perscription: prescription });
            if(res.status == 201) {
                // backend currently returns {message} not reports; just refresh
                await get().getMedicalReports();
                toast.success(res.data.message);
            }else{
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

    deleteReport: async(id) => {
        const res = await api.delete("/medical-report/delete/" + id);
        if(res.status == 200) {
            set({ medicalReports: res.data });
            toast.success(res.data.message);
        }else{
            toast.error(res.data.message);
        }
    },

    updateReport: async(id, appointmentId, diagnosis, prescription) => {
        try {
            const res = await api.put("/medical-report/update/" + id, { appointmentId, diagnosis, prescription, perscription: prescription });
            if(res.status == 200) {
                await get().getMedicalReports();
                toast.success(res.data.message);
            }else{
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },
    getDoctors: async() => {
        try {
            const res = await api.get("/auth/doctors");
            if(res.status == 200) {
                set({ doctors: res.data.doctors });
            } else {
                toast.error(res.data.message);
            }
        } catch (error) {
            console.error(error);
            toast.error("Network error");
        }
    },

}))

export default useStore;