import {Fragment} from 'react';
import type {RouteComponentProps} from 'react-router';

import AlertLink from 'sentry/components/alertLink';
import {LinkButton} from 'sentry/components/button';
import Form from 'sentry/components/forms/form';
import JsonForm from 'sentry/components/forms/jsonForm';
import LoadingError from 'sentry/components/loadingError';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import PanelAlert from 'sentry/components/panels/panelAlert';
import PluginList from 'sentry/components/pluginList';
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
import {fields} from 'sentry/data/forms/projectAlerts';
import {IconMail} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {Plugin} from 'sentry/types/integrations';
import type {Project} from 'sentry/types/project';
import type {ApiQueryKey} from 'sentry/utils/queryClient';
import {setApiQueryData, useApiQuery, useQueryClient} from 'sentry/utils/queryClient';
import routeTitleGen from 'sentry/utils/routeTitle';
import useOrganization from 'sentry/utils/useOrganization';
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
import PermissionAlert from 'sentry/views/settings/project/permissionAlert';

interface ProjectAlertSettingsProps extends RouteComponentProps<{projectId: string}, {}> {
  canEditRule: boolean;
}

function makeFetchProjectPluginsQueryKey(
  organizationSlug: string,
  projectSlug: string
): ApiQueryKey {
  return [`/projects/${organizationSlug}/${projectSlug}/plugins/`];
}

function ProjectAlertSettings({canEditRule, params}: ProjectAlertSettingsProps) {
  const organization = useOrganization();
  const queryClient = useQueryClient();

  const projectSlug = params.projectId;
  const {
    data: project,
    isLoading: isProjectLoading,
    isError: isProjectError,
    refetch: refetchProject,
  } = useApiQuery<Project>([`/projects/${organization.slug}/${projectSlug}/`], {
    staleTime: 0,
    cacheTime: 0,
  });
  const {
    data: pluginList = [],
    isLoading: isPluginListLoading,
    isError: isPluginListError,
    refetch: refetchPluginList,
  } = useApiQuery<Plugin[]>(
    makeFetchProjectPluginsQueryKey(organization.slug, projectSlug),
    {staleTime: 0, cacheTime: 0}
  );

  if ((!isProjectLoading && !project) || isPluginListError || isProjectError) {
    return (
      <LoadingError
        onRetry={() => {
          isProjectError && refetchProject();
          isPluginListError && refetchPluginList();
        }}
      />
    );
  }

  const updatePlugin = (plugin: Plugin, enabled: boolean) => {
    setApiQueryData<Plugin[]>(
      queryClient,
      makeFetchProjectPluginsQueryKey(organization.slug, projectSlug),
      oldState =>
        oldState.map(p => {
          if (p.id !== plugin.id) {
            return p;
          }
          return {
            ...plugin,
            enabled,
          };
        })
    );
  };

  const handleEnablePlugin = (plugin: Plugin) => {
    updatePlugin(plugin, true);
  };

  const handleDisablePlugin = (plugin: Plugin) => {
    updatePlugin(plugin, false);
  };

  return (
    <Fragment>
      <SentryDocumentTitle
        title={routeTitleGen(t('Alerts Settings'), projectSlug, false)}
      />
      <SettingsPageHeader
        title={t('Alerts Settings')}
        action={
          <LinkButton
            to={{
              pathname: `/organizations/${organization.slug}/alerts/rules/`,
              query: {project: project?.id},
            }}
            size="sm"
          >
            {t('View Alert Rules')}
          </LinkButton>
        }
      />
      <PermissionAlert project={project} />
      <AlertLink to="/settings/account/notifications/" icon={<IconMail />}>
        {t(
          'Looking to fine-tune your personal notification preferences? Visit your Account Settings'
        )}
      </AlertLink>

      {isProjectLoading || isPluginListLoading ? (
        <LoadingIndicator />
      ) : (
        <Fragment>
          <Form
            saveOnBlur
            allowUndo
            initialData={{
              subjectTemplate: project.subjectTemplate,
              digestsMinDelay: project.digestsMinDelay,
              digestsMaxDelay: project.digestsMaxDelay,
            }}
            apiMethod="PUT"
            apiEndpoint={`/projects/${organization.slug}/${project.slug}/`}
          >
            <JsonForm
              disabled={!canEditRule}
              title={t('Email Settings')}
              fields={[fields.subjectTemplate]}
            />

            <JsonForm
              title={t('Digests')}
              disabled={!canEditRule}
              fields={[fields.digestsMinDelay, fields.digestsMaxDelay]}
              renderHeader={() => (
                <PanelAlert type="info">
                  {t(
                    'Sentry will automatically digest alerts sent by some services to avoid flooding your inbox with individual issue notifications. To control how frequently notifications are delivered, use the sliders below.'
                  )}
                </PanelAlert>
              )}
            />
          </Form>

          {canEditRule && (
            <PluginList
              organization={organization}
              project={project}
              pluginList={(pluginList ?? []).filter(
                p => p.type === 'notification' && p.hasConfiguration
              )}
              onEnablePlugin={handleEnablePlugin}
              onDisablePlugin={handleDisablePlugin}
            />
          )}
        </Fragment>
      )}
    </Fragment>
  );
}

export default ProjectAlertSettings;