import { useEffect, useRef, useState } from 'react'
import {
  Bell,
  Mail,
  Hash,
  MessageSquare,
  Plus,
  Trash2,
  Loader2,
  Send,
  ToggleLeft,
  ToggleRight,
  ChevronDown,
} from 'lucide-react'
import { notificationsApi } from '@/api/notifications'
import type { NotificationConfig, NotificationConfigCreate, NotificationConfigUpdate } from '@/types/notification'
import { NOTIFICATION_EVENTS, CHANNEL_LABELS } from '@/types/notification'
import { toast } from '@/lib/toast'
import { cn } from '@/lib/utils'
import { Input } from '@/components/ui/Input'

type ChannelType = 'email' | 'slack_webhook' | 'teams_webhook'

const CHANNEL_ICONS: Record<ChannelType, React.ElementType> = {
  email: Mail,
  slack_webhook: Hash,
  teams_webhook: MessageSquare,
}

function maskWebhookUrl(url: string): string {
  if (url.length <= 8) return url
  return '\u2022'.repeat(12) + url.slice(-8)
}

export function NotificationSettings() {
  const [configs, setConfigs] = useState<NotificationConfig[]>([])
  const [loading, setLoading] = useState(true)
  const [addingChannel, setAddingChannel] = useState<ChannelType | null>(null)
  const [testingId, setTestingId] = useState<string | null>(null)
  const [showDropdown, setShowDropdown] = useState(false)
  const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)
  const dropdownRef = useRef<HTMLDivElement>(null)

  // Add form state
  const [newWebhookUrl, setNewWebhookUrl] = useState('')
  const [newEmails, setNewEmails] = useState('')
  const [isSaving, setIsSaving] = useState(false)

  useEffect(() => {
    loadConfigs()
  }, [])

  // Close dropdown on outside click
  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setShowDropdown(false)
      }
    }
    if (showDropdown) {
      document.addEventListener('mousedown', handleClickOutside)
      return () => document.removeEventListener('mousedown', handleClickOutside)
    }
  }, [showDropdown])

  const loadConfigs = async () => {
    try {
      const data = await notificationsApi.listConfigs()
      setConfigs(data)
    } catch (err) {
      console.error('Failed to load notification configs:', err)
      toast.error('Failed to load notification settings')
    } finally {
      setLoading(false)
    }
  }

  const handleAddChannel = (channel: ChannelType) => {
    setAddingChannel(channel)
    setShowDropdown(false)
    setNewWebhookUrl('')
    setNewEmails('')
  }

  const handleSaveNew = async () => {
    if (!addingChannel) return
    setIsSaving(true)
    try {
      const payload: NotificationConfigCreate = { channel: addingChannel }
      if (addingChannel === 'email') {
        const emails = newEmails.split(',').map(e => e.trim()).filter(Boolean)
        if (emails.length === 0) {
          toast.error('Please enter at least one email address')
          setIsSaving(false)
          return
        }
        payload.email_addresses = emails
      } else {
        if (!newWebhookUrl.trim()) {
          toast.error('Please enter a webhook URL')
          setIsSaving(false)
          return
        }
        payload.webhook_url = newWebhookUrl.trim()
      }
      await notificationsApi.createConfig(payload)
      await loadConfigs()
      setAddingChannel(null)
      setNewWebhookUrl('')
      setNewEmails('')
      toast.success(`${CHANNEL_LABELS[addingChannel]} channel added`)
    } catch (err) {
      console.error('Failed to create notification config:', err)
      toast.error('Failed to add channel')
    } finally {
      setIsSaving(false)
    }
  }

  const handleToggleActive = async (config: NotificationConfig) => {
    try {
      const update: NotificationConfigUpdate = { is_active: !config.is_active }
      await notificationsApi.updateConfig(config.id, update)
      setConfigs(prev => prev.map(c => c.id === config.id ? { ...c, is_active: !c.is_active } : c))
      toast.success(config.is_active ? 'Channel disabled' : 'Channel enabled')
    } catch (err) {
      console.error('Failed to toggle config:', err)
      toast.error('Failed to update channel')
    }
  }

  const handleToggleEvent = async (config: NotificationConfig, eventKey: string) => {
    const updated = { ...config.events_enabled, [eventKey]: !config.events_enabled[eventKey] }
    try {
      await notificationsApi.updateConfig(config.id, { events_enabled: updated })
      setConfigs(prev => prev.map(c => c.id === config.id ? { ...c, events_enabled: updated } : c))
    } catch (err) {
      console.error('Failed to update events:', err)
      toast.error('Failed to update event settings')
    }
  }

  const handleTest = async (configId: string) => {
    setTestingId(configId)
    try {
      const result = await notificationsApi.testConfig(configId)
      if (result.success) {
        toast.success(result.message || 'Test notification sent')
      } else {
        toast.error(result.message || 'Test failed')
      }
    } catch (err) {
      console.error('Failed to test config:', err)
      toast.error('Test notification failed')
    } finally {
      setTestingId(null)
    }
  }

  const handleDelete = async (configId: string) => {
    try {
      await notificationsApi.deleteConfig(configId)
      setConfigs(prev => prev.filter(c => c.id !== configId))
      toast.success('Channel removed')
    } catch (err) {
      console.error('Failed to delete config:', err)
      toast.error('Failed to remove channel')
    }
  }

  return (
    <div>
      {/* Section header */}
      <div className="mb-6 flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Bell className="h-6 w-6 text-muted-foreground" />
          <h2 className="text-xl font-semibold font-heading text-foreground">Notifications</h2>
        </div>

        <div className="relative" ref={dropdownRef}>
          <button
            onClick={() => setShowDropdown(!showDropdown)}
            className={cn(
              'inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium',
              'bg-[rgba(255,255,255,0.04)] border border-[rgba(255,255,255,0.06)] text-foreground',
              'hover:border-[rgba(255,255,255,0.12)] transition-all'
            )}
          >
            <Plus className="h-4 w-4" />
            Add Channel
            <ChevronDown className="h-3.5 w-3.5" />
          </button>

          {showDropdown && (
            <div className="absolute right-0 mt-1 z-20 w-48 rounded-xl border border-border bg-card shadow-xl">
              {(Object.entries(CHANNEL_LABELS) as [ChannelType, string][]).map(([key, label]) => {
                const Icon = CHANNEL_ICONS[key]
                return (
                  <button
                    key={key}
                    onClick={() => handleAddChannel(key)}
                    className="flex w-full items-center gap-2.5 px-4 py-2.5 text-sm text-foreground hover:bg-[rgba(255,255,255,0.04)] first:rounded-t-xl last:rounded-b-xl transition-colors"
                  >
                    <Icon className="h-4 w-4 text-muted-foreground" />
                    {label}
                  </button>
                )
              })}
            </div>
          )}
        </div>
      </div>

      {/* Loading */}
      {loading && (
        <div className="flex justify-center py-8">
          <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
        </div>
      )}

      {/* Empty state */}
      {!loading && configs.length === 0 && !addingChannel && (
        <div className="card-flat p-6 text-center">
          <Bell className="mx-auto h-8 w-8 text-muted-foreground/50 mb-3" />
          <p className="text-sm text-muted-foreground">
            No notification channels configured. Add a channel to receive alerts for session events.
          </p>
        </div>
      )}

      {/* Channel list */}
      {!loading && (
        <div className="space-y-4">
          {configs.map(config => {
            const Icon = CHANNEL_ICONS[config.channel]
            return (
              <div key={config.id} className="card-flat p-5">
                {/* Header row */}
                <div className="flex items-center gap-3 mb-4">
                  <Icon className="h-5 w-5 text-muted-foreground" />
                  <span className="text-sm font-medium text-foreground">
                    {CHANNEL_LABELS[config.channel]}
                  </span>
                  <span
                    className={cn(
                      'inline-flex h-2 w-2 rounded-full',
                      config.is_active ? 'bg-emerald-400' : 'bg-muted-foreground'
                    )}
                  />
                  <span className={cn(
                    'text-xs font-sans text-xs',
                    config.is_active ? 'text-emerald-400' : 'text-muted-foreground'
                  )}>
                    {config.is_active ? 'Active' : 'Inactive'}
                  </span>
                </div>

                {/* Config details */}
                <div className="mb-4">
                  {config.webhook_url && (
                    <div>
                      <span className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                        Webhook URL
                      </span>
                      <p className="mt-0.5 text-sm text-foreground font-mono">
                        {maskWebhookUrl(config.webhook_url)}
                      </p>
                    </div>
                  )}
                  {config.email_addresses && config.email_addresses.length > 0 && (
                    <div>
                      <span className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                        Email Addresses
                      </span>
                      <p className="mt-0.5 text-sm text-foreground">
                        {config.email_addresses.join(', ')}
                      </p>
                    </div>
                  )}
                </div>

                {/* Event toggles */}
                <div className="mb-4">
                  <span className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                    Events
                  </span>
                  <div className="mt-2 grid gap-2 sm:grid-cols-2">
                    {Object.entries(NOTIFICATION_EVENTS).map(([eventKey, eventLabel]) => (
                      <label
                        key={eventKey}
                        className="flex items-center gap-2 cursor-pointer"
                      >
                        <input
                          type="checkbox"
                          checked={config.events_enabled[eventKey] ?? false}
                          onChange={() => handleToggleEvent(config, eventKey)}
                          className="h-3.5 w-3.5 rounded border-border bg-card text-primary focus:ring-primary/30 focus:ring-offset-0 cursor-pointer accent-[#3b82f6]"
                        />
                        <span className="text-sm text-foreground">{eventLabel}</span>
                      </label>
                    ))}
                  </div>
                </div>

                {/* Action buttons */}
                <div className="flex items-center gap-3 pt-2 border-t border-border">
                  <button
                    onClick={() => handleToggleActive(config)}
                    className={cn(
                      'inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium',
                      'bg-[rgba(255,255,255,0.04)] border border-[rgba(255,255,255,0.06)] text-foreground',
                      'hover:border-[rgba(255,255,255,0.12)] transition-all'
                    )}
                  >
                    {config.is_active ? (
                      <ToggleRight className="h-4 w-4 text-emerald-400" />
                    ) : (
                      <ToggleLeft className="h-4 w-4 text-muted-foreground" />
                    )}
                    {config.is_active ? 'Disable' : 'Enable'}
                  </button>

                  <button
                    onClick={() => handleTest(config.id)}
                    disabled={testingId === config.id}
                    className={cn(
                      'inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium',
                      'bg-[rgba(255,255,255,0.04)] border border-[rgba(255,255,255,0.06)] text-foreground',
                      'hover:border-[rgba(255,255,255,0.12)] transition-all',
                      'disabled:opacity-50 disabled:cursor-not-allowed'
                    )}
                  >
                    {testingId === config.id ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <Send className="h-4 w-4" />
                    )}
                    Test
                  </button>

                  {confirmDeleteId === config.id ? (
                    <button
                      onClick={() => { handleDelete(config.id); setConfirmDeleteId(null) }}
                      className="ml-auto inline-flex items-center gap-1.5 text-sm text-red-400 hover:text-red-300 transition-colors font-medium"
                    >
                      <Trash2 className="h-4 w-4" />
                      Confirm Remove
                    </button>
                  ) : (
                    <button
                      onClick={() => setConfirmDeleteId(config.id)}
                      className="ml-auto inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-red-400 transition-colors"
                    >
                      <Trash2 className="h-4 w-4" />
                      Remove
                    </button>
                  )}
                </div>
              </div>
            )
          })}

          {/* Inline add form */}
          {addingChannel && (
            <div className="card-flat p-5">
              <div className="flex items-center gap-3 mb-4">
                {(() => {
                  const Icon = CHANNEL_ICONS[addingChannel]
                  return <Icon className="h-5 w-5 text-muted-foreground" />
                })()}
                <span className="text-sm font-medium text-foreground">
                  Add {CHANNEL_LABELS[addingChannel]}
                </span>
              </div>

              {addingChannel === 'email' ? (
                <div>
                  <label className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                    Email Addresses
                  </label>
                  <Input
                    type="text"
                    value={newEmails}
                    onChange={(e) => setNewEmails(e.target.value)}
                    placeholder="user@example.com, team@example.com"
                    className="mt-1"
                  />
                  <p className="mt-1 text-xs text-muted-foreground">
                    Separate multiple addresses with commas
                  </p>
                </div>
              ) : (
                <div>
                  <label className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                    Webhook URL
                  </label>
                  <Input
                    type="url"
                    value={newWebhookUrl}
                    onChange={(e) => setNewWebhookUrl(e.target.value)}
                    placeholder={
                      addingChannel === 'slack_webhook'
                        ? 'https://hooks.slack.com/services/...'
                        : 'https://outlook.office.com/webhook/...'
                    }
                    className="mt-1"
                  />
                </div>
              )}

              <div className="flex items-center gap-3 mt-4">
                <button
                  onClick={handleSaveNew}
                  disabled={isSaving}
                  className={cn(
                    'inline-flex items-center gap-2 rounded-lg px-5 py-2.5 text-sm font-semibold',
                    'bg-primary text-white',
                    'hover:brightness-110 active:scale-[0.98] transition-all',
                    'disabled:opacity-50 disabled:cursor-not-allowed'
                  )}
                >
                  {isSaving && <Loader2 className="h-4 w-4 animate-spin" />}
                  Save
                </button>
                <button
                  onClick={() => setAddingChannel(null)}
                  className="text-sm text-muted-foreground hover:text-foreground transition-colors"
                >
                  Cancel
                </button>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export default NotificationSettings
