import { useState } from 'react'
import { Plus, Code, List } from 'lucide-react'
import { cn } from '@/lib/utils'
import { ParameterCard } from './ParameterCard'
import type { ScriptParameter, ScriptParametersSchema } from '@/types'

interface Props {
  schema: ScriptParametersSchema
  onChange: (schema: ScriptParametersSchema) => void
  disabled?: boolean
}

function newParameter(order: number): ScriptParameter {
  return {
    key: '',
    label: '',
    type: 'text',
    required: true,
    placeholder: null,
    group: null,
    order,
    help_text: null,
    options: null,
    default: null,
    validation: null,
    sensitive: false,
  }
}

export function ParameterSchemaBuilder({ schema, onChange, disabled }: Props) {
  const [mode, setMode] = useState<'visual' | 'json'>('visual')
  const [jsonText, setJsonText] = useState('')
  const [jsonError, setJsonError] = useState<string | null>(null)

  const parameters = schema.parameters ?? []

  const updateParams = (params: ScriptParameter[]) => {
    onChange({ parameters: params })
  }

  const handleParamChange = (index: number, updated: ScriptParameter) => {
    const next = [...parameters]
    next[index] = updated
    updateParams(next)
  }

  const handleRemove = (index: number) => {
    updateParams(parameters.filter((_, i) => i !== index))
  }

  const handleMoveUp = (index: number) => {
    if (index === 0) return
    const next = [...parameters]
    ;[next[index - 1], next[index]] = [next[index], next[index - 1]]
    next.forEach((p, i) => { p.order = i + 1 })
    updateParams(next)
  }

  const handleMoveDown = (index: number) => {
    if (index === parameters.length - 1) return
    const next = [...parameters]
    ;[next[index], next[index + 1]] = [next[index + 1], next[index]]
    next.forEach((p, i) => { p.order = i + 1 })
    updateParams(next)
  }

  const handleAdd = () => {
    updateParams([...parameters, newParameter(parameters.length + 1)])
  }

  const switchToJson = () => {
    setJsonText(JSON.stringify(schema, null, 2))
    setJsonError(null)
    setMode('json')
  }

  const switchToVisual = () => {
    try {
      const parsed = JSON.parse(jsonText)
      if (!parsed.parameters || !Array.isArray(parsed.parameters)) {
        setJsonError('JSON must have a "parameters" array')
        return
      }
      onChange(parsed as ScriptParametersSchema)
      setJsonError(null)
      setMode('visual')
    } catch (e) {
      setJsonError(`Invalid JSON: ${(e as Error).message}`)
    }
  }

  return (
    <div className="flex flex-col gap-3">
      {/* Mode toggle */}
      <div className="flex items-center gap-2">
        <button
          type="button"
          onClick={() => mode === 'json' ? switchToVisual() : undefined}
          className={cn(
            'flex items-center gap-1.5 font-sans text-xs px-3 py-1.5 rounded-full border transition-all',
            mode === 'visual'
              ? 'bg-accent-dim border-primary/30 text-foreground'
              : 'border-border text-muted-foreground hover:text-foreground'
          )}
        >
          <List size={12} /> Visual
        </button>
        <button
          type="button"
          onClick={() => mode === 'visual' ? switchToJson() : undefined}
          className={cn(
            'flex items-center gap-1.5 font-sans text-xs px-3 py-1.5 rounded-full border transition-all',
            mode === 'json'
              ? 'bg-accent-dim border-primary/30 text-foreground'
              : 'border-border text-muted-foreground hover:text-foreground'
          )}
        >
          <Code size={12} /> JSON
        </button>
      </div>

      {mode === 'visual' ? (
        <>
          {parameters.length === 0 ? (
            <p className="text-sm text-muted-foreground py-4 text-center">
              No parameters defined. Add one to create dynamic form fields.
            </p>
          ) : (
            <div className="flex flex-col gap-2">
              {parameters.map((param, i) => (
                <ParameterCard
                  key={i}
                  param={param}
                  index={i}
                  onChange={handleParamChange}
                  onRemove={handleRemove}
                  onMoveUp={handleMoveUp}
                  onMoveDown={handleMoveDown}
                  isFirst={i === 0}
                  isLast={i === parameters.length - 1}
                  disabled={disabled}
                />
              ))}
            </div>
          )}
          <button
            type="button"
            onClick={handleAdd}
            disabled={disabled}
            className="flex items-center gap-1.5 text-sm text-primary hover:underline self-start"
          >
            <Plus size={14} /> Add Parameter
          </button>
        </>
      ) : (
        <>
          <textarea
            value={jsonText}
            onChange={e => { setJsonText(e.target.value); setJsonError(null) }}
            disabled={disabled}
            spellCheck={false}
            className="w-full min-h-[300px] resize-y font-sans text-xs text-sm bg-card border border-border rounded-xl p-4 text-foreground focus:outline-none focus:border-[rgba(96,165,250,0.3)] disabled:cursor-not-allowed disabled:opacity-50"
            placeholder='{ "parameters": [...] }'
          />
          {jsonError && (
            <p className="text-xs text-rose-500">{jsonError}</p>
          )}
        </>
      )}
    </div>
  )
}
