'use client'

import { useState } from 'react'
import { Button } from '../ui/button'
import { Input } from '../ui/input'
import { Label } from '../ui/label'
import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from '../ui/select'
import { notify as defaultNotify } from '../toast'
import { cn } from '../../lib/utils'
import { suggestRelationshipKey, type SchemaId } from './schema-builder-core'
import type { SchemaTypeBuilderNotifier } from './SchemaTypeBuilder'

/** A type option the edge can connect (id + its key/label for display). */
export interface RelationshipTypeOption {
  id: SchemaId
  key: string
  label: string
}

export interface RelationshipBuilderClassNames {
  root?: string
  card?: string
  submit?: string
}

export interface RelationshipBuilderProps {
  /** The org's entity types — the selectable endpoints of the edge. */
  types: RelationshipTypeOption[]
  /** Persist a relationship definition (typed edge source_type -> target_type). */
  createRelationship: (input: {
    key: string
    sourceType: SchemaId
    targetType: SchemaId
  }) => Promise<unknown>
  /** Fired after the relationship def is created (refetch here). */
  onCreated?: (created: { key: string }) => void
  notify?: SchemaTypeBuilderNotifier
  classNames?: RelationshipBuilderClassNames
}

/**
 * No-code relationship builder (768w.10.4 S5): connect two entity types with a
 * typed edge. The persistence layer is injected via `createRelationship`; the
 * consuming app supplies the type list + handles refetch in `onCreated`.
 */
export function RelationshipBuilder({
  types,
  createRelationship,
  onCreated,
  notify = defaultNotify,
  classNames,
}: RelationshipBuilderProps) {
  const [sourceId, setSourceId] = useState('')
  const [targetId, setTargetId] = useState('')
  const [keyOverride, setKeyOverride] = useState('')
  const [saving, setSaving] = useState(false)

  const sourceKey = types.find((t) => String(t.id) === sourceId)?.key ?? ''
  const targetKey = types.find((t) => String(t.id) === targetId)?.key ?? ''
  const effectiveKey = keyOverride.trim() || suggestRelationshipKey(sourceKey, targetKey)

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!sourceId || !targetId) {
      notify.error?.('Pick a source and a target type.')
      return
    }
    if (!effectiveKey) {
      notify.error?.('Give the relationship a name.')
      return
    }
    setSaving(true)
    try {
      await createRelationship({ key: effectiveKey, sourceType: sourceId, targetType: targetId })
      notify.success?.(`Connected ${sourceKey} → ${targetKey}.`)
      onCreated?.({ key: effectiveKey })
      setKeyOverride('')
    } catch (err) {
      notify.error?.(err instanceof Error ? err.message : 'Could not create the relationship.')
    } finally {
      setSaving(false)
    }
  }

  return (
    <form onSubmit={handleSubmit} className={cn('space-y-6', classNames?.root)}>
      <Card className={classNames?.card}>
        <CardHeader>
          <CardTitle>Connect two types</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          {types.length === 0 ? (
            <p className="text-sm text-gray-500">
              Create at least one entity type first, then connect them.
            </p>
          ) : (
            <>
              <div className="grid gap-3 sm:grid-cols-2">
                <div className="space-y-1.5">
                  <Label>From (source)</Label>
                  <Select value={sourceId} onValueChange={setSourceId}>
                    <SelectTrigger>
                      <SelectValue placeholder="Pick a type" />
                    </SelectTrigger>
                    <SelectContent>
                      {types.map((t) => (
                        <SelectItem key={String(t.id)} value={String(t.id)}>
                          {t.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="space-y-1.5">
                  <Label>To (target)</Label>
                  <Select value={targetId} onValueChange={setTargetId}>
                    <SelectTrigger>
                      <SelectValue placeholder="Pick a type" />
                    </SelectTrigger>
                    <SelectContent>
                      {types.map((t) => (
                        <SelectItem key={String(t.id)} value={String(t.id)}>
                          {t.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              <div className="space-y-1.5">
                <Label htmlFor="rel-key">Name (optional)</Label>
                <Input
                  id="rel-key"
                  value={keyOverride}
                  onChange={(e) => setKeyOverride(e.target.value)}
                  placeholder={effectiveKey || 'auto-generated from the two types'}
                />
                <p className="text-xs text-gray-500">
                  Stable identifier for this edge. Defaults to{' '}
                  <span className="font-mono">{effectiveKey || '—'}</span>.
                </p>
              </div>
            </>
          )}
        </CardContent>
      </Card>

      <div className="flex justify-end">
        <Button
          type="submit"
          disabled={saving || types.length === 0}
          className={classNames?.submit}
        >
          {saving ? 'Connecting…' : 'Define relationship'}
        </Button>
      </div>
    </form>
  )
}
