import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { sendRpcRequest } from "../../services/apiClient";
import type { IDevice } from "../../types/device.types";

interface IDeviceData {
  bat_level: string;
  location: {
    lat: string;
    lon: string;
    speed: string;
  };
}

interface IDeviceState {
  devices: IDevice[];
  deviceData: IDeviceData | null;
  selectedDevice: IDevice | null;
  loadingDevices: boolean;
  errorDevices: string;
}

const initialState: IDeviceState = {
  devices: [],
  deviceData: null,
  selectedDevice: null,
  loadingDevices: false,
  errorDevices: "",
};

export const fetchDevices = createAsyncThunk(
  "device/fetchDevices",
  async (_, { rejectWithValue }) => {
    try {
      const response = await sendRpcRequest<{ list: IDevice[] }>(
        "devices.getlist"
      );

      return response.list;
    } catch (error: unknown) {
      if (typeof error === "object" && error !== null && "message" in error) {
        return rejectWithValue(error.message);
      }

      return rejectWithValue("Unknown error occurred");
    }
  }
);

export const fetchDeviceData = createAsyncThunk(
  "device/fetchDeviceData",
  async (deviceId: string, { rejectWithValue }) => {
    try {
      const response = await sendRpcRequest<IDeviceData>(
        "devices.getdevicedata",
        {
          deviceId,
        }
      );

      return response;
    } catch (error: unknown) {
      if (typeof error === "object" && error !== null && "message" in error) {
        return rejectWithValue(error.message);
      }

      return rejectWithValue("Unknown error occurred");
    }
  }
);

const deviceSlice = createSlice({
  name: "device",
  initialState,
  reducers: {
    setSelectedDevice: (state, action) => {
      const selected = state.devices.find((d) => d.id === action.payload);
      state.selectedDevice = selected ?? null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchDevices.pending, (state) => {
        state.loadingDevices = true;
      })
      .addCase(fetchDevices.fulfilled, (state, action) => {
        state.loadingDevices = false;
        state.devices = action.payload;
        state.selectedDevice = action.payload[0] ?? null;
      })
      .addCase(fetchDevices.rejected, (state, action) => {
        state.loadingDevices = false;
        state.errorDevices = action.payload as string;
      })

      .addCase(fetchDeviceData.fulfilled, (state, action) => {
        state.deviceData = action.payload;
      });
  },
});

export const { setSelectedDevice } = deviceSlice.actions;
export default deviceSlice.reducer;
