'use client'
import { useState, useCallback, useRef, useEffect } from 'react'
import {
  ReactFlow, Background, Controls, MiniMap,
  addEdge, useNodesState, useEdgesState,
  Handle, Position, type NodeProps, type Connection, type Edge, type Node,
  Panel,
} from '@xyflow/react'
import '@xyflow/react/dist/style.css'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import MenuItem from '@mui/material/MenuItem'
import Chip from '@mui/material/Chip'
import Switch from '@mui/material/Switch'
import FormControlLabel from '@mui/material/FormControlLabel'
import Divider from '@mui/material/Divider'
import CircularProgress from '@mui/material/CircularProgress'
import Alert from '@mui/material/Alert'
import Tooltip from '@mui/material/Tooltip'
import IconButton from '@mui/material/IconButton'
import Dialog from '@mui/material/Dialog'
import DialogTitle from '@mui/material/DialogTitle'
import DialogContent from '@mui/material/DialogContent'
import DialogActions from '@mui/material/DialogActions'

const API = '/api'

// ─── Types ─────────────────────────────────────────────────────────────────────

type PracticeArea =
  | 'immigration' | 'corporate' | 'civil_litigation' | 'property'
  | 'family' | 'employment' | 'criminal' | 'other' | 'universal'

interface StepData {
  stepId: string
  title: string
  description: string
  mandatory: boolean
  deadlineDays: number | ''
  linkedFormTemplateId: string
}

interface FormTemplate { _id: string; name: string }

const PA_OPTIONS: { value: PracticeArea; label: string }[] = [
  { value: 'immigration',      label: 'Immigration' },
  { value: 'corporate',        label: 'Corporate' },
  { value: 'civil_litigation', label: 'Civil Litigation' },
  { value: 'property',         label: 'Property' },
  { value: 'family',           label: 'Family' },
  { value: 'employment',       label: 'Employment' },
  { value: 'criminal',         label: 'Criminal' },
  { value: 'other',            label: 'Other' },
  { value: 'universal',        label: 'Universal' },
]

const PA_COLORS: Record<string, string> = {
  immigration: '#16B1FF', corporate: '#9C6FDE', civil_litigation: '#FF4C51',
  property: '#56CA00', family: '#FFB400', employment: '#0D9394',
  criminal: '#FF6B00', other: '#8A8D93', universal: '#2F3349',
}

function uid() { return `step_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}` }

// ─── Step Node ─────────────────────────────────────────────────────────────────

function StepNode({ data, selected }: NodeProps) {
  const d = data as unknown as StepData & { stepNumber: number; accentColor: string }
  return (
    <Box sx={{
      minWidth: 200, maxWidth: 240,
      bgcolor: 'background.paper',
      border: `2px solid ${selected ? d.accentColor : '#e0e0e0'}`,
      borderRadius: 2,
      boxShadow: selected ? `0 0 0 3px ${d.accentColor}33` : '0 2px 8px rgba(0,0,0,0.12)',
      transition: 'all 0.15s',
      overflow: 'hidden',
    }}>
      {/* Top handle */}
      <Handle type='target' position={Position.Top} style={{ background: '#888', width: 10, height: 10 }} />

      {/* Header bar */}
      <Box sx={{ bgcolor: d.accentColor + '22', px: 1.5, py: 0.75, display: 'flex', alignItems: 'center', gap: 1 }}>
        <Box sx={{
          width: 22, height: 22, borderRadius: '50%',
          bgcolor: d.accentColor, color: '#fff',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: '0.65rem', fontWeight: 700, flexShrink: 0,
        }}>
          {d.stepNumber}
        </Box>
        <Typography sx={{ fontSize: '0.78rem', fontWeight: 700, color: d.accentColor, flex: 1, lineHeight: 1.2 }}>
          {d.title || <span style={{ opacity: 0.4 }}>Untitled step</span>}
        </Typography>
        {d.mandatory && (
          <Chip label='Required' size='small' sx={{ fontSize: '0.55rem', height: 14, bgcolor: '#FF4C5122', color: '#FF4C51' }} />
        )}
      </Box>

      {/* Body */}
      {d.description && (
        <Box sx={{ px: 1.5, py: 0.75 }}>
          <Typography sx={{ fontSize: '0.7rem', color: 'text.secondary', lineHeight: 1.4 }}>
            {d.description.length > 80 ? d.description.slice(0, 80) + '…' : d.description}
          </Typography>
        </Box>
      )}

      {d.deadlineDays !== '' && d.deadlineDays !== undefined && (
        <Box sx={{ px: 1.5, pb: 0.75, display: 'flex', alignItems: 'center', gap: 0.5 }}>
          <i className='ri-calendar-line' style={{ fontSize: '0.7rem', color: '#888' }} />
          <Typography sx={{ fontSize: '0.65rem', color: 'text.disabled' }}>
            {d.deadlineDays}d deadline
          </Typography>
        </Box>
      )}

      {/* Bottom handle */}
      <Handle type='source' position={Position.Bottom} style={{ background: d.accentColor, width: 10, height: 10 }} />
    </Box>
  )
}

const nodeTypes = { step: StepNode }

// ─── Properties Panel ─────────────────────────────────────────────────────────

function PropertiesPanel({
  node,
  formTemplates,
  onChange,
  onDelete,
}: {
  node: Node | null
  formTemplates: FormTemplate[]
  onChange: (id: string, data: Partial<StepData>) => void
  onDelete: (id: string) => void
}) {
  if (!node) {
    return (
      <Box sx={{ p: 2, textAlign: 'center' }}>
        <i className='ri-cursor-line' style={{ fontSize: '2rem', color: '#ccc' }} />
        <Typography variant='caption' color='text.disabled' sx={{ display: 'block', mt: 1 }}>
          Click a step to edit its properties
        </Typography>
      </Box>
    )
  }

  const d = node.data as unknown as StepData

  return (
    <Box sx={{ p: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Typography variant='subtitle2' sx={{ fontWeight: 700 }}>Step Properties</Typography>
        <Tooltip title='Delete step'>
          <IconButton size='small' color='error' onClick={() => onDelete(node.id)}>
            <i className='ri-delete-bin-line' style={{ fontSize: '1rem' }} />
          </IconButton>
        </Tooltip>
      </Box>

      <TextField
        label='Title'
        size='small'
        fullWidth
        value={d.title}
        onChange={e => onChange(node.id, { title: e.target.value })}
        placeholder='e.g. Collect passport copies'
      />

      <TextField
        label='Description'
        size='small'
        fullWidth
        multiline
        rows={3}
        value={d.description}
        onChange={e => onChange(node.id, { description: e.target.value })}
        placeholder='Instructions or notes for this step…'
      />

      <TextField
        label='Deadline (days from matter open)'
        size='small'
        fullWidth
        type='number'
        value={d.deadlineDays}
        onChange={e => onChange(node.id, { deadlineDays: e.target.value === '' ? '' : Number(e.target.value) })}
        inputProps={{ min: 1 }}
        placeholder='e.g. 14'
      />

      {formTemplates.length > 0 && (
        <TextField
          select
          label='Linked form (optional)'
          size='small'
          fullWidth
          value={d.linkedFormTemplateId}
          onChange={e => onChange(node.id, { linkedFormTemplateId: e.target.value })}
        >
          <MenuItem value=''>— None —</MenuItem>
          {formTemplates.map(f => (
            <MenuItem key={f._id} value={f._id}>{f.name}</MenuItem>
          ))}
        </TextField>
      )}

      <FormControlLabel
        control={
          <Switch
            size='small'
            checked={d.mandatory}
            onChange={e => onChange(node.id, { mandatory: e.target.checked })}
          />
        }
        label={<Typography variant='body2'>Required step</Typography>}
      />

      <Box sx={{ p: 1.5, bgcolor: 'action.hover', borderRadius: 1 }}>
        <Typography variant='caption' color='text.secondary' sx={{ lineHeight: 1.5 }}>
          <strong>stepId:</strong> {d.stepId}
        </Typography>
      </Box>
    </Box>
  )
}

// ─── Builder ───────────────────────────────────────────────────────────────────

interface WorkflowBuilderViewProps {
  onSaved?: (templateId: string) => void
  onCancel?: () => void
  /** Pre-load an existing template for editing */
  editId?: string
}

export default function WorkflowBuilderView({ onSaved, onCancel, editId }: WorkflowBuilderViewProps) {
  const [name, setName]               = useState('')
  const [description, setDescription] = useState('')
  const [practiceArea, setPracticeArea] = useState<PracticeArea>('immigration')
  const [nodes, setNodes, onNodesChange] = useNodesState<Node>([])
  const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([])
  const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null)
  const [saving, setSaving]           = useState(false)
  const [error, setError]             = useState<string | null>(null)
  const [formTemplates, setFormTemplates] = useState<FormTemplate[]>([])
  const [saved, setSaved]             = useState(false)
  const [showHelp, setShowHelp]       = useState(false)
  const stepCounter = useRef(1)

  const accentColor = PA_COLORS[practiceArea] ?? '#2F3349'

  // Load form templates for linking
  useEffect(() => {
    fetch(`${API}/form-templates`)
      .then(r => r.ok ? r.json() : [])
      .then(data => setFormTemplates(Array.isArray(data) ? data : []))
      .catch(() => {})
  }, [])

  // Load existing template if editing
  useEffect(() => {
    if (!editId) return
    fetch(`${API}/workflow-templates/${editId}`)
      .then(r => r.ok ? r.json() : null)
      .then(tpl => {
        if (!tpl) return
        setName(tpl.name)
        setDescription(tpl.description ?? '')
        setPracticeArea(tpl.practiceArea ?? 'universal')
        const loadedNodes: Node[] = tpl.steps.map((s: any, i: number) => ({
          id: s.stepId,
          type: 'step',
          position: { x: 300, y: 120 + i * 160 },
          data: {
            stepId: s.stepId,
            title: s.title,
            description: s.description ?? '',
            mandatory: s.mandatory,
            deadlineDays: s.deadlineDays ?? '',
            linkedFormTemplateId: s.linkedFormTemplateId ?? '',
            stepNumber: i + 1,
            accentColor,
          },
        }))
        setNodes(loadedNodes)
        stepCounter.current = tpl.steps.length + 1
        // Rebuild sequential edges
        const loadedEdges: Edge[] = tpl.steps.slice(0, -1).map((s: any, i: number) => ({
          id: `e${i}`,
          source: s.stepId,
          target: tpl.steps[i + 1].stepId,
          type: 'smoothstep',
          animated: false,
        }))
        setEdges(loadedEdges)
      })
      .catch(() => {})
  }, [editId]) // eslint-disable-line

  // Keep accent color in sync on all nodes when practice area changes
  useEffect(() => {
    setNodes(nds => nds.map(n => ({
      ...n,
      data: { ...n.data, accentColor },
    })))
  }, [accentColor, setNodes])

  // Re-number nodes when they change
  useEffect(() => {
    setNodes(nds => {
      // order by y position for numbering
      const sorted = [...nds].sort((a, b) => a.position.y - b.position.y)
      return nds.map(n => ({
        ...n,
        data: {
          ...n.data,
          stepNumber: sorted.findIndex(s => s.id === n.id) + 1,
        },
      }))
    })
  }, [nodes.length, setNodes]) // eslint-disable-line

  const onConnect = useCallback((params: Connection) => {
    setEdges(eds => addEdge({ ...params, type: 'smoothstep', animated: false }, eds))
  }, [setEdges])

  const addStep = useCallback(() => {
    const id = uid()
    const num = stepCounter.current++
    const lastNode = nodes.length > 0
      ? nodes.reduce((a, b) => a.position.y > b.position.y ? a : b)
      : null

    const newNode: Node = {
      id,
      type: 'step',
      position: {
        x: lastNode ? lastNode.position.x : 300,
        y: lastNode ? lastNode.position.y + 160 : 120,
      },
      data: {
        stepId: id,
        title: '',
        description: '',
        mandatory: true,
        deadlineDays: '',
        linkedFormTemplateId: '',
        stepNumber: num,
        accentColor,
      },
    }

    setNodes(nds => [...nds, newNode])

    // Auto-connect from the last node in the chain
    if (lastNode) {
      setEdges(eds => addEdge({
        id: `e_${lastNode.id}_${id}`,
        source: lastNode.id,
        target: id,
        type: 'smoothstep',
        animated: false,
      }, eds))
    }

    setSelectedNodeId(id)
  }, [nodes, accentColor, setNodes, setEdges])

  const updateNodeData = useCallback((nodeId: string, patch: Partial<StepData>) => {
    setNodes(nds => nds.map(n =>
      n.id === nodeId ? { ...n, data: { ...n.data, ...patch } } : n
    ))
  }, [setNodes])

  const deleteNode = useCallback((nodeId: string) => {
    setNodes(nds => nds.filter(n => n.id !== nodeId))
    setEdges(eds => eds.filter(e => e.source !== nodeId && e.target !== nodeId))
    setSelectedNodeId(null)
  }, [setNodes, setEdges])

  // Derive ordered steps from node Y positions (topological-ish for simple linear chains)
  function buildSteps() {
    const sorted = [...nodes].sort((a, b) => a.position.y - b.position.y)
    return sorted.map((n, i) => {
      const d = n.data as unknown as StepData
      return {
        stepId:               d.stepId,
        order:                i + 1,
        title:                d.title.trim() || `Step ${i + 1}`,
        description:          d.description || undefined,
        mandatory:            d.mandatory,
        deadlineDays:         d.deadlineDays !== '' ? Number(d.deadlineDays) : undefined,
        linkedFormTemplateId: d.linkedFormTemplateId || undefined,
      }
    })
  }

  const handleSave = async () => {
    if (!name.trim()) { setError('Template name is required'); return }
    if (nodes.length === 0) { setError('Add at least one step'); return }

    setSaving(true)
    setError(null)
    try {
      const payload = {
        name: name.trim(),
        description: description.trim() || undefined,
        practiceArea,
        steps: buildSteps(),
        isActive: true,
      }

      const url    = editId ? `${API}/workflow-templates/${editId}` : `${API}/workflow-templates`
      const method = editId ? 'PATCH' : 'POST'

      const res = await fetch(url, {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      })
      if (!res.ok) {
        const body = await res.json().catch(() => ({}))
        throw new Error(body.message ?? res.statusText)
      }
      const saved = await res.json()
      setSaved(true)
      onSaved?.(saved._id)
    } catch (e: any) {
      setError(e.message ?? 'Save failed')
    } finally {
      setSaving(false)
    }
  }

  const selectedNode = nodes.find(n => n.id === selectedNodeId) ?? null

  if (saved) {
    return (
      <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', gap: 2 }}>
        <i className='ri-checkbox-circle-fill' style={{ fontSize: '3rem', color: '#56CA00' }} />
        <Typography variant='h6' sx={{ fontWeight: 700 }}>Workflow saved!</Typography>
        <Typography variant='body2' color='text.secondary'>"{name}" is now in the template library.</Typography>
        <Button variant='outlined' onClick={onCancel}>Back to Templates</Button>
      </Box>
    )
  }

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}>

      {/* ── Top bar ──────────────────────────────────────────────────────── */}
      <Box sx={{
        display: 'flex', alignItems: 'center', gap: 2, px: 2, py: 1.5,
        borderBottom: '1px solid', borderColor: 'divider',
        flexWrap: 'wrap',
      }}>
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
          <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: accentColor }} />
          <Typography variant='subtitle1' sx={{ fontWeight: 700 }}>Workflow Builder</Typography>
        </Box>

        <TextField
          size='small'
          placeholder='Template name…'
          value={name}
          onChange={e => setName(e.target.value)}
          sx={{ minWidth: 220, flex: '0 0 auto' }}
          inputProps={{ style: { fontWeight: 600 } }}
        />

        <TextField
          select
          size='small'
          value={practiceArea}
          onChange={e => setPracticeArea(e.target.value as PracticeArea)}
          sx={{ minWidth: 160 }}
        >
          {PA_OPTIONS.map(o => (
            <MenuItem key={o.value} value={o.value}>
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: PA_COLORS[o.value] }} />
                {o.label}
              </Box>
            </MenuItem>
          ))}
        </TextField>

        <TextField
          size='small'
          placeholder='Description (optional)'
          value={description}
          onChange={e => setDescription(e.target.value)}
          sx={{ flex: 1, minWidth: 180 }}
        />

        <Box sx={{ display: 'flex', gap: 1, ml: 'auto' }}>
          <Tooltip title='How to use the builder'>
            <IconButton size='small' onClick={() => setShowHelp(true)}>
              <i className='ri-question-line' />
            </IconButton>
          </Tooltip>
          {onCancel && (
            <Button size='small' variant='outlined' onClick={onCancel} disabled={saving}>
              Cancel
            </Button>
          )}
          <Button
            size='small'
            variant='contained'
            onClick={handleSave}
            disabled={saving || nodes.length === 0 || !name.trim()}
            startIcon={saving ? <CircularProgress size={14} color='inherit' /> : <i className='ri-save-line' />}
          >
            {editId ? 'Update Template' : 'Save Template'}
          </Button>
        </Box>
      </Box>

      {error && (
        <Alert severity='error' onClose={() => setError(null)} sx={{ mx: 2, mt: 1 }}>
          {error}
        </Alert>
      )}

      {/* ── Main area ────────────────────────────────────────────────────── */}
      <Box sx={{ flex: 1, display: 'flex', overflow: 'hidden' }}>

        {/* Canvas */}
        <Box sx={{ flex: 1, position: 'relative' }}>
          <ReactFlow
            nodes={nodes}
            edges={edges}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            onNodeClick={(_, node) => setSelectedNodeId(node.id)}
            onPaneClick={() => setSelectedNodeId(null)}
            nodeTypes={nodeTypes}
            fitView
            fitViewOptions={{ padding: 0.3 }}
            deleteKeyCode='Delete'
            snapToGrid
            snapGrid={[16, 16]}
          >
            <Background gap={16} color='#f0f0f0' />
            <Controls />
            <MiniMap
              nodeColor={n => (n.data as any).accentColor ?? '#888'}
              style={{ border: '1px solid #e0e0e0', borderRadius: 8 }}
            />
            <Panel position='top-left'>
              <Button
                variant='contained'
                size='small'
                onClick={addStep}
                startIcon={<i className='ri-add-line' />}
                sx={{ bgcolor: accentColor, '&:hover': { bgcolor: accentColor + 'cc' } }}
              >
                Add Step
              </Button>
            </Panel>
            <Panel position='bottom-center'>
              <Typography variant='caption' color='text.disabled' sx={{ bgcolor: 'background.paper', px: 1.5, py: 0.5, borderRadius: 2, border: '1px solid #e0e0e0' }}>
                {nodes.length} step{nodes.length !== 1 ? 's' : ''} · Drag handles to connect · Click a step to edit · Delete key removes selected
              </Typography>
            </Panel>
          </ReactFlow>
        </Box>

        {/* Properties panel */}
        <Box sx={{
          width: 280,
          borderLeft: '1px solid',
          borderColor: 'divider',
          overflow: 'auto',
          flexShrink: 0,
        }}>
          <Box sx={{ px: 2, py: 1.5, borderBottom: '1px solid', borderColor: 'divider' }}>
            <Typography variant='caption' color='text.secondary' sx={{ fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>
              {selectedNode ? 'Edit Step' : 'Step Properties'}
            </Typography>
          </Box>
          <PropertiesPanel
            node={selectedNode}
            formTemplates={formTemplates}
            onChange={updateNodeData}
            onDelete={deleteNode}
          />

          {nodes.length > 0 && (
            <>
              <Divider />
              <Box sx={{ px: 2, py: 1.5 }}>
                <Typography variant='caption' color='text.secondary' sx={{ fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, display: 'block', mb: 1 }}>
                  Step Order Preview
                </Typography>
                {[...nodes]
                  .sort((a, b) => a.position.y - b.position.y)
                  .map((n, i) => {
                    const d = n.data as unknown as StepData
                    return (
                      <Box key={n.id}
                        onClick={() => setSelectedNodeId(n.id)}
                        sx={{
                          display: 'flex', alignItems: 'center', gap: 1, py: 0.5,
                          cursor: 'pointer', borderRadius: 1, px: 0.5,
                          bgcolor: selectedNodeId === n.id ? accentColor + '11' : 'transparent',
                          '&:hover': { bgcolor: 'action.hover' },
                        }}
                      >
                        <Typography sx={{ fontSize: '0.6rem', fontWeight: 700, color: accentColor, minWidth: 16 }}>
                          {i + 1}
                        </Typography>
                        <Typography variant='caption' noWrap sx={{ flex: 1, color: d.title ? 'text.primary' : 'text.disabled' }}>
                          {d.title || 'Untitled step'}
                        </Typography>
                        {d.mandatory && <Box sx={{ width: 5, height: 5, borderRadius: '50%', bgcolor: '#FF4C51', flexShrink: 0 }} />}
                      </Box>
                    )
                  })}
              </Box>
            </>
          )}
        </Box>
      </Box>

      {/* ── Help dialog ──────────────────────────────────────────────────── */}
      <Dialog open={showHelp} onClose={() => setShowHelp(false)} maxWidth='xs' fullWidth>
        <DialogTitle sx={{ fontWeight: 700 }}>Using the Workflow Builder</DialogTitle>
        <DialogContent>
          <Box component='ol' sx={{ pl: 2, m: 0, '& li': { mb: 1.5 } }}>
            <li><Typography variant='body2'><strong>Add a step</strong> — click "Add Step". Each new step auto-connects to the previous one.</Typography></li>
            <li><Typography variant='body2'><strong>Edit a step</strong> — click any node to open its properties in the right panel.</Typography></li>
            <li><Typography variant='body2'><strong>Connect steps</strong> — drag from the <strong>bottom handle</strong> of one step to the <strong>top handle</strong> of another to draw a custom path.</Typography></li>
            <li><Typography variant='body2'><strong>Reorder</strong> — drag nodes up or down. Step numbers update automatically based on vertical position.</Typography></li>
            <li><Typography variant='body2'><strong>Delete a step</strong> — select it and press <strong>Delete</strong>, or use the trash icon in the properties panel.</Typography></li>
            <li><Typography variant='body2'><strong>Save</strong> — click "Save Template" once you're happy. The template appears instantly in the library.</Typography></li>
          </Box>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setShowHelp(false)}>Got it</Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}
