'use client'

/**
 * InviteMemberDialog — collects email + role, calls the supplied submit
 * handler (defaults to a no-op so the caller MUST wire it; in practice the
 * caller passes api.teamInvitations.create or useInvitations().bulkInvite).
 *
 * Self-contained modal — uses a fixed overlay, doesn't pull Radix Dialog,
 * so the test harness can render the open state straightforwardly. startsim-o7s.
 */

import * as React from 'react'
import { RoleSelector } from './RoleSelector'
import type { InvitationLite, TeamRole } from './types'
import {
  INVITE_DIALOG_DEFAULTS,
  type InviteMemberDialogClassNames,
} from './invite-member-dialog-default-class-names'

export interface InviteMemberDialogProps {
  /** Team the invitation will be scoped to. */
  teamId: string
  /**
   * Submit hook. When undefined the dialog won't send anything — useful for
   * Storybook-style harnesses. Apps typically pass
   *   (input) => api.teamInvitations.create(input)
   */
  onSubmit?: (input: { email: string; teamId: string; role: TeamRole }) => Promise<InvitationLite | void>
  /** Notification when an invitation has been created. */
  onInvited?: (invitation: InvitationLite | void) => void
  /** Trigger button label. */
  triggerLabel?: string
  /** Title in the modal header. */
  title?: string
  /** Submit button label. Override when the backend adds directly rather than
   *  emailing an invite (e.g. Foundry: "Add member"). */
  submitLabel?: string
  /** Confirmation line after a successful submit. Receives the email so the
   *  caller can match its own semantics ("Added ada@x to this foundry"). */
  successMessage?: (email: string) => string
  /** Default role pre-selected. */
  defaultRole?: TeamRole
  /** Available roles in the dropdown. Defaults to admin/member/viewer (no owner). */
  availableRoles?: TeamRole[]
  classNames?: InviteMemberDialogClassNames
  /** External open-state control. When omitted the trigger button manages it. */
  open?: boolean
  onOpenChange?: (open: boolean) => void
}

export function InviteMemberDialog({
  teamId,
  onSubmit,
  onInvited,
  triggerLabel = 'Invite member',
  title = 'Invite a teammate',
  submitLabel = 'Send invitation',
  successMessage = (email) => `Invitation sent to ${email}`,
  defaultRole = 'member',
  availableRoles = ['admin', 'member', 'viewer'],
  classNames,
  open: controlledOpen,
  onOpenChange,
}: InviteMemberDialogProps) {
  const cls = { ...INVITE_DIALOG_DEFAULTS, ...(classNames ?? {}) }
  const [internalOpen, setInternalOpen] = React.useState(false)
  const open = controlledOpen ?? internalOpen
  const setOpen = (next: boolean) => {
    if (controlledOpen === undefined) setInternalOpen(next)
    onOpenChange?.(next)
  }

  const [email, setEmail] = React.useState('')
  const [role, setRole] = React.useState<TeamRole>(defaultRole)
  const [error, setError] = React.useState('')
  const [success, setSuccess] = React.useState('')
  const [submitting, setSubmitting] = React.useState(false)

  function reset() {
    setEmail('')
    setRole(defaultRole)
    setError('')
    setSuccess('')
    setSubmitting(false)
  }

  function close() {
    setOpen(false)
    reset()
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    setError('')
    setSuccess('')
    if (!email.trim()) {
      setError('Email is required')
      return
    }
    setSubmitting(true)
    try {
      let invited: InvitationLite | void = undefined
      if (onSubmit) {
        invited = await onSubmit({ email: email.trim(), teamId, role })
      }
      setSuccess(successMessage(email.trim()))
      setEmail('')
      onInvited?.(invited)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Could not send invitation')
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <>
      <button
        type="button"
        className={cls.trigger}
        onClick={() => setOpen(true)}
        aria-haspopup="dialog"
        aria-expanded={open}
      >
        {triggerLabel}
      </button>
      {open && (
        <div className={cls.overlay} role="presentation" onClick={close}>
          <div
            className={cls.panel}
            role="dialog"
            aria-modal="true"
            aria-label={title}
            onClick={(e) => e.stopPropagation()}
          >
            <div className={cls.header}>
              <h2 className={cls.title}>{title}</h2>
            </div>
            <form onSubmit={handleSubmit}>
              <div className={cls.body}>
                <div className={cls.fieldRow}>
                  <label htmlFor="invite-email" className={cls.label}>Email</label>
                  <input
                    id="invite-email"
                    type="email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    required
                    autoComplete="email"
                    className={cls.input}
                    disabled={submitting}
                  />
                </div>
                <div className={cls.fieldRow}>
                  <label htmlFor="invite-role" className={cls.label}>Role</label>
                  <RoleSelector
                    value={role}
                    onChange={setRole}
                    availableRoles={availableRoles}
                    ariaLabel="Invite role"
                    disabled={submitting}
                  />
                </div>
                {error && <p className={cls.errorText} role="alert">{error}</p>}
                {success && <p className={cls.successText}>{success}</p>}
              </div>
              <div className={cls.footer}>
                <button
                  type="button"
                  className={cls.cancelButton}
                  onClick={close}
                  disabled={submitting}
                >
                  Close
                </button>
                <button
                  type="submit"
                  className={cls.submitButton}
                  disabled={submitting}
                >
                  {submitting ? 'Saving…' : submitLabel}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </>
  )
}
