'use client'

import { useState, useEffect } from 'react'
import { Button } from './ui/button'
import { Input } from './ui/input'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from './ui/dialog'
import { Badge } from './ui/badge'
import { Tag, X, Plus, Palette } from 'lucide-react'
import { LABEL_COLORS, LabelColorName } from '@/lib/types'
import { cn } from '@/lib/utils'
import { useLabels, Label } from '@/context/LabelContext'

interface LabelManagerProps {
  existingLabels: string[]
  onUpdate: (labels: string[]) => void
}

export function LabelManager({ existingLabels, onUpdate }: LabelManagerProps) {
  const { labels, loading, addLabel, updateLabel, deleteLabel, getLabelColor } = useLabels()
  const [open, setOpen] = useState(false)
  const [newLabel, setNewLabel] = useState('')
  const [selectedLabels, setSelectedLabels] = useState<string[]>(existingLabels)
  const [editingColor, setEditingColor] = useState<string | null>(null)

  // Sync selected labels with existingLabels prop
  useEffect(() => {
    setSelectedLabels(existingLabels)
  }, [existingLabels])

  const handleAddLabel = async () => {
    const trimmed = newLabel.trim()
    if (trimmed && !selectedLabels.includes(trimmed)) {
      try {
        // Get existing label color or use random
        const existingLabel = labels.find(l => l.name === trimmed)
        const color = existingLabel?.color || (Object.keys(LABEL_COLORS) as LabelColorName[])[Math.floor(Math.random() * Object.keys(LABEL_COLORS).length)]
        
        await addLabel(trimmed, color)
        const updated = [...selectedLabels, trimmed]
        setSelectedLabels(updated)
        setNewLabel('')
      } catch (error) {
        console.error('Failed to add label:', error)
      }
    }
  }

  const handleRemoveLabel = (label: string) => {
    setSelectedLabels(selectedLabels.filter(l => l !== label))
  }

  const handleSelectExisting = (label: string) => {
    if (!selectedLabels.includes(label)) {
      setSelectedLabels([...selectedLabels, label])
    } else {
      setSelectedLabels(selectedLabels.filter(l => l !== label))
    }
  }

  const handleChangeColor = async (label: string, color: LabelColorName) => {
    const labelObj = labels.find(l => l.name === label)
    if (labelObj) {
      try {
        await updateLabel(labelObj.id, { color })
        setEditingColor(null)
      } catch (error) {
        console.error('Failed to update label color:', error)
      }
    }
  }

  const handleSave = () => {
    onUpdate(selectedLabels)
    setOpen(false)
  }

  const handleCancel = () => {
    setSelectedLabels(existingLabels)
    setEditingColor(null)
    setOpen(false)
  }

  return (
    <Dialog open={open} onOpenChange={(isOpen) => {
      if (!isOpen) {
        handleCancel()
      } else {
        setOpen(true)
      }
    }}>
      <DialogTrigger asChild>
        <Button variant="ghost" size="sm">
          <Tag className="h-4 w-4 mr-2" />
          Labels
        </Button>
      </DialogTrigger>
      <DialogContent
        className="max-w-md"
        onInteractOutside={(event) => {
          // Prevent dialog from closing when interacting with Sonner toasts
          const target = event.target as HTMLElement;

          const isSonnerElement =
            target.closest('[data-sonner-toast]') ||
            target.closest('[data-sonner-toaster]') ||
            target.closest('[data-icon]') ||
            target.closest('[data-content]') ||
            target.closest('[data-description]') ||
            target.closest('[data-title]') ||
            target.closest('[data-button]');

          if (isSonnerElement) {
            event.preventDefault();
            return;
          }

          if (target.getAttribute('data-sonner-toaster') !== null) {
            event.preventDefault();
            return;
          }
        }}
      >
        <DialogHeader>
          <DialogTitle>Manage Labels</DialogTitle>
          <DialogDescription>
            Add or remove labels for this note. Click on a label to change its color.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-4">
          {/* Add new label */}
          <div className="flex gap-2">
            <Input
              placeholder="New label name"
              value={newLabel}
              onChange={(e) => setNewLabel(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault()
                  handleAddLabel()
                }
              }}
            />
            <Button onClick={handleAddLabel} size="sm">
              <Plus className="h-4 w-4" />
            </Button>
          </div>

          {/* Selected labels */}
          {selectedLabels.length > 0 && (
            <div>
              <h4 className="text-sm font-medium mb-2">Selected Labels</h4>
              <div className="flex flex-wrap gap-2">
                {selectedLabels.map((label) => {
                  const labelObj = labels.find(l => l.name === label)
                  const colorClasses = labelObj ? LABEL_COLORS[labelObj.color] : LABEL_COLORS.gray
                  const isEditing = editingColor === label

                  return (
                    <div key={label} className="relative">
                      {isEditing && labelObj ? (
                        <div className="absolute z-10 top-8 left-0 bg-white dark:bg-zinc-900 border rounded-lg shadow-lg p-2">
                          <div className="grid grid-cols-3 gap-2">
                            {(Object.keys(LABEL_COLORS) as LabelColorName[]).map((color) => {
                              const classes = LABEL_COLORS[color]
                              return (
                                <button
                                  key={color}
                                  className={cn(
                                    'h-8 w-8 rounded-full border-2 transition-transform hover:scale-110',
                                    classes.bg,
                                    labelObj.color === color ? 'border-gray-900 dark:border-gray-100' : 'border-gray-300 dark:border-gray-600'
                                  )}
                                  onClick={() => handleChangeColor(label, color)}
                                  title={color}
                                />
                              )
                            })}
                          </div>
                        </div>
                      ) : null}
                      <Badge
                        className={cn(
                          'text-xs border cursor-pointer pr-1 flex items-center gap-1',
                          colorClasses.bg,
                          colorClasses.text,
                          colorClasses.border
                        )}
                        onClick={() => setEditingColor(isEditing ? null : label)}
                      >
                        <Palette className="h-3 w-3" />
                        {label}
                        <button
                          onClick={(e) => {
                            e.stopPropagation()
                            handleRemoveLabel(label)
                          }}
                          className="ml-1 hover:bg-black/10 dark:hover:bg-white/10 rounded-full p-0.5"
                        >
                          <X className="h-3 w-3" />
                        </button>
                      </Badge>
                    </div>
                  )
                })}
              </div>
            </div>
          )}

          {/* Available labels from context */}
          {!loading && labels.length > 0 && (
            <div>
              <h4 className="text-sm font-medium mb-2">All Labels</h4>
              <div className="flex flex-wrap gap-2">
                {labels
                  .filter(label => !selectedLabels.includes(label.name))
                  .map((label) => {
                    const colorClasses = LABEL_COLORS[label.color]

                    return (
                      <Badge
                        key={label.id}
                        className={cn(
                          'text-xs border cursor-pointer',
                          colorClasses.bg,
                          colorClasses.text,
                          colorClasses.border,
                          'hover:opacity-80'
                        )}
                        onClick={() => handleSelectExisting(label.name)}
                      >
                        {label.name}
                      </Badge>
                    )
                  })}
              </div>
            </div>
          )}
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={handleCancel}>
            Cancel
          </Button>
          <Button onClick={handleSave}>Save</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
