import DidAddress from '@arcblock/ux/lib/DID';
import { Typography } from '@mui/material';
import { Component, type ReactNode } from 'react';

/**
 * Matches DIDs that @arcblock/did-motif can parse:
 *   z-prefixed base58 DID (z1..., z2..., zNK...) — standard ArcBlock format
 *   did:method:identifier — W3C DID format
 */
function isValidDid(did: unknown): did is string {
  return typeof did === 'string' && /^(z[0-9a-zA-Z]{20,}|did:[a-z]+:[A-Za-z0-9]+)/.test(did);
}

interface ErrorBoundaryProps {
  fallback: ReactNode;
  children: ReactNode;
}

/**
 * Inline error boundary — catches DIDParsingError (or any render error) from DidAddress
 * and shows a fallback instead of crashing the whole page.
 */
class DidErrorBoundary extends Component<ErrorBoundaryProps, { hasError: boolean }> {
  // eslint-disable-next-line react/state-in-constructor
  override state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  override componentDidCatch() {
    // Swallow — DIDParsingError is non-fatal, we just show a fallback
  }

  override render() {
    if (this.state.hasError) return this.props.fallback;
    return this.props.children;
  }
}

export interface SafeDidAddressProps {
  did?: string | null;
  [key: string]: any;
}

/**
 * SafeDidAddress — drop-in replacement for `@arcblock/ux/lib/DID` that:
 *   1. Shows an em-dash placeholder for empty/null DIDs
 *   2. Pre-validates the DID format before rendering
 *   3. Catches any render errors from did-motif via an error boundary
 *
 * Use this anywhere the backing data may have invalid/missing DIDs (e.g. migrated
 * customer records with empty did fields).
 */
// eslint-disable-next-line react/require-default-props
export default function SafeDidAddress({ did, ...rest }: SafeDidAddressProps) {
  if (!did || !isValidDid(did)) {
    return (
      <Typography variant="body2" color="text.secondary" component="span">
        {did || '—'}
      </Typography>
    );
  }

  return (
    <DidErrorBoundary
      fallback={
        <Typography variant="body2" color="text.secondary" component="span">
          {did}
        </Typography>
      }>
      <DidAddress did={did} {...rest} />
    </DidErrorBoundary>
  );
}
