import type { AlgorithmDefinition } from '@/lib/visualizations/types';

export const prefixSumAlgorithm: AlgorithmDefinition = {
  id: 'prefix-sum',
  title: 'Prefix Sum - Range Query',
  slug: 'prefix-sum',
  pattern: {
    name: 'Prefix Sum',
    description:
      'Precompute cumulative sums to answer range sum queries in O(1) time.',
  },
  problemStatement:
    'Given an array, answer multiple range sum queries efficiently. Each query asks for the sum of elements from index i to j.',
  intuition:
    'Build a prefix sum array where prefix[k] = sum of all elements from 0 to k-1. Then any range sum from i to j is simply prefix[j+1] - prefix[i].',
  code: {
    language: 'python',
    code: `def build_prefix(nums: list[int]) -> list[int]:
    prefix = [0]
    for num in nums:
        prefix.append(prefix[-1] + num)
    return prefix

def range_sum(prefix: list[int], i: int, j: int) -> int:
    return prefix[j + 1] - prefix[i]`,
  },
  initialExample: {
    input: { nums: [3, 1, 4, 1, 5, 9], query: { i: 1, j: 4 } },
    expected: 11,
  },
  steps: [
    // Phase 1: Problem (2 steps)
    {
      id: 'problem-1',
      phase: 'problem',
      explanation:
        'We have an array [3, 1, 4, 1, 5, 9] and need to efficiently answer range sum queries like "sum from index 1 to 4".',
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'problem-2',
      phase: 'problem',
      explanation:
        'Naively summing each range takes O(n) per query. With many queries, this becomes expensive. Can we precompute something?',
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'highlighted' },
              { value: 4, index: 2, state: 'highlighted' },
              { value: 1, index: 3, state: 'highlighted' },
              { value: 5, index: 4, state: 'highlighted' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [
          { id: 'i', name: 'i', index: 1, color: 'left' },
          { id: 'j', name: 'j', index: 4, color: 'right' },
        ],
        variables: [
          { id: 'i', name: 'i', value: 1 },
          { id: 'j', name: 'j', value: 4 },
        ],
        calculations: [],
      },
    },

    // Phase 2: Intuition (3 steps)
    {
      id: 'intuition-1',
      phase: 'intuition',
      explanation:
        'Key insight: Build a prefix sum array where each element is the cumulative sum of all elements up to that point.',
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'normal' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'intuition-2',
      phase: 'intuition',
      explanation:
        'prefix[k] represents the sum of elements from index 0 to k-1. The extra 0 at the start simplifies our formula.',
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'highlighted' },
              { value: 1, index: 1, state: 'highlighted' },
              { value: 4, index: 2, state: 'highlighted' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'highlighted' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'normal' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [
          { id: 'calc-1', expression: '3 + 1 + 4', result: '8', position: 'above' },
        ],
      },
    },
    {
      id: 'intuition-3',
      phase: 'intuition',
      explanation:
        'Range sum from i to j = prefix[j+1] - prefix[i]. This is O(1) per query after O(n) preprocessing!',
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'highlighted' },
              { value: 4, index: 2, state: 'highlighted' },
              { value: 1, index: 3, state: 'highlighted' },
              { value: 5, index: 4, state: 'highlighted' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'comparing' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'comparing' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [
          { id: 'i', name: 'i', index: 1, color: 'left' },
          { id: 'j+1', name: 'j+1', index: 5, color: 'right' },
        ],
        variables: [
          { id: 'i', name: 'i', value: 1 },
          { id: 'j', name: 'j', value: 4 },
        ],
        calculations: [
          { id: 'calc-1', expression: '14 - 3', result: '11', position: 'above' },
        ],
      },
    },

    // Phase 3: Code walkthrough (4 steps)
    {
      id: 'code-1',
      phase: 'code',
      explanation:
        'Start with prefix = [0]. This handles the edge case of summing from index 0.',
      codeLine: 2,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'code-2',
      phase: 'code',
      explanation:
        'For each element, append prefix[-1] + num. This builds the cumulative sum.',
      codeLine: 3,
      codeHighlightLines: [3, 4],
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'code-3',
      phase: 'code',
      explanation:
        'The range_sum function computes prefix[j+1] - prefix[i] in O(1).',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'code-4',
      phase: 'code',
      explanation:
        'Why j+1? Because prefix[k] is the sum of elements 0 through k-1. So prefix[j+1] includes element j.',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },

    // Phase 4: Execution - Building prefix array (10 steps)
    {
      id: 'exec-1',
      phase: 'execution',
      explanation: 'Initialize prefix = [0].',
      codeLine: 2,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'highlighted' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    {
      id: 'exec-2',
      phase: 'execution',
      explanation: 'Process nums[0] = 3. Append prefix[-1] + 3 = 0 + 3 = 3.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'comparing' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 0, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-1', expression: '0 + 3', result: '3', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-3',
      phase: 'execution',
      explanation: 'Process nums[1] = 1. Append prefix[-1] + 1 = 3 + 1 = 4.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'comparing' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 1, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-2', expression: '3 + 1', result: '4', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-4',
      phase: 'execution',
      explanation: 'Process nums[2] = 4. Append prefix[-1] + 4 = 4 + 4 = 8.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'dimmed' },
              { value: 4, index: 2, state: 'comparing' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 2, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-3', expression: '4 + 4', result: '8', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-5',
      phase: 'execution',
      explanation: 'Process nums[3] = 1. Append prefix[-1] + 1 = 8 + 1 = 9.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'dimmed' },
              { value: 4, index: 2, state: 'dimmed' },
              { value: 1, index: 3, state: 'comparing' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 3, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-4', expression: '8 + 1', result: '9', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-6',
      phase: 'execution',
      explanation: 'Process nums[4] = 5. Append prefix[-1] + 5 = 9 + 5 = 14.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'dimmed' },
              { value: 4, index: 2, state: 'dimmed' },
              { value: 1, index: 3, state: 'dimmed' },
              { value: 5, index: 4, state: 'comparing' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 4, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-5', expression: '9 + 5', result: '14', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-7',
      phase: 'execution',
      explanation: 'Process nums[5] = 9. Append prefix[-1] + 9 = 14 + 9 = 23.',
      codeLine: 4,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'dimmed' },
              { value: 4, index: 2, state: 'dimmed' },
              { value: 1, index: 3, state: 'dimmed' },
              { value: 5, index: 4, state: 'dimmed' },
              { value: 9, index: 5, state: 'comparing' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'normal' },
              { value: 23, index: 6, state: 'highlighted' },
            ],
          },
        ],
        pointers: [
          { id: 'curr', name: 'num', index: 5, color: 'mid' },
        ],
        variables: [],
        calculations: [
          { id: 'calc-6', expression: '14 + 9', result: '23', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-8',
      phase: 'execution',
      explanation: 'Prefix array complete! Now we can answer range queries in O(1).',
      codeLine: 5,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 1, index: 3, state: 'normal' },
              { value: 5, index: 4, state: 'normal' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'success' },
              { value: 3, index: 1, state: 'success' },
              { value: 4, index: 2, state: 'success' },
              { value: 8, index: 3, state: 'success' },
              { value: 9, index: 4, state: 'success' },
              { value: 14, index: 5, state: 'success' },
              { value: 23, index: 6, state: 'success' },
            ],
          },
        ],
        pointers: [],
        variables: [],
        calculations: [],
      },
    },
    // Range query execution
    {
      id: 'exec-9',
      phase: 'execution',
      explanation: 'Query: sum from index 1 to 4. We need elements [1, 4, 1, 5].',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'highlighted' },
              { value: 4, index: 2, state: 'highlighted' },
              { value: 1, index: 3, state: 'highlighted' },
              { value: 5, index: 4, state: 'highlighted' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'normal' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'normal' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [
          { id: 'i', name: 'i', index: 1, color: 'left' },
          { id: 'j', name: 'j', index: 4, color: 'right' },
        ],
        variables: [
          { id: 'i', name: 'i', value: 1 },
          { id: 'j', name: 'j', value: 4 },
        ],
        calculations: [],
      },
    },
    {
      id: 'exec-10',
      phase: 'execution',
      explanation: 'Use formula: prefix[j+1] - prefix[i] = prefix[5] - prefix[1].',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'highlighted' },
              { value: 4, index: 2, state: 'highlighted' },
              { value: 1, index: 3, state: 'highlighted' },
              { value: 5, index: 4, state: 'highlighted' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'comparing' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'comparing' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [
          { id: 'prefix[i]', name: 'prefix[i]', index: 1, color: 'left' },
          { id: 'prefix[j+1]', name: 'prefix[j+1]', index: 5, color: 'right' },
        ],
        variables: [
          { id: 'i', name: 'i', value: 1 },
          { id: 'j', name: 'j', value: 4 },
        ],
        calculations: [],
      },
    },
    {
      id: 'exec-11',
      phase: 'execution',
      explanation: 'Calculate: prefix[5] - prefix[1] = 14 - 3 = 11.',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'normal' },
              { value: 1, index: 1, state: 'success' },
              { value: 4, index: 2, state: 'success' },
              { value: 1, index: 3, state: 'success' },
              { value: 5, index: 4, state: 'success' },
              { value: 9, index: 5, state: 'normal' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'normal' },
              { value: 3, index: 1, state: 'comparing' },
              { value: 4, index: 2, state: 'normal' },
              { value: 8, index: 3, state: 'normal' },
              { value: 9, index: 4, state: 'normal' },
              { value: 14, index: 5, state: 'comparing' },
              { value: 23, index: 6, state: 'normal' },
            ],
          },
        ],
        pointers: [],
        variables: [
          { id: 'i', name: 'i', value: 1 },
          { id: 'j', name: 'j', value: 4 },
          { id: 'result', name: 'result', value: 11, derivation: '14 - 3' },
        ],
        calculations: [
          { id: 'calc-7', expression: '14 - 3', result: '11', position: 'above' },
        ],
      },
    },
    {
      id: 'exec-12',
      phase: 'execution',
      explanation: 'Verify: 1 + 4 + 1 + 5 = 11. Correct! O(n) preprocessing enables O(1) queries.',
      codeLine: 8,
      dataState: {
        arrays: [
          {
            id: 'nums',
            label: 'Original Array',
            elements: [
              { value: 3, index: 0, state: 'dimmed' },
              { value: 1, index: 1, state: 'success' },
              { value: 4, index: 2, state: 'success' },
              { value: 1, index: 3, state: 'success' },
              { value: 5, index: 4, state: 'success' },
              { value: 9, index: 5, state: 'dimmed' },
            ],
          },
          {
            id: 'prefix',
            label: 'Prefix Sum Array',
            elements: [
              { value: 0, index: 0, state: 'dimmed' },
              { value: 3, index: 1, state: 'success' },
              { value: 4, index: 2, state: 'dimmed' },
              { value: 8, index: 3, state: 'dimmed' },
              { value: 9, index: 4, state: 'dimmed' },
              { value: 14, index: 5, state: 'success' },
              { value: 23, index: 6, state: 'dimmed' },
            ],
          },
        ],
        pointers: [],
        variables: [
          { id: 'result', name: 'result', value: 11 },
        ],
        calculations: [
          { id: 'calc-8', expression: '1 + 4 + 1 + 5', result: '11', position: 'above' },
        ],
      },
    },
  ],
};
