'use client';

/**
 * Code block — read-only syntax highlighting via `PrettyCode`.
 *
 * Inline, the panel is height-capped (`maxLines`) so a long snippet never
 * blows up the transcript — beyond the cap PrettyCode scrolls internally.
 * When capped, a header expand (⤢) button opens the FULL code in a large
 * dialog (same pattern as the map / image blocks), where it reads/scrolls
 * comfortably and copies in one shot.
 */

import { useCallback, useState } from 'react';

import { Check, Copy, X } from 'lucide-react';
import { cn } from '@djangocfg/ui-core/lib';
import { Dialog, DialogClose, DialogContent, DialogTitle } from '@djangocfg/ui-core/components';

import { LazyPrettyCode } from '../../../../dev/code/PrettyCode/lazy';
import type { Language } from '../../../../dev/code/PrettyCode/lazy';
import type { CodeBlock } from '../../../types/block';
import type { BlockRendererProps } from './types';

/** Roomy on-dark button for the expanded dialog header. */
const DIALOG_BTN =
  'inline-flex h-8 items-center justify-center gap-1.5 rounded-lg px-2.5 text-xs font-medium ' +
  'text-white/70 transition-colors hover:bg-white/10 hover:text-white ' +
  'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white/40';

export default function CodeBlockRenderer({ block, ctx }: BlockRendererProps<CodeBlock>) {
  const compact = ctx.appearance === 'compact';
  const [open, setOpen] = useState(false);
  const [copied, setCopied] = useState(false);
  const language = block.language as Language;

  const copyAll = useCallback(() => {
    void navigator.clipboard?.writeText(block.code).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1400);
    });
  }, [block.code]);

  // 16 lines in the narrow chat, 24 in a full-page chat. Beyond this the
  // inline panel scrolls and the header shows the expand button.
  const maxLines = compact ? 16 : 24;

  return (
    <>
      {/* Inline — capped + internally scrollable; expand opens the dialog.
          The dark panel is clipped to the shared 2xl corner by BLOCK_SURFACE. */}
      <LazyPrettyCode
        data={block.code}
        language={language}
        isCompact={compact}
        maxLines={maxLines}
        onExpand={() => setOpen(true)}
      />

      {/* Full code, uncapped, in a large dialog (map/image-block pattern).
          ONE header (language + copy + close) over a dark panel; the body
          renders PrettyCode in `plain` (chrome-less) so there's no second
          header to collide with — the dialog owns the chrome and scroll. */}
      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent
          className="flex h-[85vh] w-[90vw] max-w-[1100px] flex-col overflow-hidden border-0 p-0 sm:rounded-xl"
          // Fixed GitHub-dark surface (matches PrettyCode's own panel) — the
          // code theme is always dark regardless of the app theme, so a
          // theme-driven `bg-code` (light in light mode) would be unreadable.
          style={{ backgroundColor: '#0d1117' }}
          // We render our own close inside the single header, so suppress the
          // default X (it would collide with the header buttons).
          closeButton={false}
        >
          <DialogTitle className="sr-only">{block.caption ?? language ?? 'Code'}</DialogTitle>
          {open && (
            <>
              {/* Roomy dialog header: language left; actions right in the
                  conventional order — primary "Copy" then "Close" (X) at the
                  far edge. Taller + larger than the inline header to suit the
                  big surface. */}
              <div className="flex h-11 shrink-0 items-center justify-between gap-2 border-b border-white/[0.08] px-4">
                <span className="min-w-0 truncate font-mono text-sm lowercase tracking-wide text-white/55">
                  {language}
                </span>
                <div className="flex shrink-0 items-center gap-1">
                  <button type="button" onClick={copyAll} aria-label="Copy code" className={DIALOG_BTN}>
                    {copied ? <Check className="size-3.5" aria-hidden /> : <Copy className="size-3.5" aria-hidden />}
                    <span>{copied ? 'Copied' : 'Copy'}</span>
                  </button>
                  <DialogClose
                    aria-label="Close"
                    className={cn(DIALOG_BTN, 'w-8 px-0')}
                  >
                    <X className="size-4" aria-hidden />
                  </DialogClose>
                </div>
              </div>
              <div className="min-h-0 flex-1 overflow-auto">
                <LazyPrettyCode data={block.code} language={language} variant="plain" />
              </div>
            </>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
