/**
 * Right-side results panel that displays one result per editor line.
 *
 * Each result line matches CodeMirror's 24px line height (15px * 1.6)
 * so that results visually align with their corresponding expressions.
 * Scroll position is driven externally via a forwarded ref.
 */

import { forwardRef, useState, useCallback } from 'react'
import type { EngineLineResult } from '../engine/types.ts'
import '../styles/results-panel.css'

const DISPLAYABLE_TYPES = new Set([
  'number',
  'unitValue',
  'currencyValue',
  'dateTime',
  'timeDelta',
  'boolean',
])

const NON_RESULT_TYPES = new Set(['comment', 'text', 'empty'])

/** Map result type to CSS class for type-specific coloring */
function resultColorClass(type: string): string {
  switch (type) {
    case 'currencyValue': return 'result-currency'
    case 'unitValue': return 'result-unit'
    case 'dateTime':
    case 'timeDelta': return 'result-datetime'
    case 'boolean': return 'result-boolean'
    default: return 'result-number'
  }
}

export interface ResultsPanelProps {
  results: EngineLineResult[]
  align: 'left' | 'center' | 'right'
  style?: React.CSSProperties
}

export const ResultsPanel = forwardRef<HTMLDivElement, ResultsPanelProps>(
  function ResultsPanel({ results, align, style }, ref) {
    const [copiedIdx, setCopiedIdx] = useState<number | null>(null)

    const handleClick = useCallback((idx: number, rawValue: number | null, display: string) => {
      const text = rawValue != null ? String(rawValue) : display
      navigator.clipboard.writeText(text).then(() => {
        setCopiedIdx(idx)
        setTimeout(() => setCopiedIdx(null), 1200)
      }).catch(() => { /* clipboard unavailable */ })
    }, [])

    return (
      <div
        ref={ref}
        className="results-panel"
        style={{ textAlign: align, ...style }}
        role="complementary"
        aria-label="Calculation results"
      >
        {results.map((result, i) => {
          const isEven = (i + 1) % 2 === 0
          const stripe = isEven ? ' result-stripe' : ''

          if (DISPLAYABLE_TYPES.has(result.type) && result.display) {
            const colorClass = resultColorClass(result.type)
            const isCopied = copiedIdx === i

            return (
              <div
                key={i}
                className={`result-line result-value ${colorClass}${stripe}${isCopied ? ' copied' : ''}`}
                onClick={() => handleClick(i, result.rawValue, result.display)}
                title="Click to copy"
              >
                {isCopied ? 'Copied!' : result.display}
              </div>
            )
          }

          // Error hint
          if (result.type === 'error' && result.error) {
            return (
              <div key={i} className={`result-line result-error-hint${stripe}`}>
                · error
              </div>
            )
          }

          // Comment/heading marker
          if (result.type === 'comment' || result.type === 'text') {
            return (
              <div key={i} className={`result-line result-marker${stripe}`}>
                <span className="result-dash">────</span>
              </div>
            )
          }

          return (
            <div key={i} className={`result-line result-empty${stripe}`}>
              &nbsp;
            </div>
          )
        })}
      </div>
    )
  },
)
