import * as plugins from './plugins.js';
import * as domtools from '@design.estate/dees-domtools';

const appstate = new plugins.deesDomtools.plugins.smartstate.Smartstate();
export interface ILoginState {
  identity: plugins.interfaces.data.IIdentity;
}
export const loginStatePart: plugins.smartstate.StatePart<unknown, ILoginState> = await appstate.getStatePart<ILoginState>(
  'login',
  { identity: null },
  'persistent'
);

export const loginAction = loginStatePart.createAction<{ username: string; password: string }>(
  async (statePartArg, payloadArg) => {
    const currentState = statePartArg.getState();
    const trLogin =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>(
        '/typedrequest',
        'adminLoginWithUsernameAndPassword'
      );
    const response = await trLogin.fire({
      username: payloadArg.username,
      password: payloadArg.password,
    }).catch(err => {
      console.log(err);
      return {
        ...statePartArg.getState(),
      }
    });
    return {
      ...currentState,
      ...(response.identity ? { identity: response.identity } : {}),
    };
  }
);

export const logoutAction = loginStatePart.createAction(async (statePartArg) => {
  const currentState = statePartArg.getState();
  return {
    ...currentState,
    identity: null,
  };
});

export interface IDataState {
  secretGroups?: plugins.interfaces.data.ISecretGroup[];
  secretBundles?: plugins.interfaces.data.ISecretBundle[];
  clusters?: plugins.interfaces.data.ICluster[];
  images?: any[];
  services?: any[];
  deployments?: any[];
  dns?: any[];
  mails?: any[];
  logs?: any[];
  s3?: any[];
  dbs?: any[];
  backups?: any[];
}
export const dataState = await appstate.getStatePart<IDataState>(
  'data',
  {
    secretGroups: [],
    secretBundles: [],
    clusters: [],
    images: [],
    services: [],
    deployments: [],
    dns: [],
    mails: [],
    logs: [],
    s3: [],
    dbs: [],
    backups: [],
  },
  'soft'
);

// Getting data
export const getAllDataAction = dataState.createAction(async (statePartArg) => {
  let currentState = statePartArg.getState();
  // SecretsGroups
  const trGetSecretGroups =
    new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_GetSecretGroups>(
      '/typedrequest',
      'getSecretGroups'
    );
  const response = await trGetSecretGroups.fire({
    identity: loginStatePart.getState().identity,
  });
  currentState = {
    ...currentState,
    secretGroups: response.secretGroups,
  };

  // SecretBundles
  const trGetSecretBundles =
    new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_GetSecretBundles>(
      '/typedrequest',
      'getSecretBundles'
    );
  const responseSecretBundles = await trGetSecretBundles.fire({
    identity: loginStatePart.getState().identity,
  });
  currentState = {
    ...currentState,
    secretBundles: responseSecretBundles.secretBundles,
  };

  // images
  const trGetImages =
    new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_GetAllImages>(
      '/typedrequest',
      'getAllImages'
    );
  const responseImages = await trGetImages.fire({
    identity: loginStatePart.getState().identity,
  });
  currentState = {
    ...currentState,
    images: responseImages.images,
  };

  // Clusters
  const trGetClusters =
    new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IReq_Any_Cloudly_GetClusters>(
      '/typedrequest',
      'getClusters'
    );
  const responseClusters = await trGetClusters.fire({
    identity: loginStatePart.getState().identity,
  });

  currentState = {
    ...currentState,
    clusters: responseClusters.clusters,
  }

  return currentState;
});

// SecretGroup Actions
export const createSecretGroupAction = dataState.createAction(
  async (statePartArg, payloadArg: plugins.interfaces.data.ISecretGroup) => {
    let currentState = statePartArg.getState();
    const trCreateSecretGroup =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_CreateSecretGroup>(
        '/typedrequest',
        'createSecretGroup'
      );
    const response = await trCreateSecretGroup.fire({
      identity: loginStatePart.getState().identity,
      secretGroup: payloadArg,
    });
    currentState = await dataState.dispatchAction(getAllDataAction, null);
    return currentState;
    return currentState;
  }
);

export const deleteSecretGroupAction = dataState.createAction(
  async (statePartArg, payloadArg: { secretGroupId: string }) => {
    let currentState = statePartArg.getState();
    const trDeleteSecretGroup =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretgroup.IReq_DeleteSecretGroupById>(
        '/typedrequest',
        'deleteSecretGroupById'
      );
    const response = await trDeleteSecretGroup.fire({
      identity: loginStatePart.getState().identity,
      secretGroupId: payloadArg.secretGroupId,
    });
    currentState = await dataState.dispatchAction(getAllDataAction, null);
    return currentState;
  }
);

// SecretBundle Actions
export const deleteSecretBundleAction = dataState.createAction(
  async (statePartArg, payloadArg: { configBundleId: string }) => {
    let currentState = statePartArg.getState();
    const trDeleteConfigBundle =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.secretbundle.IReq_DeleteSecretBundleById>( 
        '/typedrequest',
        'deleteSecretBundleById'
      );
    const response = await trDeleteConfigBundle.fire({
      identity: loginStatePart.getState().identity,
      secretBundleId: payloadArg.configBundleId,
    });
    currentState = await dataState.dispatchAction(getAllDataAction, null);
    return currentState;
  }
);

// image actions
export const createImageAction = dataState.createAction(
  async (statePartArg, payloadArg: { imageName: string, description: string }) => {
    let currentState = statePartArg.getState();
    const trCreateImage =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_CreateImage>(
        '/typedrequest',
        'createImage'
      );
    const response = await trCreateImage.fire({
      identity: loginStatePart.getState().identity,
      name: payloadArg.imageName,
      description: payloadArg.description,
    });
    currentState = {
      ...currentState,
      ...{
        images: [...currentState.images, response.image],
      },
    };
    return currentState;
  }
);

export const deleteImageAction = dataState.createAction(
  async (statePartArg, payloadArg: { imageId: string }) => {
    let currentState = statePartArg.getState();
    const trDeleteImage =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.image.IRequest_DeleteImage>(
        '/typedrequest',
        'deleteImage'
      );
    const response = await trDeleteImage.fire({
      identity: loginStatePart.getState().identity,
      imageId: payloadArg.imageId,
    });
    currentState = {
      ...currentState,
      ...{
        images: currentState.images.filter((image) => image.id !== payloadArg.imageId),
      },
    };
    return currentState;
  }
);

// cluster
export const addClusterAction = dataState.createAction(
  async (
    statePartArg,
    payloadArg: {
      clusterName: string;
    }
  ) => {
    let currentState = statePartArg.getState();
    const trAddCluster =
      new domtools.plugins.typedrequest.TypedRequest<plugins.interfaces.requests.cluster.IRequest_CreateCluster>(
        '/typedrequest',
        'createCluster'
      );
    const response = await trAddCluster.fire({
      identity: loginStatePart.getState().identity,
      ...payloadArg,
    });
    currentState = {
      ...currentState,
      ...{
        clusters: [...currentState.clusters, response.cluster],
      },
    }
    return currentState;
  }
);