import { css } from '@emotion/css';
import { skipToken } from '@reduxjs/toolkit/query';
import { useState } from 'react';

import { type GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { config } from '@grafana/runtime';
import { Stack, useStyles2 } from '@grafana/ui';
import { type Repository, useGetFrontendSettingsQuery } from 'app/api/clients/provisioning/v0alpha1';

import { CloudInfoBox } from '../Shared/CloudInfoBox';
import provisioningSvg from '../img/provisioning.svg';

import { EnhancedFeatures } from './EnhancedFeatures';
import { FeaturesList } from './FeaturesList';
import { SetupModal } from './SetupModal';
import { getConfigurationStatus } from './features';

type SetupType = 'public-access' | 'required-features' | null;

// Configuration examples
const featureIni = `# In your custom.ini file

[feature_toggles]
provisioning = true
`;

const ngrokExample = `ngrok http 3000

Help shape K8s Bindings https://ngrok.com/new-features-update?ref=k8s

Session Status                online
Account                       Roberto Jiménez Sánchez (Plan: Free)
Version                       3.18.4
Region                        Europe (eu)
Latency                       44ms
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://d60d-83-33-235-27.ngrok-free.app -> http://localhost:3000
Connections                   ttl     opn     rt1     rt5     p50     p90
                              50      2       0.00    0.00    83.03   90.56

HTTP Requests
-------------

09:18:46.147 CET             GET  /favicon.ico                   302 Found
09:18:46.402 CET             GET  /login`;

const rootUrlExample = `[server]
root_url = https://d60d-83-33-235-27.ngrok-free.app`;

const getModalContent = (setupType: SetupType) => {
  switch (setupType) {
    case 'public-access':
      return {
        title: t('provisioning.getting-started.modal-title-set-up-public-access', 'Set up public access'),
        description: t(
          'provisioning.getting-started.modal-description-public-access',
          'Set up public access to your Grafana instance to enable GitHub integration'
        ),
        steps: [
          {
            title: t('provisioning.getting-started.step-title-start-ngrok', 'Start ngrok for temporary public access'),
            description: t(
              'provisioning.getting-started.step-description-start-ngrok',
              'Run this command to create a secure tunnel to your local Grafana:'
            ),
            code: 'ngrok http 3000',
          },
          {
            title: t('provisioning.getting-started.step-title-copy-url', 'Copy your public URL'),
            description: t(
              'provisioning.getting-started.step-description-copy-url',
              'From the ngrok output, copy the https:// forwarding URL that looks like this:'
            ),
            code: ngrokExample,
            copyCode: false,
          },
          {
            title: t(
              'provisioning.getting-started.step-title-update-grafana-config',
              'Update your Grafana configuration'
            ),
            description: t(
              'provisioning.getting-started.step-description-update-grafana-config',
              'Add this to your custom.ini file, replacing the URL with your actual ngrok URL:'
            ),
            code: rootUrlExample,
          },
        ],
      };
    case 'required-features':
      return {
        title: t('provisioning.getting-started.modal-title-set-up-required-features', 'Set up required features'),
        description: t(
          'provisioning.getting-started.modal-description-required-features',
          'Enable required Grafana features for provisioning'
        ),
        steps: [
          {
            title: t(
              'provisioning.getting-started.step-title-enable-feature-toggles',
              'Enable Required Feature Toggles'
            ),
            description: t(
              'provisioning.getting-started.step-description-enable-feature-toggles',
              'Add the provisioning feature toggle to your custom.ini file.'
            ),
            code: featureIni,
          },
        ],
      };
    default:
      return {
        title: '',
        description: '',
        steps: [],
      };
  }
};

interface Props {
  items: Repository[];
}

export default function GettingStarted({ items }: Props) {
  const styles = useStyles2(getStyles);
  const settingsArg = config.featureToggles.provisioning ? undefined : skipToken;
  const settingsQuery = useGetFrontendSettingsQuery(settingsArg, {
    refetchOnMountOrArgChange: true,
  });
  const connectionCount = settingsQuery.data?.items?.length ?? 0;
  const hasItems = connectionCount > 0;
  const maxRepositories = settingsQuery.data?.maxRepositories;
  const isConnectionLimitExceeded = !!maxRepositories && connectionCount >= maxRepositories;
  const { hasPublicAccess, hasImageRenderer, hasRequiredFeatures } = getConfigurationStatus();
  const [showInstructionsModal, setShowModal] = useState(false);
  const [setupType, setSetupType] = useState<SetupType>(null);

  return (
    <>
      <Stack direction="column" gap={6} wrap="wrap">
        <CloudInfoBox />
        <Stack gap={10} alignItems="center">
          <div className={styles.imageContainer}>
            {/* decorative img, use empty str to skip alt*/}
            <img src={provisioningSvg} className={styles.image} alt="" />
          </div>
          <FeaturesList
            hasRequiredFeatures={hasRequiredFeatures}
            isConnectionLimitExceeded={isConnectionLimitExceeded}
            maxRepositories={maxRepositories}
            onSetupFeatures={() => {
              setSetupType('required-features');
              setShowModal(true);
            }}
          />
        </Stack>
        {(!hasPublicAccess || !hasImageRenderer) && hasItems && (
          <EnhancedFeatures
            hasPublicAccess={hasPublicAccess}
            hasImageRenderer={hasImageRenderer}
            onSetupPublicAccess={() => {
              setSetupType('public-access');
              setShowModal(true);
            }}
          />
        )}
      </Stack>
      {showInstructionsModal && setupType && (
        <SetupModal
          {...getModalContent(setupType)}
          isOpen={showInstructionsModal}
          onDismiss={() => setShowModal(false)}
        />
      )}
    </>
  );
}

function getStyles(theme: GrafanaTheme2) {
  return {
    imageContainer: css({
      height: 350,
      display: `flex`,
      alignItems: `center`,
      justifyContent: `center`,
    }),
    image: css({
      borderRadius: theme.shape.radius.default,
      width: '100%',
      height: '100%',
    }),
  };
}
