import { useCallback, useEffect, useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import {
  fetchVideo,
  fetchRelated,
  recordView,
  toggleLike,
  shareVideo,
} from '../api/endpoints'
import { useAuth } from '../context/AuthContext'
import { useToast } from '../context/ToastContext'
import { compact, timeAgo } from '../lib/format'
import Player from '../components/Player'
import LockScreen from '../components/LockScreen'
import CommentSection from '../components/CommentSection'
import VideoCard from '../components/VideoCard'
import AdSlot from '../components/AdSlot'
import SubscribeButton from '../components/SubscribeButton'
import { Heart, Share, Eye, Comment } from '../components/icons'

export default function Watch() {
  const { slug } = useParams()
  const { isAuthenticated } = useAuth()
  const toast = useToast()
  const [video, setVideo] = useState(null)
  const [related, setRelated] = useState([])
  const [loading, setLoading] = useState(true)
  const [notFound, setNotFound] = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    setNotFound(false)
    try {
      const v = await fetchVideo(slug)
      setVideo(v)
      // SEO / Open Graph tags.
      applyMeta(v)
      fetchRelated(slug).then(setRelated).catch(() => {})
    } catch {
      setNotFound(true)
    } finally {
      setLoading(false)
    }
  }, [slug])

  useEffect(() => {
    window.scrollTo(0, 0)
    load()
  }, [load])

  if (loading) return <WatchSkeleton />
  if (notFound || !video)
    return (
      <div className="py-20 text-center text-gray-500">
        <p className="text-lg font-semibold">Video not found.</p>
        <Link to="/" className="mt-3 inline-block text-[var(--brand)]">
          Back home
        </Link>
      </div>
    )

  // Locked and not yet unlocked → show the ad-unlock lock screen.
  if (video.is_locked && !video.unlocked) {
    return <LockScreen video={video} onUnlocked={load} />
  }

  return (
    <div className="grid gap-6 lg:grid-cols-[1fr_340px]">
      <div className="min-w-0">
        <Player video={video} onFirstPlay={() => recordView(slug).catch(() => {})} />

        <VideoInfo
          video={video}
          isAuthenticated={isAuthenticated}
          onUpdate={setVideo}
          toast={toast}
        />

        {/* Dedicated ad slot under the video info. */}
        <AdSlot
          placement="below_video"
          className="my-5 bg-gray-100 p-2 dark:bg-gray-900"
        />

        <CommentSection slug={slug} />
      </div>

      {/* Related videos */}
      <aside className="min-w-0">
        <h2 className="mb-3 text-base font-bold">Related videos</h2>
        <div className="grid grid-cols-2 gap-3 lg:grid-cols-1">
          {related.map((v) => (
            <VideoCard key={v.id} video={v} />
          ))}
          {related.length === 0 && (
            <p className="text-sm text-gray-400">No related videos.</p>
          )}
        </div>
      </aside>
    </div>
  )
}

function VideoInfo({ video, isAuthenticated, onUpdate, toast }) {
  const [liked, setLiked] = useState(video.liked)
  const [likes, setLikes] = useState(video.stats.likes)
  const [shares, setShares] = useState(video.stats.shares)

  const onLike = async () => {
    if (!isAuthenticated) {
      toast.info('Log in to like videos')
      return
    }
    try {
      const res = await toggleLike(video.slug)
      setLiked(res.liked)
      setLikes(res.likes)
    } catch {
      toast.error('Could not like')
    }
  }

  const onShare = async () => {
    const url = window.location.href
    try {
      shareVideo(video.slug)
        .then((r) => setShares(r.shares))
        .catch(() => {})
      if (navigator.share) {
        await navigator.share({ title: video.title, url })
      } else {
        await navigator.clipboard.writeText(url)
        toast.success('Link copied to clipboard')
      }
    } catch {
      /* user cancelled share */
    }
  }

  return (
    <div className="mt-4">
      <h1 className="text-xl font-extrabold leading-snug sm:text-2xl">{video.title}</h1>

      <div className="mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-gray-500 dark:text-gray-400">
        <span className="inline-flex items-center gap-1">
          <Eye width={15} height={15} /> {compact(video.stats.views)} views
        </span>
        <span className="inline-flex items-center gap-1">
          <Comment width={15} height={15} /> {compact(video.stats.comments)}
        </span>
        <span>{timeAgo(video.created_at)}</span>
      </div>

      <div className="mt-4 flex flex-wrap items-center justify-between gap-3 border-y border-gray-100 py-3.5 dark:border-gray-800">
        {/* Uploader */}
        <div className="flex items-center gap-3">
          <img
            src={video.uploader?.avatar || 'https://i.pravatar.cc/60'}
            alt=""
            className="h-10 w-10 rounded-full object-cover ring-2 ring-[var(--brand)]/20"
          />
          <div className="mr-1">
            <p className="font-bold leading-tight">{video.uploader?.name}</p>
            <p className="text-xs text-gray-500">Official channel</p>
          </div>
          <SubscribeButton />
        </div>

        {/* Actions */}
        <div className="flex items-center gap-2">
          <button
            onClick={onLike}
            className={`inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-bold transition-all duration-200 ${
              liked
                ? 'bg-rose-500 text-white shadow-md shadow-rose-500/30'
                : 'bg-gray-100 text-gray-700 ring-1 ring-gray-200 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:ring-gray-700'
            }`}
          >
            <Heart width={17} height={17} /> {compact(likes)}
          </button>
          <button
            onClick={onShare}
            className="inline-flex items-center gap-2 rounded-full bg-gray-100 px-4 py-2 text-sm font-bold text-gray-700 ring-1 ring-gray-200 transition-all duration-200 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:ring-gray-700"
          >
            <Share width={17} height={17} /> {compact(shares)}
          </button>
        </div>
      </div>

      {/* Description + tags */}
      {video.description && (
        <div className="mt-4 rounded-2xl bg-gray-50 p-4 text-sm leading-relaxed text-gray-700 ring-1 ring-gray-100 dark:bg-gray-900 dark:text-gray-200 dark:ring-gray-800">
          <p className="whitespace-pre-wrap">{video.description}</p>
          {video.tags?.length > 0 && (
            <div className="mt-3 flex flex-wrap gap-1.5">
              {video.tags.map((t) => (
                <Link
                  key={t}
                  to={`/search?q=${encodeURIComponent(t)}`}
                  className="rounded-full bg-[var(--brand)]/10 px-2.5 py-0.5 text-xs font-medium text-[var(--brand)]"
                >
                  #{t}
                </Link>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  )
}

function WatchSkeleton() {
  return (
    <div className="grid gap-6 lg:grid-cols-[1fr_340px]">
      <div>
        <div className="aspect-video shimmer relative overflow-hidden rounded-2xl bg-gray-200 dark:bg-gray-800" />
        <div className="mt-4 h-6 w-2/3 rounded bg-gray-200 dark:bg-gray-800" />
        <div className="mt-3 h-10 w-full rounded bg-gray-200 dark:bg-gray-800" />
      </div>
      <div className="space-y-3">
        {Array.from({ length: 4 }).map((_, i) => (
          <div key={i} className="aspect-video shimmer relative overflow-hidden rounded-xl bg-gray-200 dark:bg-gray-800" />
        ))}
      </div>
    </div>
  )
}

/** Set document title + Open Graph meta for sharing/SEO. */
function applyMeta(v) {
  document.title = `${v.title} · StreamHub`
  const set = (prop, content, attr = 'property') => {
    let el = document.head.querySelector(`meta[${attr}="${prop}"]`)
    if (!el) {
      el = document.createElement('meta')
      el.setAttribute(attr, prop)
      document.head.appendChild(el)
    }
    el.setAttribute('content', content)
  }
  set('og:title', v.title)
  set('og:type', 'video.other')
  set('og:description', (v.description || '').slice(0, 160))
  if (v.thumbnail) set('og:image', v.thumbnail)
  set('og:url', window.location.href)
  set('description', (v.description || '').slice(0, 160), 'name')
}
