'use client'

import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Plus, Trash2 } from 'lucide-react'
import type { Node } from '@xyflow/react'
import { NODE_TYPE_LABELS } from '@/lib/mail-automation/node-definitions'
import {
  actionTypesForDomains,
  AUTOMATION_DOMAIN_LABELS,
  conditionFieldsForDomains,
  inferDomainsFromTriggers,
  primaryDomainFromTriggers,
} from '@/lib/mail-automation/domains'
import { useAutomationDomains } from './automation-domain-context'
import { isBooleanConditionField, isLabelConditionField } from '@/lib/mail-automation/condition-helpers'
import {
  actionValueSuggestionKind,
  conditionValueSuggestionKind,
  defaultOperatorForField,
  formatConditionSummary,
  operatorOptionsForConditionField,
  switchFieldSuggestionKind,
} from '@/lib/mail-automation/condition-helpers'
import type {
  ActionsNodeData,
  ConditionNodeData,
  LLMCheckNodeData,
  SetVarNodeData,
  SwitchNodeData,
  CallRuleNodeData,
  WorkflowNodeType,
  ConditionField,
} from '@/lib/mail-automation/types'
import type { ApiRule } from '@/lib/api/types'
import { createEmptyAction } from '@/lib/mail-automation/defaults'
import { AutomationSuggestInput } from './automation-suggest-input'
import { Input } from '@/components/ui/input'

interface WorkflowNodeInspectorProps {
  node: Node | null
  allRules: ApiRule[]
  onUpdate: (nodeId: string, data: Record<string, unknown>) => void
  onDelete: (nodeId: string) => void
  triggers?: import('@/lib/mail-automation/types').TriggerOrGroup
}

export function WorkflowNodeInspector({
  node,
  allRules,
  onUpdate,
  onDelete,
  triggers,
}: WorkflowNodeInspectorProps) {
  const contextDomains = useAutomationDomains()
  const activeDomains = triggers ? inferDomainsFromTriggers(triggers) : contextDomains
  const conditionFields = conditionFieldsForDomains(activeDomains)
  const actionTypes = actionTypesForDomains(activeDomains)
  const primaryDomain = primaryDomainFromTriggers(
    triggers ?? { operator: 'or', groups: [{ operator: 'and', items: [] }] }
  )

  if (!node || node.type === 'start' || node.type === 'end') {
    return (
      <div className="flex h-full items-center justify-center p-4 text-center text-xs text-muted-foreground">
        Sélectionnez un nœud pour le configurer
      </div>
    )
  }

  const type = node.type as WorkflowNodeType
  const data = node.data as unknown as Record<string, unknown>

  function patch(partial: Record<string, unknown>) {
    onUpdate(node!.id, { ...data, ...partial })
  }

  return (
    <div className="flex h-full flex-col overflow-hidden">
      <div className="flex items-start justify-between gap-2 border-b border-border px-3 py-2">
        <div className="min-w-0">
          <p className="text-sm font-medium">{NODE_TYPE_LABELS[type]}</p>
          <p className="truncate font-mono text-[10px] text-muted-foreground">{node.id}</p>
        </div>
        <Button
          type="button"
          variant="ghost"
          size="icon"
          className="size-8 shrink-0 text-muted-foreground hover:text-destructive"
          title="Supprimer le nœud"
          onClick={() => onDelete(node.id)}
        >
          <Trash2 className="size-4" />
        </Button>
      </div>
      <div className="flex-1 space-y-3 overflow-y-auto p-3">
        {type === 'condition' || type === 'label_check' ? (
          <ConditionEditor
            fields={conditionFields}
            data={
              type === 'label_check'
                ? {
                    field: 'label',
                    operator: (data as { operator?: string }).operator === 'not_has' ? 'not_has' : 'has',
                    value: String((data as { label?: string }).label ?? ''),
                  }
                : (data as unknown as ConditionNodeData)
            }
            onChange={patch}
          />
        ) : null}
        {type === 'switch' ? (
          <SwitchEditor fields={conditionFields} data={data as unknown as SwitchNodeData} onChange={patch} />
        ) : null}
        {type === 'llm_check' ? (
          <LLMEditor data={data as unknown as LLMCheckNodeData} onChange={patch} />
        ) : null}
        {type === 'actions' ? (
          <ActionsEditor
            actionTypes={actionTypes}
            primaryDomain={primaryDomain}
            data={data as unknown as ActionsNodeData}
            onChange={patch}
          />
        ) : null}
        {type === 'set_var' ? (
          <SetVarEditor data={data as unknown as SetVarNodeData} onChange={patch} />
        ) : null}
        {type === 'call_function' || type === 'call_rule' ? (
          <CallRuleEditor
            data={data as unknown as CallRuleNodeData}
            allRules={allRules}
            kindFilter={type === 'call_function' ? 'function' : 'rule'}
            onChange={patch}
          />
        ) : null}
      </div>
    </div>
  )
}

function ConditionEditor({
  fields,
  data,
  onChange,
}: {
  fields: { value: ConditionField; label: string; domain: import('@/lib/mail-automation/domains').AutomationDomain }[]
  data: ConditionNodeData
  onChange: (p: Partial<ConditionNodeData>) => void
}) {
  const operatorOptions = operatorOptionsForConditionField(data.field)
  const valueKind = conditionValueSuggestionKind(data.field, data.operator)
  const isRegex = data.operator === 'regex' || data.operator === 'not_regex'

  function onFieldChange(field: ConditionField) {
    onChange({
      field,
      operator: defaultOperatorForField(field),
      value: isBooleanConditionField(field) ? 'true' : '',
    })
  }

  return (
    <>
      <DomainGroupedFieldSelect
        label="Champ"
        value={data.field}
        fields={fields}
        onChange={(v) => onFieldChange(v as ConditionField)}
      />
      <FieldSelect
        label={isLabelConditionField(data.field) ? 'Mode' : 'Opérateur'}
        value={data.operator}
        options={operatorOptions}
        onChange={(v) => onChange({ operator: v as ConditionNodeData['operator'] })}
      />
      <div>
        <Label className="text-xs">
          {isLabelConditionField(data.field) ? 'Libellé' : isRegex ? 'Expression régulière' : 'Valeur'}
        </Label>
        <div className="mt-1">
          {isBooleanConditionField(data.field) ? (
            <FieldSelect
              label=""
              value={data.value || 'true'}
              options={[
                { value: 'true', label: 'Oui' },
                { value: 'false', label: 'Non' },
              ]}
              onChange={(v) => onChange({ value: v })}
            />
          ) : (
            <AutomationSuggestInput
              kind={valueKind}
              value={data.value}
              placeholder={isRegex ? '(?i)facture|invoice' : undefined}
              onChange={(value) => onChange({ value })}
            />
          )}
        </div>
      </div>
    </>
  )
}

function SwitchEditor({
  fields,
  data,
  onChange,
}: {
  fields: { value: ConditionField; label: string; domain: import('@/lib/mail-automation/domains').AutomationDomain }[]
  data: SwitchNodeData
  onChange: (p: Partial<SwitchNodeData>) => void
}) {
  const cases = data.cases ?? []
  const fieldKind = switchFieldSuggestionKind(data.field)

  return (
    <>
      <DomainGroupedFieldSelect
        label="Champ"
        value={data.field}
        fields={fields}
        onChange={(v) => onChange({ field: v })}
      />
      <div className="space-y-2">
        <Label className="text-xs">Cas de sortie</Label>
        {cases.map((c, i) => (
          <div key={i} className="flex gap-1">
            <AutomationSuggestInput
              kind={fieldKind}
              className="flex-1"
              placeholder="Valeur"
              value={c.value}
              onChange={(value) => {
                const next = [...cases]
                next[i] = { ...c, value }
                onChange({ cases: next })
              }}
            />
            <Input
              className="h-8 flex-1 text-xs"
              placeholder="Libellé"
              value={c.label ?? ''}
              onChange={(e) => {
                const next = [...cases]
                next[i] = { ...c, label: e.target.value }
                onChange({ cases: next })
              }}
            />
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className="size-8 shrink-0"
              onClick={() => onChange({ cases: cases.filter((_, j) => j !== i) })}
            >
              <Trash2 className="size-3.5" />
            </Button>
          </div>
        ))}
        <Button type="button" variant="outline" size="sm" className="h-7 w-full text-xs" onClick={() => onChange({ cases: [...cases, { value: '', label: '' }] })}>
          <Plus className="mr-1 size-3" />
          Ajouter un cas
        </Button>
      </div>
    </>
  )
}

function LLMEditor({
  data,
  onChange,
}: {
  data: LLMCheckNodeData
  onChange: (p: Partial<LLMCheckNodeData>) => void
}) {
  return (
    <>
      <div>
        <Label className="text-xs">Prompt</Label>
        <textarea
          className="mt-1 min-h-20 w-full rounded-md border border-input bg-background px-2 py-1.5 text-xs"
          value={data.prompt}
          onChange={(e) => onChange({ prompt: e.target.value })}
        />
      </div>
      <div>
        <Label className="text-xs">Fournisseur (optionnel)</Label>
        <Input className="mt-1 h-8 text-xs" value={data.provider ?? ''} onChange={(e) => onChange({ provider: e.target.value })} />
      </div>
    </>
  )
}

function ActionsEditor({
  actionTypes,
  primaryDomain,
  data,
  onChange,
}: {
  actionTypes: ReturnType<typeof actionTypesForDomains>
  primaryDomain: import('@/lib/mail-automation/domains').AutomationDomain
  data: ActionsNodeData
  onChange: (p: Partial<ActionsNodeData>) => void
}) {
  const actions = data.actions ?? []
  const grouped = ['universal', 'mail', 'drive', 'contacts'] as const

  return (
    <div className="space-y-2">
      {actions.map((action, i) => {
        const meta = actionTypes.find((a) => a.value === action.type)
        const suggestKind = actionValueSuggestionKind(action.type)
        return (
          <div key={i} className="space-y-1 rounded border border-border/60 p-2">
            <Select value={action.type} onValueChange={(v) => {
              const next = [...actions]
              next[i] = { ...action, type: v as typeof action.type, value: '' }
              onChange({ actions: next })
            }}>
              <SelectTrigger className="h-8 text-xs"><SelectValue /></SelectTrigger>
              <SelectContent>
                {grouped.map((group) => {
                  const items = actionTypes.filter((a) => a.domain === group)
                  if (items.length === 0) return null
                  const groupLabel =
                    group === 'universal' ? 'Commun' : AUTOMATION_DOMAIN_LABELS[group]
                  return (
                    <SelectGroup key={group}>
                      <SelectLabel className="text-[10px]">{groupLabel}</SelectLabel>
                      {items.map((a) => (
                        <SelectItem key={a.value} value={a.value} className="text-xs">
                          {a.label}
                        </SelectItem>
                      ))}
                    </SelectGroup>
                  )
                })}
              </SelectContent>
            </Select>
            {meta?.needsValue ? (
              <AutomationSuggestInput
                kind={suggestKind}
                value={action.value}
                placeholder={meta.placeholder}
                onChange={(value) => {
                  const next = [...actions]
                  next[i] = { ...action, value }
                  onChange({ actions: next })
                }}
              />
            ) : null}
            <Button type="button" variant="ghost" size="sm" className="h-6 text-xs" onClick={() => onChange({ actions: actions.filter((_, j) => j !== i) })}>
              Retirer
            </Button>
          </div>
        )
      })}
      <Button
        type="button"
        variant="outline"
        size="sm"
        className="h-7 w-full text-xs"
        onClick={() => onChange({ actions: [...actions, createEmptyAction(primaryDomain)] })}
      >
        <Plus className="mr-1 size-3" />
        Ajouter une action
      </Button>
    </div>
  )
}

function SetVarEditor({
  data,
  onChange,
}: {
  data: SetVarNodeData
  onChange: (p: Partial<SetVarNodeData>) => void
}) {
  return (
    <>
      <div>
        <Label className="text-xs">Nom</Label>
        <Input className="mt-1 h-8 font-mono text-xs" value={data.name} onChange={(e) => onChange({ name: e.target.value })} />
      </div>
      <div>
        <Label className="text-xs">Valeur ({"{{var}}"} pour interpolation)</Label>
        <Input className="mt-1 h-8 font-mono text-xs" value={data.value} onChange={(e) => onChange({ value: e.target.value })} />
      </div>
    </>
  )
}

function CallRuleEditor({
  data,
  allRules,
  kindFilter,
  onChange,
}: {
  data: CallRuleNodeData
  allRules: ApiRule[]
  kindFilter: 'rule' | 'function'
  onChange: (p: Partial<CallRuleNodeData>) => void
}) {
  const options = allRules.filter((r) => (r.rule_kind ?? 'rule') === kindFilter)
  return (
    <div>
      <Label className="text-xs">{kindFilter === 'function' ? 'Fonction' : 'Règle'}</Label>
      <Select value={data.rule_id || undefined} onValueChange={(v) => onChange({ rule_id: v })}>
        <SelectTrigger className="mt-1 h-8 text-xs"><SelectValue placeholder="Choisir…" /></SelectTrigger>
        <SelectContent>
          {options.map((r) => (
            <SelectItem key={r.id} value={r.id} className="text-xs">{r.name}</SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  )
}

function DomainGroupedFieldSelect({
  label,
  value,
  fields,
  onChange,
}: {
  label: string
  value: string
  fields: { value: ConditionField; label: string; domain: import('@/lib/mail-automation/domains').AutomationDomain }[]
  onChange: (v: string) => void
}) {
  const domains = [...new Set(fields.map((f) => f.domain))]
  return (
    <div>
      {label ? <Label className="text-xs">{label}</Label> : null}
      <Select value={value} onValueChange={onChange}>
        <SelectTrigger className={label ? 'mt-1 h-8 text-xs' : 'h-8 text-xs'}><SelectValue /></SelectTrigger>
        <SelectContent>
          {domains.map((domain) => (
            <SelectGroup key={domain}>
              <SelectLabel className="text-[10px]">{AUTOMATION_DOMAIN_LABELS[domain]}</SelectLabel>
              {fields
                .filter((f) => f.domain === domain)
                .map((f) => (
                  <SelectItem key={f.value} value={f.value} className="text-xs">
                    {f.label}
                  </SelectItem>
                ))}
            </SelectGroup>
          ))}
        </SelectContent>
      </Select>
    </div>
  )
}

function FieldSelect({
  label,
  value,
  options,
  onChange,
}: {
  label: string
  value: string
  options: { value: string; label: string }[]
  onChange: (v: string) => void
}) {
  return (
    <div>
      {label ? <Label className="text-xs">{label}</Label> : null}
      <Select value={value} onValueChange={onChange}>
        <SelectTrigger className={label ? 'mt-1 h-8 text-xs' : 'h-8 text-xs'}><SelectValue /></SelectTrigger>
        <SelectContent>
          {options.map((o) => (
            <SelectItem key={o.value} value={o.value} className="text-xs">{o.label}</SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  )
}
