import { selectors } from '@grafana/e2e-selectors';
import { Trans, t } from '@grafana/i18n';
import { config } from '@grafana/runtime';
import { type SceneObject, SceneVariableSet, sceneUtils } from '@grafana/scenes';
import { Box, Button, Stack } from '@grafana/ui';

import { openAddSectionVariablePane } from '../settings/variables/VariableTypeSelectionPane';
import { getTopPlacementLabel } from '../utils/getTopPlacementLabel';
import { DashboardInteractions } from '../utils/interactions';
import { getDashboardSceneFor } from '../utils/utils';
import { filterSectionRepeatLocalVariables } from '../variables/utils';

import { DashboardVariablesList } from './dashboard/DashboardVariablesList';

export interface SectionVariablesCategoryTitleProps {
  /** Scene object that owns section-local variables */
  sectionOwner: SceneObject;
  isExpanded: boolean;
}

export function SectionVariablesCategoryTitle(_: SectionVariablesCategoryTitleProps) {
  return (
    <Stack direction="row" alignItems="center" gap={1} flex={1}>
      <span style={{ flexGrow: 1 }}>{t('dashboard.edit-pane.section-variables.title', 'Variables')}</span>
    </Stack>
  );
}

export interface SectionVariablesListProps {
  /** Scene object that owns section-local variables */
  sectionOwner: SceneObject;
}

export function SectionVariablesList({ sectionOwner }: SectionVariablesListProps) {
  const variableSet = sectionOwner.state.$variables;

  if (!(variableSet instanceof SceneVariableSet)) {
    return (
      <Box display="flex" paddingBottom={2}>
        <AddVariableButton sectionOwner={sectionOwner} />
      </Box>
    );
  }

  return <SectionVariablesListInner sectionOwner={sectionOwner} variableSet={variableSet} />;
}

interface SectionVariablesListInnerProps {
  sectionOwner: SceneObject;
  variableSet: SceneVariableSet;
}

function SectionVariablesListInner({ sectionOwner, variableSet }: SectionVariablesListInnerProps) {
  const { variables: rawVariables } = variableSet.useState();
  const variables = filterSectionRepeatLocalVariables(rawVariables, variableSet);
  const topPlacementLabel = getTopPlacementLabel(sectionOwner);
  const visibleCount = config.featureToggles.dashboardUnifiedDrilldownControls
    ? variables.filter((v) => !sceneUtils.isAdHocVariable(v)).length
    : variables.length;

  return (
    <>
      <DashboardVariablesList
        sourceVariableSet={variableSet}
        renderVariables={variables}
        topPlacementLabel={topPlacementLabel}
      />
      <Box display="flex" paddingTop={visibleCount > 0 ? 1 : 0} paddingBottom={2}>
        <AddVariableButton sectionOwner={sectionOwner} />
      </Box>
    </>
  );
}

interface AddVariableButtonProps {
  sectionOwner: SceneObject;
}

function AddVariableButton({ sectionOwner }: AddVariableButtonProps) {
  const dashboard = getDashboardSceneFor(sectionOwner);

  return (
    <Button
      fullWidth
      icon="plus"
      size="sm"
      variant="secondary"
      onClick={() => {
        openAddSectionVariablePane(dashboard, sectionOwner);
        DashboardInteractions.addVariableButtonClicked({ source: 'edit_pane' });
      }}
      data-testid={selectors.components.PanelEditor.ElementEditPane.addVariableButton}
    >
      <Trans i18nKey="dashboard-scene.variables-list.add-variable">Add variable</Trans>
    </Button>
  );
}
