import { useState } from 'react'
import type { FieldPath, FieldsRevision, FieldsRevisionDiff } from '@platform-modules/fields'
import type { FieldValidationIssue } from './complete-editor.js'

function displayPath(path: readonly (string|number)[]):string{return path.map(String).join(' › ')}
function pathId(prefix:string,path:FieldPath):string{return `${prefix}-${path.map((segment)=>String(segment).replace(/[^a-zA-Z0-9_-]/g,'_')).join('__')||'root'}`}

export interface FieldValidationSummaryProps {
  readonly issues: readonly FieldValidationIssue[]
  readonly idPrefix?: string
  readonly title?: string
}

export function FieldValidationSummary({issues,idPrefix='fields-react',title='Fix validation errors'}:FieldValidationSummaryProps){
  if(!issues.length)return null
  return <section className="fields-validation-summary" role="alert" aria-labelledby={`${idPrefix}-validation-title`} tabIndex={-1}>
    <h2 id={`${idPrefix}-validation-title`}>{title}</h2>
    <ul>{issues.map((issue,index)=><li key={`${index}:${displayPath(issue.path)}`}><a href={`#${pathId(idPrefix,issue.path)}`}>{displayPath(issue.path) || 'Form'}: {issue.message}</a></li>)}</ul>
  </section>
}

export interface FieldsRevisionDiffViewProps {
  readonly diff: FieldsRevisionDiff
  readonly leftLabel?: string
  readonly rightLabel?: string
}
export function FieldsRevisionDiffView({diff,leftLabel='Earlier revision',rightLabel='Later revision'}:FieldsRevisionDiffViewProps){
  return <section className="fields-revision-diff" aria-label={`${leftLabel} compared with ${rightLabel}`} style={{containerType:'inline-size'}}>
    <h3>Field changes</h3>
    {diff.valuePaths.length?<ul>{diff.valuePaths.map((change,index)=><li key={`${index}:${displayPath(change.path)}`}><strong>{change.kind}</strong> <code>{displayPath(change.path)}</code></li>)}</ul>:<p>No field value changes.</p>}
    <h3>Block changes</h3>
    {diff.blockNodes.length?<ul>{diff.blockNodes.map((change)=><li key={`${change.nodeId}:${change.kind}`}><strong>{change.kind}</strong> block <code>{change.nodeId}</code></li>)}</ul>:<p>No block changes.</p>}
  </section>
}

export interface FieldsRevisionRestorePanelProps {
  readonly revision: FieldsRevision
  readonly diff?: FieldsRevisionDiff
  readonly onRestore: (revision: FieldsRevision) => void | Promise<void>
  readonly disabled?: boolean
  readonly confirmationLabel?: string
}
export function FieldsRevisionRestorePanel({revision,diff,onRestore,disabled=false,confirmationLabel='I understand this writes a new current snapshot'}:FieldsRevisionRestorePanelProps){
  const [confirmed,setConfirmed]=useState(false),[busy,setBusy]=useState(false),[status,setStatus]=useState(''),[error,setError]=useState<string|null>(null)
  const restore=async()=>{if(!confirmed||busy||disabled)return;setBusy(true);setError(null);try{await onRestore(revision);setStatus(`Revision from ${revision.createdAt.toLocaleString()} restored`);setConfirmed(false)}catch(cause){setError(cause instanceof Error?cause.message:String(cause))}finally{setBusy(false)}}
  return <section className="fields-revision-restore" style={{containerType:'inline-size'}} aria-label="Restore field revision">
    <div role="status" aria-live="polite">{status}</div>
    {error?<div role="alert" tabIndex={0}>{error}</div>:null}
    <dl>
      <div><dt>Created</dt><dd>{revision.createdAt.toLocaleString()}</dd></div>
      <div><dt>Created by</dt><dd>{revision.createdBy}</dd></div>
      <div><dt>Kind</dt><dd>{revision.kind}</dd></div>
      <div><dt>Source version</dt><dd>{revision.sourceVersion}</dd></div>
    </dl>
    {diff?<FieldsRevisionDiffView diff={diff}/>:null}
    <p role="note">Password credentials are not restored from revisions; only their configured marker is retained in revision data.</p>
    <label><input type="checkbox" checked={confirmed} disabled={disabled||busy} onChange={(event)=>setConfirmed(event.currentTarget.checked)}/> {confirmationLabel}</label>
    <button type="button" disabled={disabled||busy||!confirmed} onClick={()=>void restore()}>{busy?'Restoring…':'Restore revision'}</button>
  </section>
}
