import { code } from 'dashboard/generated/controlplane';
import { createSubscriptions } from 'dashboard/generated/controlplane/twirp';
import * as _ from 'lodash';
import { TwirpHTTPError } from 'pbjs-twirp';
import { useEffect, useState } from 'react';
import { GetControlplaneEndpoint } from './env';

import twirp = code.justin.tv.eventbus.controlplane;

export const useSubscriptions = (targetId: string) => {
  const [subscriptions, setSubscriptions] = useState(
    new Array<twirp.ISubscription>(),
  );
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);
  const [forbidden, setForbidden] = useState(false);

  const getSubscriptionsForTarget = new twirp.GetSubscriptionsForTargetReq({
    targetId,
  });

  const client = createSubscriptions(GetControlplaneEndpoint());

  useEffect(() => {
    if (!targetId) {
      return;
    }
    const fetchData = async () => {
      try {
        const resp = await client.getSubscriptionsForTarget(
          getSubscriptionsForTarget,
        );
        setSubscriptions(resp.subscriptions);
        setLoading(false);
      } catch (err) {
        if (
          err instanceof TwirpHTTPError &&
          (err as TwirpHTTPError).status === 403
        ) {
          setLoading(false);
          setForbidden(true);
        } else {
          setLoading(false);
          setError(err);
        }
      }
    };
    fetchData();
  }, [targetId]);

  return { subscriptions, loading, error, forbidden };
};

export const createSubscription = async (
  subscription: twirp.ISubscription,
  success: (s: twirp.ISubscription) => void,
  error: (e: Error) => void,
) => {
  const client = createSubscriptions(GetControlplaneEndpoint());
  const req: twirp.ICreateSubscriptionReq = {
    targetId: subscription.targetId,
    eventType: subscription.eventType,
    environment: subscription.environment,
  };
  try {
    const resp = await client.create(req);
    if (_.isNil(resp.subscription)) {
      throw new Error('unexpected nil in create response');
    }
    success(resp.subscription);
  } catch (e) {
    error(e);
  }
};

export const deleteSubscription = async (
  subscription: twirp.ISubscription,
  success: (s: twirp.ISubscription) => void,
  error: (e: Error) => void,
) => {
  const client = createSubscriptions(GetControlplaneEndpoint());
  const req: twirp.IDeleteSubscriptionReq = {
    targetId: subscription.targetId,
    eventType: subscription.eventType,
    environment: subscription.environment,
  };
  try {
    await client.delete(req);
    success(subscription);
  } catch (e) {
    error(e);
  }
};
