import api from '@/lib/axios';
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { createKey } from 'next/dist/shared/lib/router/router';
import { toast } from 'sonner';
import messages from '../../../messages/en.json';

// Define types
interface Address {
    line1: string;
    line2: string;
    country: string;
    state: string;
    city: string;
    zipcode: string;
}

export interface ClientCompany {
    id: number;
    name: string;
    clientTypeId: number;
    clientTypeName: string;
    address: Address;
    countryCode: string;
    phoneNumber: string;
    email: string;
    website: string;
    allowPlatformAccess: boolean;
    contactsCount: number;
    hasContract: boolean;
}

interface ClientCompaniesState {
    items: ClientCompany[];
    details: ClientCompany | null;
    dropdown: ClientCompany[];
    count: number;
    status: 'idle' | 'loading' | 'succeeded' | 'failed';
    error: string | null;
}

// Initial state
const initialState: ClientCompaniesState = {
    items: [],
    dropdown: [],
    details: null,
    count: 0,
    status: 'idle',
    error: null,
};

// Async thunks
export const fetchClientCompanies = createAsyncThunk(
    'clientCompanies/fetchClientCompanies',
    async (params: any, { rejectWithValue }) => {
        try {
            const response = await api.get('/clients', { params });
            return response?.data?.data;
        } catch (error) {
            return rejectWithValue('Failed to fetch client companies');
        }
    },
);

export const fetchClientCompaniesWithDropdown = createAsyncThunk(
    'clientCompanies/fetchClientCompaniesDropdown',
    async (params: any, { rejectWithValue }) => {
        try {
            const response = await api.get('/clients/dropdown', { params });

            return response?.data;
        } catch (error) {
            return rejectWithValue('Failed to fetch client companies');
        }
    },
);

export const fetchClientCompaniesDetails = createAsyncThunk(
    'clientCompanies/fetchClientCompaniesDetails',
    async (id: any, { rejectWithValue }) => {
        try {
            const response = await api.get(`/clients/${id}`);
            return response;
        } catch (error) {
            return rejectWithValue('Failed to fetch client companies details');
        }
    },
);

export const addClientCompany = createAsyncThunk(
    'clientCompanies/addClientCompany',
    async (payload: any, { rejectWithValue }) => {
        try {
            const response = await api.post('/clients', payload);

            return response;
        } catch (error) {
            return rejectWithValue('Failed to add client companies');
        }
    },
);

export const updateClientCompany = createAsyncThunk(
    'clientCompanies/updateClientCompany',
    async ({ id, payload }: any, { rejectWithValue }) => {
        try {
            const response = await api.patch(`/clients/${id}`, payload);

            return response;
        } catch (error) {
            return rejectWithValue('Failed to update client companies');
        }
    },
);

export const deleteClientCompany = createAsyncThunk(
    'clientCompanies/deleteClientCompany',
    async ({ clientId }: any, { rejectWithValue }) => {
        try {
            const response = await api.delete(`/clients/${clientId}`);
            return response;
        } catch (error) {
            return rejectWithValue('Failed to update client companies');
        }
    },
);

// Create slice
const clientCompaniesSlice = createSlice({
    name: 'clientCompanies',
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        builder
            .addCase(fetchClientCompanies.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchClientCompanies.fulfilled, (state: any, action) => {
                state.status = 'succeeded';
                state.count = action.payload.count;
                state.items = action.payload?.data;
            })
            .addCase(fetchClientCompanies.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.error.message || null;
            })
            .addCase(addClientCompany.fulfilled, (state, action) => {
                const code = action.payload?.data?.code;
                if (code === 200) {
                    toast.success(messages.toasts.success.company_added);
                } else if (code === 422) {
                    toast.error(action.payload?.data?.message || messages.toasts.error.failed_to_add_company);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
            })
            .addCase(updateClientCompany.fulfilled, (state, action) => {
                const code = action.payload?.data?.code;
                if (code === 200) {
                    toast.success(messages.toasts.success.company_updated);
                } else if (code === 422) {
                    toast.error(action.payload?.data?.message || messages.toasts.error.failed_to_update_company);
                } else {
                    toast.error(messages.toasts.error.generic);
                }
            })
            .addCase(fetchClientCompaniesDetails.pending, (state) => {
                state.status = 'loading';
            })
            .addCase(fetchClientCompaniesDetails.fulfilled, (state: any, action) => {
                state.status = 'succeeded';
                state.details = action.payload?.data?.data;
            })
            .addCase(fetchClientCompaniesDetails.rejected, (state) => {
                state.status = 'failed';
            })
            .addCase(fetchClientCompaniesWithDropdown.pending, (state, action: any) => {
                state.status = 'failed';
                state.error = null;
            })
            .addCase(fetchClientCompaniesWithDropdown.fulfilled, (state: any, action) => {
                state.status = 'succeeded';
                state.count = action.payload.count;
                state.dropdown = action.payload?.data;
            })
            .addCase(fetchClientCompaniesWithDropdown.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.error.message || null;
            });
    },
});

export default clientCompaniesSlice.reducer;
