import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { sendRpcRequest } from "../../services/apiClient";
import type { IPaymentMethod, ITariff } from "../../types/billing.types";

interface IBillingState {
  tariffs: ITariff[];
  isTariffsLoading: boolean;
  tariffsError: string | null;
  paymentMethods: IPaymentMethod[];
  isPaymentMethodsLoading: boolean;
  paymentMethodsError: string | null;
  payUrl: string;
  isPayLoading: boolean;
}

const initialState: IBillingState = {
  tariffs: [],
  isTariffsLoading: false,
  tariffsError: null,
  paymentMethods: [],
  isPaymentMethodsLoading: false,
  paymentMethodsError: null,
  payUrl: "",
  isPayLoading: false,
};

export const fetchTariffs = createAsyncThunk(
  "billing/fetchTariffs",
  async (_, { rejectWithValue }) => {
    try {
      const response = await sendRpcRequest<{ list: ITariff[] }>(
        "billing.tariffs"
      );

      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 fetchPaymentMethods = createAsyncThunk(
  "billing/fetchPaymentMethods",
  async (_, { rejectWithValue }) => {
    try {
      const response = await sendRpcRequest<{ list: IPaymentMethod[] }>(
        "billing.paymentMethods"
      );

      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 pay = createAsyncThunk(
  "billing/pay",
  async (
    {
      payMonths,
      paymentMethodId,
    }: { payMonths: string; paymentMethodId: string },
    { rejectWithValue }
  ) => {
    try {
      const response = await sendRpcRequest<{ url: string }>("billing.pay", {
        methodId: paymentMethodId,
        months: payMonths,
      });

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

const billingSlice = createSlice({
  name: "billing",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchTariffs.pending, (state) => {
        state.isTariffsLoading = true;
        state.tariffsError = null;
      })
      .addCase(fetchTariffs.fulfilled, (state, action) => {
        state.isTariffsLoading = false;
        state.tariffs = action.payload;
      })
      .addCase(fetchTariffs.rejected, (state, action) => {
        state.isTariffsLoading = false;
        state.tariffsError = action.payload as string;
      })

      .addCase(fetchPaymentMethods.pending, (state) => {
        state.isPaymentMethodsLoading = true;
        state.paymentMethodsError = null;
      })
      .addCase(fetchPaymentMethods.fulfilled, (state, action) => {
        state.isPaymentMethodsLoading = false;
        state.paymentMethods = action.payload;
      })
      .addCase(fetchPaymentMethods.rejected, (state, action) => {
        state.isPaymentMethodsLoading = false;
        state.paymentMethodsError = action.payload as string;
      })

      .addCase(pay.pending, (state) => {
        state.isPayLoading = true;
        state.payUrl = "";
      })
      .addCase(pay.fulfilled, (state, action) => {
        state.isPayLoading = false;
        state.payUrl = action.payload;
      })
      .addCase(pay.rejected, (state, action) => {
        state.isPayLoading = false;
        state.payUrl = action.payload as string;
      });
  },
});

export default billingSlice.reducer;
