import { useMutation, useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import z from 'zod';
import { m } from '../../../paraglide/messages';
import api from '../../../shared/api/api';
import type { Settings } from '../../../shared/api/types';
import { Controls } from '../../../shared/components/Controls/Controls';
import { SettingsCard } from '../../../shared/components/SettingsCard/SettingsCard';
import { SettingsHeader } from '../../../shared/components/SettingsHeader/SettingsHeader';
import { SettingsLayout } from '../../../shared/components/SettingsLayout/SettingsLayout';
import { Suggestion } from '../../../shared/components/Suggestion/Suggestion';
import { Button } from '../../../shared/defguard-ui/components/Button/Button';
import { Divider } from '../../../shared/defguard-ui/components/Divider/Divider';
import { Fold } from '../../../shared/defguard-ui/components/Fold/Fold';
import { Icon } from '../../../shared/defguard-ui/components/Icon';
import { SizedBox } from '../../../shared/defguard-ui/components/SizedBox/SizedBox';
import { Snackbar } from '../../../shared/defguard-ui/providers/snackbar/snackbar';
import { ThemeSpacing, ThemeVariable } from '../../../shared/defguard-ui/types';
import { isPresent } from '../../../shared/defguard-ui/utils/isPresent';
import { useAppForm } from '../../../shared/form';
import { formChangeLogic } from '../../../shared/formLogic';
import { getSettingsQueryOptions } from '../../../shared/query';

const messageTemplatesHelpVariables = [
  ['{{ first_name }}', m.settings_enrollment_template_help_first_name()],
  ['{{ last_name }}', m.settings_enrollment_template_help_last_name()],
  ['{{ username }}', m.settings_enrollment_template_help_username()],
  ['{{ admin_first_name }}', m.settings_enrollment_template_help_admin_first_name()],
  ['{{ admin_last_name }}', m.settings_enrollment_template_help_admin_last_name()],
  ['{{ admin_phone }}', m.settings_enrollment_template_help_admin_phone()],
  ['{{ admin_email }}', m.settings_enrollment_template_help_admin_email()],
  ['{{ defguard_url }}', m.settings_enrollment_template_help_defguard_url()],
  ['{{ defguard_version }}', m.settings_enrollment_template_help_defguard_version()],
] as const;

const messageTemplatesHelpMarkdown = [
  ['#, ##', m.settings_enrollment_template_help_markdown_headings(), 'medium'],
  ['**text**', m.settings_enrollment_template_help_markdown_bold()],
  ['- item', m.settings_enrollment_template_help_markdown_lists()],
  ['[text](url)', m.settings_enrollment_template_help_markdown_link()],
] as const;

const messageTemplatesFormSchema = z.object({
  enrollment_display_welcome_message: z.boolean(),
  enrollment_welcome_message: z.string(m.form_error_required()),
  enrollment_send_welcome_email: z.boolean(),
  enrollment_welcome_email_subject: z.string().min(1, m.form_error_required()),
  enrollment_use_welcome_message_as_email: z.boolean(),
  enrollment_welcome_email: z.string(m.form_error_required()),
});

type MessageTemplatesFormFields = z.infer<typeof messageTemplatesFormSchema>;

export const MessageTemplatesTab = () => {
  const { data: settings } = useQuery(getSettingsQueryOptions);

  if (!isPresent(settings)) {
    return null;
  }

  return <MessageTemplatesTabContent settings={settings} />;
};

const MessageTemplatesTabContent = ({ settings }: { settings: Settings }) => {
  const { mutateAsync } = useMutation({
    mutationFn: api.settings.patchSettings,
    meta: {
      invalidate: ['settings'],
    },
    onSuccess: () => {
      Snackbar.default(m.settings_msg_saved());
    },
    onError: () => {
      Snackbar.error(m.settings_msg_save_failed());
    },
  });

  const defaultValues = useMemo(
    (): MessageTemplatesFormFields => ({
      enrollment_display_welcome_message: true,
      enrollment_welcome_message: settings.enrollment_welcome_message ?? '',
      enrollment_send_welcome_email: settings.enrollment_send_welcome_email ?? true,
      enrollment_welcome_email_subject: settings.enrollment_welcome_email_subject ?? '',
      enrollment_use_welcome_message_as_email:
        settings.enrollment_use_welcome_message_as_email ?? true,
      enrollment_welcome_email: settings.enrollment_welcome_email ?? '',
    }),
    [settings],
  );

  const form = useAppForm({
    defaultValues,
    validationLogic: formChangeLogic,
    validators: {
      onSubmit: messageTemplatesFormSchema,
      onChange: messageTemplatesFormSchema,
    },
    onSubmit: async ({ value }) => {
      const { enrollment_display_welcome_message: _displayWelcomeMessage, ...payload } =
        value;
      await mutateAsync(payload);
      form.reset(value);
    },
  });

  return (
    <SettingsLayout suggestion={<MessageTemplatesSuggestion />}>
      <div data-testid="enrollment-tab-message-templates">
        <div>
          <SettingsHeader
            icon="file-add"
            title={m.settings_enrollment_message_templates_title()}
            subtitle={m.settings_enrollment_message_templates_subtitle()}
          />
          <SettingsCard>
            <form
              onSubmit={(e) => {
                e.stopPropagation();
                e.preventDefault();
                form.handleSubmit();
              }}
            >
              <form.AppForm>
                <div>
                  <form.AppField name="enrollment_display_welcome_message">
                    {(field) => (
                      <field.FormInteractiveBlock
                        variant="empty"
                        title={m.settings_enrollment_template_display_message_title()}
                        content={m.settings_enrollment_template_display_message_description()}
                      >
                        <SizedBox height={ThemeSpacing.Xl2} />
                        <form.AppField name="enrollment_welcome_message">
                          {(field) => (
                            <field.FormTextarea
                              required
                              label={m.settings_enrollment_template_message_label()}
                              minHeight={383}
                              maxHeight={383}
                              helper={m.settings_enrollment_template_helper_welcome_message()}
                            />
                          )}
                        </form.AppField>
                        <Divider spacing={ThemeSpacing.Xl2} />
                      </field.FormInteractiveBlock>
                    )}
                  </form.AppField>
                </div>
                <div>
                  <form.AppField name="enrollment_send_welcome_email">
                    {(field) => {
                      const sendWelcomeEmail = Boolean(field.state.value);

                      return (
                        <field.FormInteractiveBlock
                          variant="toggle"
                          title={m.settings_enrollment_template_send_email_title()}
                          content={m.settings_enrollment_template_send_email_description()}
                        >
                          <Fold open={sendWelcomeEmail}>
                            <SizedBox height={ThemeSpacing.Xl2} />
                            <form.AppField name="enrollment_welcome_email_subject">
                              {(field) => (
                                <field.FormInput
                                  required
                                  label={m.settings_enrollment_template_email_subject_label()}
                                  helper={m.settings_enrollment_template_helper_email_subject()}
                                />
                              )}
                            </form.AppField>
                            <SizedBox height={ThemeSpacing.Xl} />
                            <div>
                              <form.AppField name="enrollment_use_welcome_message_as_email">
                                {(field) => {
                                  const sameAsWelcomeMessage = Boolean(field.state.value);

                                  return (
                                    <>
                                      <field.FormCheckbox
                                        text={m.settings_enrollment_template_same_as_message()}
                                      />
                                      <SizedBox height={ThemeSpacing.Xl} />
                                      <Fold
                                        open={sameAsWelcomeMessage}
                                        className="message-template-fold"
                                      >
                                        <div className="message-templates-success-banner">
                                          <Icon
                                            icon="check-circle"
                                            staticColor={ThemeVariable.FgSuccess}
                                            size={20}
                                          />
                                          <p className="copy">
                                            {m.settings_enrollment_template_same_as_message_banner()}
                                          </p>
                                        </div>
                                      </Fold>
                                      <Fold
                                        open={!sameAsWelcomeMessage}
                                        className="message-template-fold"
                                      >
                                        <form.AppField name="enrollment_welcome_email">
                                          {(field) => (
                                            <field.FormTextarea
                                              required
                                              label={m.settings_enrollment_template_email_label()}
                                              minHeight={383}
                                              maxHeight={383}
                                              helper={m.settings_enrollment_template_helper_email_body()}
                                            />
                                          )}
                                        </form.AppField>
                                      </Fold>
                                    </>
                                  );
                                }}
                              </form.AppField>
                            </div>
                          </Fold>
                        </field.FormInteractiveBlock>
                      );
                    }}
                  </form.AppField>
                </div>
              </form.AppForm>
              <SizedBox height={ThemeSpacing.Xl2} />
              <Divider />
              <SizedBox height={ThemeSpacing.Xl} />
              <form.Subscribe
                selector={(state) => ({
                  isDefault: state.isDefaultValue || state.isPristine,
                  isSubmitting: state.isSubmitting,
                  canSubmit: state.canSubmit,
                })}
              >
                {({ isDefault, isSubmitting, canSubmit }) => (
                  <Controls>
                    <div className="right">
                      <Button
                        variant="primary"
                        text={m.controls_save_changes()}
                        disabled={isDefault || !canSubmit}
                        loading={isSubmitting}
                        type="submit"
                        onClick={() => {
                          form.handleSubmit();
                        }}
                      />
                    </div>
                  </Controls>
                )}
              </form.Subscribe>
            </form>
          </SettingsCard>
        </div>
      </div>
    </SettingsLayout>
  );
};

const MessageTemplatesSuggestion = () => {
  return (
    <Suggestion
      title={m.settings_enrollment_template_help_title()}
      content={
        <>
          <ul className="sidebar-list">
            {messageTemplatesHelpVariables.map(([token, description]) => (
              <li key={token}>
                <span className="sidebar-token">{token}</span>
                <span className="sidebar-separator"> - </span>
                <span>{description}</span>
              </li>
            ))}
          </ul>
          <SizedBox height={ThemeSpacing.Lg} />
          <Divider />
          <SizedBox height={ThemeSpacing.Lg} />
          <ul className="sidebar-list">
            {messageTemplatesHelpMarkdown.map(([token, description, weight]) => (
              <li key={token}>
                <span
                  className={
                    weight === 'medium' ? 'sidebar-token-medium' : 'sidebar-token'
                  }
                >
                  {token}
                </span>
                <span className="sidebar-separator"> - </span>
                <span>{description}</span>
              </li>
            ))}
          </ul>
        </>
      }
    />
  );
};
