'use client'

/**
 * PendingInvitationCallout — "You've been invited to <team> as <role>" banner
 * with an Accept button. Apps pass an `onAccept` handler that typically
 * resolves the invitation token (from the URL) and calls
 * api.teamInvitations.accept(id, token).
 *
 * Optional `teamName` lets apps render the team's display name even though
 * the invitation row from the backend only carries teamId. startsim-o7s.
 */

import * as React from 'react'
import type { InvitationLite } from './types'
import {
  PENDING_INVITE_DEFAULTS,
  type PendingInvitationCalloutClassNames,
} from './pending-invitation-callout-default-class-names'

export interface PendingInvitationCalloutProps {
  invitation: InvitationLite
  /** Resolved team name (caller supplies). When omitted we use `team #<id>`. */
  teamName?: string
  /** Called when the user clicks Accept. */
  onAccept?: (invitation: InvitationLite) => Promise<void> | void
  /** Called when the user clicks Decline. Optional — hidden when not provided. */
  onDecline?: (invitation: InvitationLite) => Promise<void> | void
  /** Notification once accept resolves. */
  onAccepted?: (invitation: InvitationLite) => void
  acceptLabel?: string
  declineLabel?: string
  classNames?: PendingInvitationCalloutClassNames
}

export function PendingInvitationCallout({
  invitation,
  teamName,
  onAccept,
  onDecline,
  onAccepted,
  acceptLabel = 'Accept',
  declineLabel = 'Decline',
  classNames,
}: PendingInvitationCalloutProps) {
  const cls = { ...PENDING_INVITE_DEFAULTS, ...(classNames ?? {}) }
  const [submitting, setSubmitting] = React.useState(false)
  const [error, setError] = React.useState('')

  const renderedTeam = teamName ?? `team #${invitation.teamId}`
  const role = invitation.role

  async function handleAccept() {
    setError('')
    setSubmitting(true)
    try {
      await onAccept?.(invitation)
      onAccepted?.(invitation)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Could not accept invitation')
    } finally {
      setSubmitting(false)
    }
  }

  async function handleDecline() {
    setError('')
    setSubmitting(true)
    try {
      await onDecline?.(invitation)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Could not decline invitation')
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <div role="status" className={cls.root}>
      <p className={cls.message}>
        You&apos;ve been invited to <span className={cls.emphasized}>{renderedTeam}</span> as a{' '}
        <span className={cls.emphasized}>{role}</span>.
      </p>
      <div className={cls.actions}>
        {onDecline && (
          <button
            type="button"
            className={cls.declineButton}
            onClick={handleDecline}
            disabled={submitting}
          >
            {declineLabel}
          </button>
        )}
        <button
          type="button"
          className={cls.acceptButton}
          onClick={handleAccept}
          disabled={submitting}
        >
          {submitting ? 'Working…' : acceptLabel}
        </button>
      </div>
      {error && <p className={cls.errorText} role="alert">{error}</p>}
    </div>
  )
}
