/* @jsxRuntime classic */
/* @jsx h */
/* @jsxFrag Fragment */
import type { RenderElement } from 'claude-code'
import type { Kit } from '../kit'
import Layout from '../layout'
import type { DetailModel } from './detail-model'
import { gutterCellsOf } from './gutter-cells-of'
import { hunkBody } from './hunk-body'
import { linesOf } from './lines-of'
import { MARKER_CELLS } from './marker-cells'
import { maxRowsOf } from './max-rows-of'
import { placeholderOf } from './placeholder-of'
import { rowsOf } from './rows-of'
/**
* The selected file under the list: its bold path and asides (renamed
* from, untracked, truncated) cut to the width, the ask Button, the body.
*
* The body is a placeholder or the hunks (cut to the rows the body's char
* and node budgets hold, maxRowsOf), then the footer; the gutter fits the
* largest number.
*
* @param kit the elements and the width
* @param detail the selected file
* @param onToggleAsk arms or disarms the file for the next prompt
* @returns the detail element
*/
export function detailView(
kit: Kit,
detail: DetailModel,
onToggleAsk: () => void,
): RenderElement {
const { Box, Text, Button } = kit.ui
const placeholder = placeholderOf(detail)
const hunks = placeholder ? [] : (detail.body?.hunks ?? [])
const lines = linesOf(hunks)
const gutterCells = gutterCellsOf(lines)
const contentCells = Math.max(1, kit.columns - gutterCells - MARKER_CELLS)
const rows = placeholder ? [] : rowsOf(lines, contentCells)
const cells = { gutterCells, contentCells }
const maxRows = maxRowsOf(rows, cells)
const isTruncated = detail.body?.isTruncated === true || rows.length > maxRows
const nameOf = (path: string) =>
Layout.truncateStart(Layout.sanitizeName(path), kit.columns)
const renamedFrom =
detail.renamedFrom === null ? null : nameOf(detail.renamedFrom)
const asides = [
renamedFrom === null ? null : `renamed from ${renamedFrom}`,
detail.isUntracked ? 'untracked' : null,
isTruncated ? 'truncated' : null,
].filter(word => word !== null)
const aside = asides.length === 0 ? '' : ` (${asides.join(', ')})`
const notes = (placeholder ?? []).map(line => (
{line}
))
const body = placeholder
? notes
: [hunkBody(kit.ui, rows.slice(0, maxRows), cells)]
const ask = placeholder
? []
: [
,
]
const footer = isTruncated
? [
… diff truncated (exceeded 400 line limit)
,
]
: []
const header = (
{[
{nameOf(detail.path)}
,
{aside},
,
...ask,
]}
)
return {[header, ...body, ...footer]}
}