/* DMS shared components — single source for badges / chips / states / buttons (P7).
   Visual refinement only; labels, levels, and logic mirror the original. */
(function () {
  const { Icon } = window;
  const DMS = window.DMS;
  const { CONFIDENTIALITY, STATUS } = DMS;

  // Tweak context — defaults match the converged direction; main.jsx overrides live.
  const TweakContext = React.createContext({
    badgeStyle: 'soft',
    density: 'comfortable',
    recordLayout: 'blocks',
    tableStyle: 'lines',
    deniedStyle: 'panel',
  });
  const useTw = () => React.useContext(TweakContext);

  const CONF_VARS = {
    public: { '--conf': 'var(--conf-public)', '--conf-ink': 'var(--conf-public-ink)' },
    internal: { '--conf': 'var(--conf-internal)', '--conf-ink': 'var(--conf-internal-ink)' },
    confidential: { '--conf': 'var(--conf-confidential)', '--conf-ink': 'var(--conf-confidential-ink)' },
    secret: { '--conf': 'var(--conf-secret)', '--conf-ink': 'var(--conf-secret-ink)' },
  };

  function ConfidentialityBadge({ level, size = 12 }) {
    const { badgeStyle } = useTw();
    const c = CONFIDENTIALITY[level];
    const secret = level === 'secret';
    return (
      <span className={`conf v-${badgeStyle}`} style={{ ...CONF_VARS[level], fontSize: size }} title={`Confidentiality: ${c.label}`}>
        {secret ? <Icon name="lock" size={12} strokeWidth={2} /> : <span className="dot" />}
        {c.label}
      </span>
    );
  }

  const STATUS_VARS = {
    draft: 'var(--st-draft)',
    active: 'var(--st-active)',
    archived: 'var(--st-archived)',
    legal_hold: 'var(--st-hold)',
    disposal_pending: 'var(--st-disposal)',
    disposed: 'var(--st-disposed)',
  };
  const STATUS_ICON = { legal_hold: 'lock', disposal_pending: 'clock' };

  function StatusChip({ status }) {
    const color = STATUS_VARS[status];
    const icon = STATUS_ICON[status];
    const strike = status === 'disposed';
    return (
      <span
        className="chip"
        style={{
          background: `color-mix(in srgb, rgb(${color}) 13%, white)`,
          color: `color-mix(in srgb, rgb(${color}) 78%, black)`,
          textDecoration: strike ? 'line-through' : 'none',
        }}
      >
        {icon && <Icon name={icon} size={11} strokeWidth={2} />}
        {STATUS[status].label}
      </span>
    );
  }

  function LegalHoldChip() {
    return (
      <span className="chip" style={{ background: 'color-mix(in srgb, rgb(var(--st-hold)) 13%, white)', color: 'rgb(var(--st-hold))' }}>
        <Icon name="lock" size={11} strokeWidth={2} />
        Legal hold
      </span>
    );
  }

  const AX = {
    read: { icon: 'check', color: 'var(--ax-read)', label: 'Access', title: 'Full access' },
    metadata: { icon: 'eye', color: 'var(--ax-meta)', label: 'Metadata', title: 'Metadata only — content is locked' },
    step_up: { icon: 'lock', color: 'var(--ax-stepup)', label: 'step-up', title: 'Extra confirmation required' },
    denied: { icon: 'ban', color: 'var(--ax-denied)', label: 'Closed', title: 'No access' },
  };

  function AccessIndicator({ visibility }) {
    const a = AX[visibility];
    if (!a) return null;
    return (
      <span className="inline-flex items-center gap-1 text-xs font-medium" style={{ color: `rgb(${a.color})` }} title={a.title}>
        <Icon name={a.icon} size={13} strokeWidth={1.9} />
        {a.label}
      </span>
    );
  }

  function Card({ children, className = '', as: Tag = 'div', ...rest }) {
    return (
      <Tag className={`rounded-card border border-border bg-surface shadow-card transition-shadow duration-200 ${className}`} {...rest}>
        {children}
      </Tag>
    );
  }

  function SectionTitle({ children, hint }) {
    return (
      <div className="mb-3 flex items-baseline justify-between gap-3">
        <h2 className="flex items-baseline gap-2.5 text-[17px] font-semibold tracking-tight text-text">
          <span className="seal-rule" aria-hidden="true" />
          <span className="serif">{children}</span>
        </h2>
        {hint && <span className="text-xs text-text-faint">{hint}</span>}
      </div>
    );
  }

  function Button({ children, onClick, variant = 'primary', size = 'md', disabled, title, icon }) {
    const base = 'inline-flex items-center gap-1.5 rounded-btn font-medium transition-colors focusring disabled:opacity-40 disabled:cursor-not-allowed';
    const sizes = { sm: 'px-2.5 py-1 text-[13px]', md: 'px-3 py-1.5 text-sm' };
    const styles = {
      primary: 'bg-primary text-white hover:bg-primary-hover shadow-sm',
      ghost: 'border border-border bg-surface text-text hover:bg-surface-2 hover:border-border-strong',
      subtle: 'text-primary hover:bg-primary-tint',
      danger: 'text-white hover:brightness-110',
    };
    const inline = variant === 'danger' ? { background: 'rgb(var(--st-hold))' } : undefined;
    return (
      <button title={title} disabled={disabled} onClick={onClick} className={`${base} ${sizes[size]} ${styles[variant]}`} style={inline}>
        {icon && <Icon name={icon} size={size === 'sm' ? 13 : 15} strokeWidth={1.8} />}
        {children}
      </button>
    );
  }

  function EmptyState({ title, hint, action, icon = 'inboxEmpty' }) {
    return (
      <div className="flex flex-col items-center justify-center gap-2.5 rounded-card border border-dashed border-border bg-surface/70 px-6 py-12 text-center">
        <div className="flex h-11 w-11 items-center justify-center rounded-full bg-surface-2 text-text-faint">
          <Icon name={icon} size={22} strokeWidth={1.5} />
        </div>
        <div className="font-semibold text-text">{title}</div>
        {hint && <div className="max-w-md text-sm text-text-muted text-balance">{hint}</div>}
        {action && <div className="mt-1">{action}</div>}
      </div>
    );
  }

  // Denied ≠ error: calm, explanatory, neutral (not red alarm). Two tweakable directions.
  function DeniedState({ reason, what }) {
    const { deniedStyle } = useTw();
    if (deniedStyle === 'inline') {
      return (
        <div className="flex items-start gap-3 rounded-card border border-border bg-surface-2 px-4 py-3.5">
          <div className="mt-0.5 flex h-7 w-7 flex-none items-center justify-center rounded-full bg-surface text-text-faint shadow-sm">
            <Icon name="lock" size={15} strokeWidth={1.7} />
          </div>
          <div className="min-w-0">
            <div className="text-sm font-semibold text-text">{what || 'You have no access to this content'}</div>
            {reason && <div className="mt-0.5 text-[13px] leading-relaxed text-text-muted">{reason}</div>}
          </div>
        </div>
      );
    }
    return (
      <div className="flex flex-col items-center justify-center gap-3 rounded-card border border-border bg-surface px-6 py-12 text-center">
        <div className="flex h-12 w-12 items-center justify-center rounded-full bg-surface-2 text-text-muted ring-1 ring-border">
          <Icon name="lock" size={22} strokeWidth={1.6} />
        </div>
        <div className="text-[15px] font-semibold text-text">{what || 'You have no access to this document'}</div>
        {reason && <div className="max-w-md text-sm leading-relaxed text-text-muted text-balance">{reason}</div>}
        <div className="mt-1 text-xs text-text-faint">This is not error — the document exists, but your role can’t open it.</div>
      </div>
    );
  }

  function ErrorState({ message, onRetry }) {
    return (
      <div className="flex flex-col items-center justify-center gap-2.5 rounded-card border px-6 py-10 text-center" style={{ borderColor: 'color-mix(in srgb, rgb(var(--st-hold)) 35%, transparent)', background: 'color-mix(in srgb, rgb(var(--st-hold)) 7%, white)' }}>
        <div style={{ color: 'rgb(var(--st-hold))' }}><Icon name="alert" size={24} strokeWidth={1.7} /></div>
        <div className="font-semibold" style={{ color: 'rgb(var(--st-hold))' }}>error</div>
        <div className="text-sm" style={{ color: 'color-mix(in srgb, rgb(var(--st-hold)) 80%, black)' }}>{message}</div>
        {onRetry && <Button variant="danger" icon="refresh" onClick={onRetry}>Try again</Button>}
      </div>
    );
  }

  // Metadata field row — label + value, optional AI-suggested marker, optional mono value.
  function Field({ label, value, ai, mono }) {
    return (
      <div className="flex items-baseline justify-between gap-4 border-b border-border py-[7px] text-sm last:border-0">
        <span className="shrink-0 text-text-muted">{label}</span>
        <span className={`text-right font-medium text-text ${mono ? 'mono' : 'tnum'}`}>
          {value || <span className="text-text-faint">—</span>}
          {ai && (
            <span className="ml-1.5 inline-flex items-center gap-1 rounded-badge px-1.5 py-0.5 align-middle text-[11px] font-semibold" style={{ background: 'color-mix(in srgb, rgb(124 92 224) 12%, white)', color: 'rgb(98 66 196)' }} title="AI suggested — unconfirmed">
              <Icon name="sparkles" size={11} strokeWidth={1.8} /> AI
            </span>
          )}
        </span>
      </div>
    );
  }

  // 4-block document card section.
  function Block({ title, icon, children, className = '' }) {
    return (
      <Card className={`overflow-hidden ${className}`}>
        <div className="flex items-center gap-2 border-b border-border bg-surface-2/60 px-4 py-2.5 text-[11.5px] font-semibold uppercase tracking-wide text-text-muted">
          {icon && <Icon name={icon} size={14} strokeWidth={1.7} />}
          {title}
        </div>
        <div className="px-4 py-3">{children}</div>
      </Card>
    );
  }

  // Data table primitives — sticky header + density + zebra (tweakable).
  function DataTable({ headers, children, className = '' }) {
    const { tableStyle } = useTw();
    return (
      <Card className="overflow-hidden">
        <div className="max-h-[calc(100vh-220px)] overflow-auto">
          <table className={`dms-table ${tableStyle === 'zebra' ? 'zebra' : ''} ${className}`}>
            <thead>
              <tr>{headers.map((h, i) => <th key={i} className="dms-th" style={h.style}>{h.label}</th>)}</tr>
            </thead>
            <tbody>{children}</tbody>
          </table>
        </div>
      </Card>
    );
  }

  Object.assign(window, {
    TweakContext,
    useTw,
    ConfidentialityBadge,
    StatusChip,
    LegalHoldChip,
    AccessIndicator,
    Card,
    SectionTitle,
    Button,
    EmptyState,
    DeniedState,
    ErrorState,
    Field,
    Block,
    DataTable,
  });
})();
