import { useCallback } from 'react';

import { llm } from '@grafana/llm';

import { DashboardModel } from '../../state/DashboardModel';

import { GenAIButton } from './GenAIButton';
import { EventTrackingSrc } from './tracking';
import { getDashboardChanges, Message, Role } from './utils';

interface GenAIDashboardChangesButtonProps {
  dashboard: DashboardModel;
  onGenerate: (title: string) => void;
  disabled?: boolean;
}

const CHANGES_GENERATION_PREFIX_PROMPT = [
  'You are an expert in Grafana Dashboards',
  'Your goal is to write a description of the changes for a dashboard to display to the user',
  'You will be given human-readable diffs with most irrelevant lines filtered out',
].join('.\n');

const CHANGES_GENERATION_POSTFIX_PROMPT = [
  `Respond only with the diff description, which is meant to be loaded directly into the application for the user.`,
  `If there are no substantial user or migration changes, the correct description is "Minor changes only"`,
  `If there are too many changes of either kind, and those changes have a message saying 'too long', the correct response for that section is "Too many changes to auto-summarize"`,
  'In a diff, lines beginning with - are removed, and lines beginning with + are added.',
  'Lines with neither + nor - are included for context. Be careful not to mark them as added or removed if they do not start with + or -.',
  'If a line is changed, it will show a previous version removed and a new version added',
  'When referring to panel changes, use the panel title',
  'When using panel title, wrap it with double quotes',
  'When the panel changes position, just mention that the panel has changed position',
  'When an entire panel is added or removed, use the panel title and only say it was added or removed and disregard the rest of the changes for that panel',
  'Group together similar changes into one line when multiple panels are affected',
  'Refer to templating elements as variables',
  'Try to make the response as short as possible',
].join('.\n');

export const GenAIDashboardChangesButton = ({ dashboard, onGenerate, disabled }: GenAIDashboardChangesButtonProps) => {
  const messages = useCallback(() => getMessages(dashboard), [dashboard]);

  return (
    <GenAIButton
      messages={messages}
      onGenerate={onGenerate}
      temperature={0}
      model={llm.Model.BASE}
      eventTrackingSrc={EventTrackingSrc.dashboardChanges}
      toggleTipTitle={'Improve your dashboard changes summary'}
      disabled={disabled}
    />
  );
};

function getMessages(dashboard: DashboardModel): Message[] {
  let { userChanges, migrationChanges } = getDashboardChanges(dashboard);
  if (userChanges.length > 8000) {
    userChanges =
      "User changes were too long, fill in the user changes section with 'User changes too long to auto-summarize'";
  }

  if (migrationChanges.split('\n').length < 10) {
    migrationChanges = 'No significant migration changes';
  } else if (migrationChanges.length > 8000) {
    migrationChanges =
      "Migration changes were too long, fill in the migration changes section with 'Migration changes too long to auto-summarize'";
  }

  return [
    {
      content: CHANGES_GENERATION_PREFIX_PROMPT,
      role: Role.system,
    },
    {
      content: `Summarize the following user changes diff under "User changes":\n${userChanges}`,
      role: Role.system,
    },
    {
      content:
        `Be sure to only include substantial user changes, such as adding or removing entire panels, changing panel titles or descriptions, etc.\n` +
        `Do not include "User Changes" section if there are no substantial user changes to report.`,
      role: Role.system,
    },
    {
      content: `Summarize the following migration changes diff under "Migration changes":\n${migrationChanges}`,
      role: Role.system,
    },
    {
      content:
        `Be sure to only include substantial migration changes, such as adding or removing entire panels, changing panel titles or descriptions, etc.\n` +
        `Ignore any threshold step changes or templating list changes.\n` +
        `Ignore other changes and do not include them in the summary. Do not include "Migration Changes" section if there are no substantial migration changes to report.\n` +
        `If there are substantial migration changes, add "Some autogenerated changes are included to update the dashboard to the latest valid schema version" at the end.`,
      role: Role.system,
    },
    {
      content: CHANGES_GENERATION_POSTFIX_PROMPT,
      role: Role.system,
    },
  ];
}
