'use client'

import { useCallback, useMemo, useState, ChangeEvent } from 'react'
import { Handle, Position, NodeProps, useReactFlow } from 'reactflow'
import { nanoid } from 'nanoid'
import { useEditorContext } from '@/components/editor/EditorContext'
import OptionConditionEditor from '@/components/editor/OptionConditionEditor'
import NodeLockIndicator from '@/components/editor/NodeLockIndicator'
import type { Condition } from '@/types/flowchart'

type ChoiceOption = {
  id: string
  label: string
  condition?: Condition
}

type ChoiceNodeData = {
  prompt: string
  options: ChoiceOption[]
}

const MIN_OPTIONS = 2
const MAX_OPTIONS = 6

export default function ChoiceNode({ id, data }: NodeProps<ChoiceNodeData>) {
  const { setNodes } = useReactFlow()
  const { variables, nodeLocks, onNodeFocus, onNodeBlur } = useEditorContext()
  const [editingConditionOptionId, setEditingConditionOptionId] = useState<string | null>(null)

  const lockInfo = nodeLocks.get(id)
  const isLockedByOther = !!lockInfo

  // --- Handlers de Atualização ---

  const updatePrompt = useCallback(
    (e: ChangeEvent<HTMLInputElement>) => {
      setNodes((nodes) =>
        nodes.map((node) =>
          node.id === id
            ? { ...node, data: { ...node.data, prompt: e.target.value } }
            : node
        )
      )
    },
    [id, setNodes]
  )

  const updateOptionLabel = useCallback(
    (optionId: string, label: string) => {
      setNodes((nodes) =>
        nodes.map((node) =>
          node.id === id
            ? {
                ...node,
                data: {
                  ...node.data,
                  options: node.data.options.map((opt: ChoiceOption) =>
                    opt.id === optionId ? { ...opt, label } : opt
                  ),
                },
              }
            : node
        )
      )
    },
    [id, setNodes]
  )

  const handleSaveCondition = useCallback((optionId: string, condition: Condition) => {
    setNodes((nodes) =>
      nodes.map((node) =>
        node.id === id
          ? {
              ...node,
              data: {
                ...node.data,
                options: node.data.options.map((opt: ChoiceOption) =>
                  opt.id === optionId ? { ...opt, condition } : opt
                ),
              },
            }
          : node
      )
    )
    setEditingConditionOptionId(null)
  }, [id, setNodes])

  const handleRemoveCondition = useCallback((optionId: string) => {
    setNodes((nodes) =>
      nodes.map((node) =>
        node.id === id
          ? {
              ...node,
              data: {
                ...node.data,
                options: node.data.options.map((opt: ChoiceOption) =>
                  opt.id === optionId ? { ...opt, condition: undefined } : opt
                ),
              },
            }
          : node
      )
    )
    setEditingConditionOptionId(null)
  }, [id, setNodes])

  const addOption = useCallback(() => {
    if (data.options.length >= MAX_OPTIONS) return
    setNodes((nodes) =>
      nodes.map((node) =>
        node.id === id
          ? {
              ...node,
              data: {
                ...node.data,
                options: [...node.data.options, { id: nanoid(), label: '' }],
              },
            }
          : node
      )
    )
  }, [id, data.options.length, setNodes])

  const removeOption = useCallback(
    (optionId: string) => {
      if (data.options.length <= MIN_OPTIONS) return
      setNodes((nodes) =>
        nodes.map((node) =>
          node.id === id
            ? {
                ...node,
                data: {
                  ...node.data,
                  options: node.data.options.filter((opt: ChoiceOption) => opt.id !== optionId),
                },
              }
            : node
        )
      )
    },
    [id, data.options.length, setNodes]
  )

  // --- Auxiliares ---

  const editingOption = useMemo(() => {
    if (!editingConditionOptionId) return null
    return data.options.find((opt) => opt.id === editingConditionOptionId) || null
  }, [editingConditionOptionId, data.options])

  const hasInvalidConditionReference = useCallback(
    (option: ChoiceOption) => {
      if (!option.condition?.variableId) return false
      return !variables.some((v) => v.id === option.condition!.variableId)
    },
    [variables]
  )

  const handleFocus = useCallback(() => {
    onNodeFocus(id)
  }, [id, onNodeFocus])

  return (
    <div
      className="relative min-w-[240px] rounded-lg border-2 border-green-500 bg-white p-3 shadow-md dark:border-green-400 dark:bg-zinc-900"
      onFocus={handleFocus}
      onBlur={onNodeBlur}
    >
      {isLockedByOther && (
        <NodeLockIndicator lock={lockInfo} color={lockInfo.color} />
      )}
      {isLockedByOther && (
        <div className="absolute inset-0 z-20 flex items-center justify-center rounded-lg bg-black/10">
          <span className="rounded bg-black/70 px-2 py-1 text-xs text-white">
            Being edited by {lockInfo.displayName}
          </span>
        </div>
      )}
      <Handle type="target" position={Position.Top} className="!bg-green-500" />
      
      <div className="mb-2 flex items-center justify-between">
        <span className="text-[10px] font-bold uppercase text-green-600">Choice Node</span>
      </div>

      <input
        type="text"
        value={data.prompt || ''}
        onChange={updatePrompt}
        placeholder="Dialogue prompt..."
        className="mb-3 w-full rounded border border-zinc-200 bg-zinc-50 px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-green-500 dark:border-zinc-700 dark:bg-zinc-800"
      />

      <div className="space-y-3">
        {data.options.map((option, index) => (
          <div key={option.id} className="group relative">
            <div className="flex items-center gap-1">
              <input
                type="text"
                value={option.label}
                onChange={(e) => updateOptionLabel(option.id, e.target.value)}
                placeholder={`Option ${index + 1}`}
                className="flex-1 rounded border border-zinc-200 px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-green-500 dark:border-zinc-700 dark:bg-zinc-800"
              />
              
              {/* Botão de Condição */}
              <button
                onClick={() => setEditingConditionOptionId(option.id)}
                className={`p-1 rounded transition-colors ${
                  option.condition 
                    ? hasInvalidConditionReference(option)
                      ? 'bg-red-100 text-red-600 dark:bg-red-900/30'
                      : 'bg-amber-100 text-amber-600 dark:bg-amber-900/30'
                    : 'text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800'
                }`}
              >
                <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
                </svg>
              </button>

              <button
                onClick={() => removeOption(option.id)}
                className="text-zinc-400 hover:text-red-500"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>

            {/* Visualização da Condição */}
            {option.condition && (
              <div className={`mt-1 text-[9px] font-mono px-1 rounded ${
                hasInvalidConditionReference(option) ? 'text-red-500 bg-red-50' : 'text-amber-600 bg-amber-50'
              }`}>
                IF: {option.condition.variableName} {option.condition.operator} {option.condition.value}
                {hasInvalidConditionReference(option) && " (Variable Missing!)"}
              </div>
            )}

            <Handle
              type="source"
              position={Position.Bottom}
              id={option.id}
              style={{ left: `${((index + 1) / (data.options.length + 1)) * 100}%` }}
              className="!bg-green-500"
            />
          </div>
        ))}
      </div>

      <button
        onClick={addOption}
        disabled={data.options.length >= MAX_OPTIONS}
        className="mt-3 w-full border border-dashed border-zinc-300 py-1 text-[10px] text-zinc-500 hover:bg-zinc-50 disabled:opacity-50 dark:border-zinc-700 dark:hover:bg-zinc-800"
      >
        + Add Option
      </button>

      {/* Modal de Edição de Condição */}
      {editingOption && (
        <OptionConditionEditor
          condition={editingOption.condition}
          onChange={(cond) => {
            if (cond) {
              handleSaveCondition(editingOption.id, cond)
            } else {
              handleRemoveCondition(editingOption.id)
            }
          }}
          onClose={() => setEditingConditionOptionId(null)}
        />
      )}
    </div>
  )
}