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

import AlertLink from 'sentry/components/alertLink';
import {Button} from 'sentry/components/button';
import Form from 'sentry/components/forms/form';
import JsonForm from 'sentry/components/forms/jsonForm';
import {PanelAlert} from 'sentry/components/panels';
import PluginList from 'sentry/components/pluginList';
import {fields} from 'sentry/data/forms/projectAlerts';
import {IconMail} from 'sentry/icons';
import {t} from 'sentry/locale';
import {Organization, Plugin, Project} from 'sentry/types';
import routeTitleGen from 'sentry/utils/routeTitle';
import AsyncView from 'sentry/views/asyncView';
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
import PermissionAlert from 'sentry/views/settings/project/permissionAlert';

type RouteParams = {projectId: string};

type Props = RouteComponentProps<RouteParams, {}> &
  AsyncView['props'] & {
    canEditRule: boolean;
    organization: Organization;
  };

type State = AsyncView['state'] & {
  pluginList: Array<Plugin> | null;
  project: Project | null;
};

class Settings extends AsyncView<Props, State> {
  getDefaultState() {
    return {
      ...super.getDefaultState(),
      project: null,
      pluginList: [],
    };
  }

  getProjectEndpoint() {
    const {organization, params} = this.props;
    return `/projects/${organization.slug}/${params.projectId}/`;
  }

  getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
    const {organization, params} = this.props;
    const projectEndpoint = this.getProjectEndpoint();
    return [
      ['project', projectEndpoint],
      ['pluginList', `/projects/${organization.slug}/${params.projectId}/plugins/`],
    ];
  }

  handleEnablePlugin = (plugin: Plugin) => {
    this.setState(prevState => ({
      pluginList: (prevState.pluginList ?? []).map(p => {
        if (p.id !== plugin.id) {
          return p;
        }
        return {
          ...plugin,
          enabled: true,
        };
      }),
    }));
  };

  handleDisablePlugin = (plugin: Plugin) => {
    this.setState(prevState => ({
      pluginList: (prevState.pluginList ?? []).map(p => {
        if (p.id !== plugin.id) {
          return p;
        }
        return {
          ...plugin,
          enabled: false,
        };
      }),
    }));
  };

  getTitle() {
    const {projectId} = this.props.params;
    return routeTitleGen(t('Alerts Settings'), projectId, false);
  }

  renderBody() {
    const {canEditRule, organization} = this.props;
    const {project, pluginList} = this.state;

    if (!project) {
      return null;
    }

    const projectEndpoint = this.getProjectEndpoint();

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

        <Form
          saveOnBlur
          allowUndo
          initialData={{
            subjectTemplate: project.subjectTemplate,
            digestsMinDelay: project.digestsMinDelay,
            digestsMaxDelay: project.digestsMaxDelay,
          }}
          apiMethod="PUT"
          apiEndpoint={projectEndpoint}
        >
          <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={this.handleEnablePlugin}
            onDisablePlugin={this.handleDisablePlugin}
          />
        )}
      </Fragment>
    );
  }
}

export default Settings;