import {
  getApiService,
  getApiServices,
  patchToggleApiService,
  postApiService,
  putApiService,
  type CreateApiServiceRequest,
  type UpdateApiServiceRequest,
} from "@/api/admin/apiServices";
import type { ApiService, ApiServiceCredentials } from "@/types";
import { create } from "zustand";

interface IApiServicesState {
  apiServices: ApiService[];
  loading: boolean;

  createdCredentials: ApiServiceCredentials | null;
  creating: boolean;

  view: ApiService | null;
  fetching: boolean;

  fetch: () => Promise<void>;
  fetchSingle: (id: string) => Promise<void>;
  create: (req: CreateApiServiceRequest) => Promise<void>;
  resetCredentials: () => void;

  toggling: boolean;
  toggle: () => Promise<void>;

  update: (req: UpdateApiServiceRequest) => Promise<void>;
  updating: boolean;
  updated: boolean;

  resetUpdated: () => void;
}

export const useApiServices = create<IApiServicesState>((set, get) => ({
  apiServices: [],
  loading: false,

  createdCredentials: null,
  creating: false,

  view: null,
  fetching: false,

  toggling: false,

  updating: false,
  updated: false,
  resetUpdated: () => set({ updated: false }),

  resetCredentials: () => set({ createdCredentials: null }),

  fetch: async () => {
    set({ loading: true });

    try {
      const response = await getApiServices();
      set({ apiServices: response.items });
    } catch (err) {
      console.log("ERR: Failed to fetch services:", err);
    } finally {
      set({ loading: false });
    }
  },

  fetchSingle: async (id: string) => {
    set({ fetching: true });

    try {
      const response = await getApiService(id);
      set({ view: response });
    } catch (err) {
      console.log("ERR: Failed to fetch services:", err);
    } finally {
      set({ fetching: false });
    }
  },

  update: async (req: UpdateApiServiceRequest) => {
    const viewService = get().view;
    if (!viewService) return;

    set({ updating: true });

    try {
      await putApiService(viewService.id, req);
      get().fetchSingle(viewService.id);
      set({ updated: true });
    } catch (err) {
      console.log("ERR: Failed to toggle service:", err);
    } finally {
      set({ updating: false });
    }
  },

  toggle: async () => {
    const viewService = get().view;
    if (!viewService) return;

    set({ toggling: true });

    try {
      await patchToggleApiService(viewService.id);
      get().fetchSingle(viewService.id);
    } catch (err) {
      console.log("ERR: Failed to toggle service:", err);
    } finally {
      set({ toggling: false });
    }
  },

  create: async (req: CreateApiServiceRequest) => {
    set({ creating: true });

    try {
      const response = await postApiService(req);
      set({ createdCredentials: response.credentials });
    } catch (err) {
      console.log("ERR: Failed to fetch services:", err);
    } finally {
      set({ creating: false });
    }
  },
}));
