import { useMemo } from 'react';

import { UserMediaAdvancement, UserMediaAdvancementResource } from '@/back-api';
import { useServiceContext } from '@/service/ServiceContext';
import { SessionServiceProps, useSessionService } from '@/service/session';
import { DataStoreType, useDataStore } from '@/utils/data-store';
import { useQueryCall, useQueryCallProps } from '@/utils/query';

export type AdvancementServiceProps = {
  store: DataStoreType<UserMediaAdvancement>;
};

export const useAdvancementService = (): AdvancementServiceProps => {
  const { advancement } = useServiceContext();
  return advancement;
};

export const useAdvancementServiceWrapped = (
  session: SessionServiceProps
): AdvancementServiceProps => {
  const store = useDataStore<UserMediaAdvancement>(
    {
      restApiName: 'Advancement',
      primaryKey: 'id',
      available: session.token !== undefined,
      getsCall: () => {
        return UserMediaAdvancementResource.gets({
          restConfig: session.getRestConfig(),
        });
      },
    },
    [session.token]
  );

  return { store };
};

export const useSpecificAdvancement = (id: number | undefined) => {
  const { store } = useAdvancementService();
  const dataAdvancement = useMemo(() => {
    return store.get(id);
  }, [store.data, id]);
  return { dataAdvancement };
};

export type updateTimeProps = {
  time: number;
  total: number;
  addCount: boolean;
}

export const useAdvancementUpdateTime = (id: number,
  config: Omit<useQueryCallProps<UserMediaAdvancement, updateTimeProps>, 'queryFunction'>
    = {}) => {
  const { store } = useAdvancementService();

  const { onSuccess, ...restConfig } = config;
  const { getRestConfig } = useSessionService();
  const { call, ...rest } = useQueryCall<
    UserMediaAdvancement,
    updateTimeProps
  >({
    queryFunction: (inputData) => {
      const data = {
        time: inputData.time,
        percent: inputData.time / inputData.total,
        addCount: inputData.addCount
      };
      return UserMediaAdvancementResource.patch({
        restConfig: getRestConfig(),
        params: {
          id
        },
        data
      });
    },
    onSuccess: (response) => {
      if (onSuccess) {
        onSuccess(response);
      }
      store.updateRaw(response);
    },
    ...restConfig,
  });
  return { updateTime: call, ...rest };
};
