// hospitalSlice.ts
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import api from '@/lib/axios';
import { toast } from 'sonner';
import messages from '../../../messages/en.json';
import { handleToastError } from '@/lib/utils';

// Type definitions
export interface Hospital {
    id: number;
    name: string;
    address: string;
    city_id: number;
    state_id: number;
    country_id: number;
    zip_code: string;
    phone_number?: string;
    email?: string;
    is_partner: boolean;
    status: 'active' | 'inactive';
    contacts: Contact[];
    customer: Customer[];
    customer_count: number;
    created_at: string;
    updated_at: string;
    state?: State;
    city?: City;
}

export interface State {
    id: number;
    name: string;
}

export interface City {
    id: number;
    name: string;
    state_id: number;
}

export interface Contact {
    id: number;
    name: string;
    position?: string;
    department?: string;
    phone_number: string;
    email: string;
    is_primary: boolean;
}

export interface Customer {
    id: number;
    customer_name: string;
}

export interface AddOrUpdateHospitalPayload {
    name: string;
    address: string;
    city_id: number;
    state_id: number;
    country_id: number;
    country_code: string;
    zip_code: string;
    phone_number?: string;
    email?: string;
    is_partner: boolean;
    status: 'active' | 'inactive';
    latitude?: number;
    longitude?: number;
    place_id?: string;
    primaryContact?: {
        name: string;
        phone_number: string;
        email: string;
        position?: string;
        department?: string;
        is_primary: boolean;
    };
}

interface HospitalState {
    items: Hospital[];
    totalCount: number;
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    error: string | null;
    filters: {
        search: string;
        limit: number;
        skip: number;
        state_id: string;
        city: string;
    };
}

const initialState: HospitalState = {
    items: [],
    totalCount: 0,
    status: 'idle',
    error: null,
    filters: {
        search: '',
        limit: 10,
        skip: 0,
        state_id: 'all',
        city: 'all',
    },
};

// Async thunks
export const fetchHospitals = createAsyncThunk('hospitals/fetch', async (params: any, { rejectWithValue }) => {
    try {
        const response = await api.get('/hospitals', { params });
        return response.data.data;
    } catch (err) {
        return rejectWithValue('Failed to fetch hospitals');
    }
});

export const addHospital = createAsyncThunk('hospitals/add', async (payload: AddOrUpdateHospitalPayload, { rejectWithValue }) => {
    try {
        const response = await api.post('/hospitals', payload);
        handleToastError(response);
        return response;
    } catch (err) {
        return rejectWithValue('Failed to add hospital');
    }
});

export const updateHospital = createAsyncThunk(
    'hospitals/update',
    async ({ id, data }: { id: number; data: Partial<AddOrUpdateHospitalPayload> }, { rejectWithValue }) => {
        try {
            const response = await api.patch(`/hospitals/${id}`, data);
            handleToastError(response);
            return response;
        } catch (err) {
            return rejectWithValue('Failed to update hospital');
        }
    },
);

export const getHospitalById = createAsyncThunk('hospitals/getById', async (id: number, { rejectWithValue }) => {
    try {
        const response = await api.get(`/hospitals/${id}`);
        return response.data;
    } catch (err) {
        return rejectWithValue('Failed to fetch hospital');
    }
});

export const deleteHospital = createAsyncThunk('hospitals/delete', async (id: number, { rejectWithValue }) => {
    try {
        const response = await api.delete(`/hospitals/${id}`);
        return response.data.code === 200 ? id : rejectWithValue('Delete failed');
    } catch (err) {
        return rejectWithValue('Failed to delete hospital');
    }
});

// Slice
const hospitalSlice = createSlice({
    name: 'hospitals',
    initialState,
    reducers: {
        setFilters(state, action: PayloadAction<Partial<HospitalState['filters']>>) {
            state.filters = { ...state.filters, ...action.payload };
        },
        resetFilters(state) {
            state.filters = initialState.filters;
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(fetchHospitals.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchHospitals.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.items = action.payload.data;
                state.totalCount = action.payload.count;
            })
            .addCase(fetchHospitals.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.payload as string;
            })
            .addCase(addHospital.fulfilled, (state, action) => {
                state.status = 'succeeded';
            })
            .addCase(addHospital.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(updateHospital.fulfilled, (state, action) => {
                state.status = 'succeeded';
            })
            .addCase(updateHospital.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(deleteHospital.fulfilled, (state, action) => {
                state.items = state.items.filter((item) => item.id !== action.payload);
                toast.success(messages.toasts.success.hospital_deleted);
            })
            .addCase(deleteHospital.rejected, (_, action) => {
                toast.error(action.payload as string);
            })
            .addCase(getHospitalById.fulfilled, (state, action) => {
                state.status = 'succeeded';
            })
            .addCase(getHospitalById.rejected, (_, action) => {
                toast.error(action.payload as string);
            });
    },
});

export const { setFilters, resetFilters } = hospitalSlice.actions;
export default hospitalSlice.reducer;
