'use client'

import { useState, useEffect, useRef, useCallback, useMemo } from 'react'
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { JefflixLogo } from "@/components/jefflix-logo"
import { GlobeLoader, type GlobePoint } from "@/components/globe/globe-loader"
import { countryToLatLng } from "@/lib/country-centroids"
import { Search, CheckCircle, AlertCircle, ArrowLeft, X, Loader2, Globe2, List } from "lucide-react"
import Link from 'next/link'

interface Channel {
  id: string
  name: string
  country: string
  categories: string[]
}

export default function RequestChannelPage() {
  const [channels, setChannels] = useState<Channel[]>([])
  const [loading, setLoading] = useState(true)
  const [loadError, setLoadError] = useState('')
  const [query, setQuery] = useState('')
  const [debouncedQuery, setDebouncedQuery] = useState('')
  const [selected, setSelected] = useState<Channel[]>([])
  const [email, setEmail] = useState('')
  const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle')
  const [errorMessage, setErrorMessage] = useState('')
  const debounceRef = useRef<NodeJS.Timeout>(null)

  // Globe view toggle
  const [view, setView] = useState<'search' | 'globe'>('search')
  const [globeCountry, setGlobeCountry] = useState<string | null>(null)

  // Build globe points from channels (aggregate by country)
  const globePoints: GlobePoint[] = useMemo(() => {
    const countryMap = new Map<string, { count: number; coords: [number, number] }>()
    for (const ch of channels) {
      if (!ch.country) continue
      const existing = countryMap.get(ch.country)
      if (existing) {
        existing.count++
      } else {
        const coords = countryToLatLng(ch.country)
        if (coords) {
          countryMap.set(ch.country, { count: 1, coords })
        }
      }
    }
    return Array.from(countryMap.entries()).map(([country, { count, coords }]) => ({
      lat: coords[0],
      lng: coords[1],
      id: country,
      label: `${country} (${count} channels)`,
      color: '#06b6d4', // cyan-500
      size: Math.max(1, Math.min(8, Math.log2(count + 1) * 2)),
    }))
  }, [channels])

  // Channels filtered for globe-selected country
  const globeFilteredChannels = useMemo(() => {
    if (!globeCountry) return []
    return channels.filter((ch) => ch.country === globeCountry)
  }, [channels, globeCountry])

  const handleGlobePointClick = useCallback((point: GlobePoint) => {
    setGlobeCountry(point.id) // id = country name
  }, [])

  // Fetch channel list on mount
  useEffect(() => {
    fetch('/api/channels')
      .then((res) => {
        if (!res.ok) throw new Error('Failed to load channels')
        return res.json()
      })
      .then((data: Channel[]) => {
        setChannels(data)
        setLoading(false)
      })
      .catch((err) => {
        setLoadError(err.message)
        setLoading(false)
      })
  }, [])

  // Debounce search input
  useEffect(() => {
    debounceRef.current = setTimeout(() => setDebouncedQuery(query), 200)
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current) }
  }, [query])

  const results = debouncedQuery.length < 2
    ? []
    : channels.filter((ch) => {
        const q = debouncedQuery.toLowerCase()
        return (
          ch.name.toLowerCase().includes(q) ||
          ch.country.toLowerCase().includes(q) ||
          ch.categories.some((c) => c.toLowerCase().includes(q))
        )
      })

  const totalMatches = results.length
  const displayResults = results.slice(0, 50)

  const toggleChannel = useCallback((ch: Channel) => {
    setSelected((prev) =>
      prev.some((s) => s.id === ch.id)
        ? prev.filter((s) => s.id !== ch.id)
        : prev.length < 20
          ? [...prev, ch]
          : prev
    )
  }, [])

  const removeChannel = useCallback((id: string) => {
    setSelected((prev) => prev.filter((s) => s.id !== id))
  }, [])

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (selected.length === 0) return
    setStatus('submitting')
    setErrorMessage('')

    try {
      const res = await fetch('/api/request-channel', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          email,
          channels: selected.map(({ id, name, country, categories }) => ({
            id, name, country, categories,
          })),
        }),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data.error || 'Failed to submit request')
      setStatus('success')
    } catch (err) {
      setStatus('error')
      setErrorMessage(err instanceof Error ? err.message : 'Something went wrong')
    }
  }

  if (status === 'success') {
    return (
      <div className="min-h-screen bg-background flex items-center justify-center p-4">
        <div className="max-w-md w-full text-center space-y-6">
          <div className="inline-block p-6 bg-green-100 dark:bg-green-900/30 rounded-full">
            <CheckCircle className="h-12 w-12 text-green-600 dark:text-green-400" />
          </div>
          <h1 className="text-2xl font-bold">Request Submitted!</h1>
          <p className="text-muted-foreground">
            We&apos;ll look into adding {selected.length === 1 ? 'this channel' : `these ${selected.length} channels`} and
            let you know once {selected.length === 1 ? "it's" : "they're"} available.
          </p>
          <p className="text-sm text-muted-foreground">
            Most channels are added within a few days.
          </p>
          <Link href="/">
            <Button variant="outline" className="mt-4">
              <ArrowLeft className="mr-2 h-4 w-4" />
              Back to Jefflix
            </Button>
          </Link>
        </div>
      </div>
    )
  }

  return (
    <div className="min-h-screen bg-background">
      {/* Header */}
      <div className="border-b border-border">
        <div className="container mx-auto px-4 py-4">
          <Link href="/" className="inline-block">
            <JefflixLogo size="small" />
          </Link>
        </div>
      </div>

      {/* Main Content */}
      <div className="container mx-auto px-4 py-12 md:py-20">
        <div className="max-w-2xl mx-auto">
          <div className="text-center space-y-4 mb-8">
            <div className="inline-block p-4 bg-cyan-100 dark:bg-cyan-900/30 rounded-full">
              <Search className="h-10 w-10 text-cyan-600 dark:text-cyan-400" />
            </div>
            <h1 className="text-3xl font-bold font-marker">Request a Channel</h1>
            <p className="text-muted-foreground">
              Search the iptv-org catalog and select channels you&apos;d like us to add to the Live TV lineup.
            </p>

            {/* View toggle */}
            {!loading && !loadError && (
              <div className="flex items-center justify-center gap-2">
                <Button
                  variant={view === 'search' ? 'default' : 'outline'}
                  size="sm"
                  onClick={() => setView('search')}
                  className={view === 'search' ? 'bg-cyan-600 hover:bg-cyan-700' : ''}
                >
                  <List className="h-4 w-4 mr-1.5" />
                  Search
                </Button>
                <Button
                  variant={view === 'globe' ? 'default' : 'outline'}
                  size="sm"
                  onClick={() => setView('globe')}
                  className={view === 'globe' ? 'bg-cyan-600 hover:bg-cyan-700' : ''}
                >
                  <Globe2 className="h-4 w-4 mr-1.5" />
                  Globe
                </Button>
              </div>
            )}
          </div>

          {loading ? (
            <div className="flex flex-col items-center gap-4 py-16">
              <Loader2 className="h-8 w-8 animate-spin text-cyan-600" />
              <p className="text-muted-foreground">Loading channel catalog...</p>
            </div>
          ) : loadError ? (
            <div className="flex flex-col items-center gap-4 py-16">
              <AlertCircle className="h-8 w-8 text-red-500" />
              <p className="text-muted-foreground">{loadError}</p>
              <Button variant="outline" onClick={() => window.location.reload()}>
                Try Again
              </Button>
            </div>
          ) : view === 'globe' ? (
            /* Globe View */
            <div className="space-y-6">
              <div className="rounded-xl border border-border bg-card overflow-hidden">
                <GlobeLoader
                  points={globePoints}
                  onPointClick={handleGlobePointClick}
                  height={450}
                  autoRotate={!globeCountry}
                />
              </div>

              {/* Selected chips (shared with search view) */}
              {selected.length > 0 && (
                <div className="flex flex-wrap gap-2">
                  {selected.map((ch) => (
                    <Badge
                      key={ch.id}
                      className="bg-cyan-600 text-white pl-3 pr-1 py-1.5 text-sm flex items-center gap-1 cursor-pointer hover:bg-cyan-700"
                      onClick={() => removeChannel(ch.id)}
                    >
                      {ch.name}
                      <X className="h-3.5 w-3.5 ml-1" />
                    </Badge>
                  ))}
                </div>
              )}

              {/* Country channel list */}
              {globeCountry && (
                <div className="border border-border rounded-lg">
                  <div className="px-4 py-3 border-b border-border flex items-center justify-between">
                    <div>
                      <h3 className="font-semibold">{globeCountry}</h3>
                      <p className="text-xs text-muted-foreground">{globeFilteredChannels.length} channels</p>
                    </div>
                    <button onClick={() => setGlobeCountry(null)} className="text-muted-foreground hover:text-foreground">
                      <X className="h-4 w-4" />
                    </button>
                  </div>
                  <div className="max-h-[300px] overflow-y-auto divide-y divide-border">
                    {globeFilteredChannels.map((ch) => {
                      const isSelected = selected.some((s) => s.id === ch.id)
                      return (
                        <button
                          key={ch.id}
                          type="button"
                          onClick={() => toggleChannel(ch)}
                          className={`w-full text-left px-4 py-3 flex items-center justify-between gap-3 hover:bg-muted/50 transition-colors ${
                            isSelected ? 'bg-cyan-50 dark:bg-cyan-950/30' : ''
                          }`}
                        >
                          <div className="min-w-0">
                            <div className="font-medium truncate">{ch.name}</div>
                            <div className="flex flex-wrap gap-1 mt-1">
                              {ch.categories.map((cat) => (
                                <Badge key={cat} variant="secondary" className="text-xs">{cat}</Badge>
                              ))}
                            </div>
                          </div>
                          {isSelected && <CheckCircle className="h-5 w-5 text-cyan-600 flex-shrink-0" />}
                        </button>
                      )
                    })}
                  </div>
                </div>
              )}

              {!globeCountry && (
                <p className="text-center text-sm text-muted-foreground">
                  Click a point on the globe to browse channels by country
                </p>
              )}

              {/* Email + Submit (same as search view) */}
              <form onSubmit={handleSubmit} className="space-y-4">
                <div className="space-y-2">
                  <label htmlFor="globe-email" className="text-sm font-medium">Your Email</label>
                  <input
                    type="email"
                    id="globe-email"
                    required
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    className="w-full px-4 py-3 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-cyan-500"
                    placeholder="your@email.com"
                  />
                </div>
                {status === 'error' && (
                  <div className="flex items-center gap-2 p-4 bg-red-100 dark:bg-red-900/30 rounded-lg text-red-600 dark:text-red-400">
                    <AlertCircle className="h-5 w-5 flex-shrink-0" />
                    <p className="text-sm">{errorMessage}</p>
                  </div>
                )}
                <Button
                  type="submit"
                  disabled={status === 'submitting' || selected.length === 0}
                  className="w-full py-6 text-lg font-bold bg-cyan-600 hover:bg-cyan-700 text-white disabled:opacity-50"
                >
                  {status === 'submitting'
                    ? 'Submitting...'
                    : selected.length === 0
                      ? 'Select channels to request'
                      : `Request ${selected.length} Channel${selected.length > 1 ? 's' : ''}`}
                </Button>
              </form>
            </div>
          ) : (
            <form onSubmit={handleSubmit} className="space-y-6">
              {/* Search input */}
              <div className="relative">
                <Search className="absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
                <input
                  type="text"
                  value={query}
                  onChange={(e) => setQuery(e.target.value)}
                  className="w-full pl-12 pr-4 py-3 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-cyan-500"
                  placeholder="Search by channel name, country, or category..."
                  autoFocus
                />
              </div>

              {/* Selected chips */}
              {selected.length > 0 && (
                <div className="flex flex-wrap gap-2">
                  {selected.map((ch) => (
                    <Badge
                      key={ch.id}
                      className="bg-cyan-600 text-white pl-3 pr-1 py-1.5 text-sm flex items-center gap-1 cursor-pointer hover:bg-cyan-700"
                      onClick={() => removeChannel(ch.id)}
                    >
                      {ch.name}
                      <X className="h-3.5 w-3.5 ml-1" />
                    </Badge>
                  ))}
                </div>
              )}

              {/* Results */}
              {debouncedQuery.length >= 2 && (
                <div className="border border-border rounded-lg divide-y divide-border max-h-[400px] overflow-y-auto">
                  {displayResults.length === 0 ? (
                    <div className="p-6 text-center text-muted-foreground">
                      No channels found for &quot;{debouncedQuery}&quot;
                    </div>
                  ) : (
                    <>
                      {displayResults.map((ch) => {
                        const isSelected = selected.some((s) => s.id === ch.id)
                        return (
                          <button
                            key={ch.id}
                            type="button"
                            onClick={() => toggleChannel(ch)}
                            className={`w-full text-left px-4 py-3 flex items-center justify-between gap-3 hover:bg-muted/50 transition-colors ${
                              isSelected ? 'bg-cyan-50 dark:bg-cyan-950/30' : ''
                            }`}
                          >
                            <div className="min-w-0">
                              <div className="font-medium truncate">{ch.name}</div>
                              <div className="flex flex-wrap gap-1 mt-1">
                                {ch.country && (
                                  <Badge variant="outline" className="text-xs">
                                    {ch.country}
                                  </Badge>
                                )}
                                {ch.categories.map((cat) => (
                                  <Badge key={cat} variant="secondary" className="text-xs">
                                    {cat}
                                  </Badge>
                                ))}
                              </div>
                            </div>
                            {isSelected && (
                              <CheckCircle className="h-5 w-5 text-cyan-600 flex-shrink-0" />
                            )}
                          </button>
                        )
                      })}
                      {totalMatches > 50 && (
                        <div className="p-3 text-center text-sm text-muted-foreground bg-muted/30">
                          {totalMatches - 50} more — refine your search
                        </div>
                      )}
                    </>
                  )}
                </div>
              )}

              {debouncedQuery.length > 0 && debouncedQuery.length < 2 && (
                <p className="text-sm text-muted-foreground text-center">
                  Type at least 2 characters to search
                </p>
              )}

              {/* Email */}
              <div className="space-y-2">
                <label htmlFor="email" className="text-sm font-medium">
                  Your Email
                </label>
                <input
                  type="email"
                  id="email"
                  required
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  className="w-full px-4 py-3 rounded-lg border border-border bg-background focus:outline-none focus:ring-2 focus:ring-cyan-500"
                  placeholder="your@email.com"
                />
                <p className="text-xs text-muted-foreground">
                  We&apos;ll let you know when the channels are added
                </p>
              </div>

              {/* Error */}
              {status === 'error' && (
                <div className="flex items-center gap-2 p-4 bg-red-100 dark:bg-red-900/30 rounded-lg text-red-600 dark:text-red-400">
                  <AlertCircle className="h-5 w-5 flex-shrink-0" />
                  <p className="text-sm">{errorMessage}</p>
                </div>
              )}

              {/* Submit */}
              <Button
                type="submit"
                disabled={status === 'submitting' || selected.length === 0}
                className="w-full py-6 text-lg font-bold bg-cyan-600 hover:bg-cyan-700 text-white disabled:opacity-50"
              >
                {status === 'submitting'
                  ? 'Submitting...'
                  : selected.length === 0
                    ? 'Select channels to request'
                    : `Request ${selected.length} Channel${selected.length > 1 ? 's' : ''}`}
              </Button>
            </form>
          )}

          <div className="mt-8 p-6 bg-muted/50 rounded-lg space-y-4">
            <h3 className="font-bold mb-2">How does this work?</h3>
            <p className="text-sm text-muted-foreground">
              This catalog comes from <a href="https://iptv-org.github.io" className="text-cyan-600 hover:underline font-medium">iptv-org</a>,
              a community-maintained collection of publicly available IPTV streams. Select the channels
              you want and we&apos;ll map them into the Jefflix Live TV lineup.
            </p>
            <p className="text-xs text-muted-foreground border-t border-border pt-3">
              Not all channels have working streams—we&apos;ll do our best and let you know the result.
            </p>
          </div>
        </div>
      </div>
    </div>
  )
}
