import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { admin } from '../api/endpoints'
import { useToast } from '../context/ToastContext'
import { mediaUrl } from '../api/client'
import { compact } from '../lib/format'
import { Card, Button, Input, Textarea, Select, Toggle, Modal } from './ui'
import { Edit, Trash, Plus, Lock } from '../components/icons'

const blank = {
  title: '',
  description: '',
  thumbnail_url: '',
  source_type: 'file',
  source_url: '',
  category_id: '',
  tags: '',
  duration: 0,
  status: 'published',
  is_exclusive: false,
  is_live: false,
  is_locked: false,
  required_ad_visits: 3,
  ad_links: '',
  return_seconds: 20,
  unlock_expiry_hours: 24,
  ad_break_enabled: true,
  ad_break_interval: '',
  fake_views: 0,
  fake_likes: 0,
  fake_comments: 0,
  fake_shares: 0,
}

export default function AdminVideos() {
  const toast = useToast()
  const [data, setData] = useState(null)
  const [categories, setCategories] = useState([])
  const [q, setQ] = useState('')
  const [editing, setEditing] = useState(null)

  const load = (query = '') => admin.videos({ q: query }).then(setData).catch(() => {})
  useEffect(() => {
    load()
    admin.categories().then(setCategories).catch(() => {})
  }, [])

  const openNew = () => setEditing({ ...blank })
  const openEdit = (v) =>
    setEditing({
      ...blank,
      ...v,
      thumbnail_url: v.thumbnail || '',
      source_url: v.source_url || '',
      category_id: v.category_id || '',
      tags: (v.tags || []).join(', '),
      ad_links: (v.ad_links || []).join('\n'),
      ad_break_interval: v.ad_break_interval || '',
    })

  const remove = async (v) => {
    if (!confirm(`Delete "${v.title}"?`)) return
    await admin.deleteVideo(v.id).then(() => load(q)).catch(() => toast.error('Could not delete'))
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h1 className="text-xl font-extrabold">Videos</h1>
        <Button onClick={openNew}>
          <span className="inline-flex items-center gap-1">
            <Plus width={15} height={15} /> Add video
          </span>
        </Button>
      </div>

      <form
        onSubmit={(e) => {
          e.preventDefault()
          load(q)
        }}
        className="flex gap-2"
      >
        <Input placeholder="Search videos…" value={q} onChange={(e) => setQ(e.target.value)} />
        <Button type="submit">Search</Button>
      </form>

      <Card>
        <div className="space-y-2">
          {data?.data?.map((v) => (
            <div key={v.id} className="flex items-center gap-3 rounded-xl p-2 hover:bg-gray-50 dark:hover:bg-gray-800/50">
              <img src={mediaUrl(v.thumbnail)} alt="" className="h-12 w-20 shrink-0 rounded-lg object-cover" />
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-2">
                  <Link to={`/watch/${v.slug}`} className="truncate font-medium hover:text-[var(--brand)]">
                    {v.title}
                  </Link>
                  {v.is_locked && <Lock width={13} height={13} className="shrink-0 text-amber-500" />}
                </div>
                <div className="flex gap-3 text-xs text-gray-500">
                  <span>{v.category?.name || 'Uncategorized'}</span>
                  <span>{compact(v.display_stats?.views)} views</span>
                  <span className={v.status === 'published' ? 'text-emerald-500' : 'text-gray-400'}>{v.status}</span>
                </div>
              </div>
              <button onClick={() => openEdit(v)} className="rounded-lg p-2 text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800">
                <Edit width={16} height={16} />
              </button>
              <button onClick={() => remove(v)} className="rounded-lg p-2 text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-900/20">
                <Trash width={16} height={16} />
              </button>
            </div>
          ))}
          {data && data.data.length === 0 && <p className="py-6 text-center text-gray-400">No videos.</p>}
        </div>
      </Card>

      {editing && (
        <VideoForm
          value={editing}
          categories={categories}
          onClose={() => setEditing(null)}
          onSaved={() => {
            setEditing(null)
            load(q)
          }}
        />
      )}
    </div>
  )
}

/** Serialize a payload object + files into multipart FormData for Laravel. */
function toFormData(payload, files) {
  const fd = new FormData()
  Object.entries(payload).forEach(([k, v]) => {
    if (v === null || v === undefined) return
    if (Array.isArray(v)) {
      v.forEach((item) => fd.append(`${k}[]`, item))
    } else if (typeof v === 'boolean') {
      fd.append(k, v ? '1' : '0')
    } else {
      fd.append(k, v)
    }
  })
  if (files.thumbnail_file) fd.append('thumbnail_file', files.thumbnail_file)
  if (files.video_file) fd.append('video_file', files.video_file)
  return fd
}

function VideoForm({ value, categories, onClose, onSaved }) {
  const toast = useToast()
  const [f, setF] = useState(value)
  const [busy, setBusy] = useState(false)
  const [files, setFiles] = useState({ thumbnail_file: null, video_file: null })
  const [progress, setProgress] = useState(0)
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }))
  const setFile = (k, file) => setFiles((p) => ({ ...p, [k]: file }))

  const save = async () => {
    setBusy(true)
    const payload = {
      title: f.title,
      description: f.description,
      thumbnail_url: f.thumbnail_url,
      source_type: f.source_type,
      source_url: f.source_url,
      category_id: f.category_id || null,
      tags: f.tags ? f.tags.split(',').map((t) => t.trim()).filter(Boolean) : [],
      duration: Number(f.duration) || 0,
      status: f.status,
      is_exclusive: !!f.is_exclusive,
      is_live: !!f.is_live,
      is_locked: !!f.is_locked,
      required_ad_visits: Number(f.required_ad_visits) || 1,
      ad_links: f.ad_links ? f.ad_links.split('\n').map((l) => l.trim()).filter(Boolean) : [],
      return_seconds: Number(f.return_seconds) || 20,
      unlock_expiry_hours: Number(f.unlock_expiry_hours) || 0,
      ad_break_enabled: !!f.ad_break_enabled,
      ad_break_interval: f.ad_break_interval ? Number(f.ad_break_interval) : null,
      fake_views: Number(f.fake_views) || 0,
      fake_likes: Number(f.fake_likes) || 0,
      fake_comments: Number(f.fake_comments) || 0,
      fake_shares: Number(f.fake_shares) || 0,
    }

    const hasFiles = files.thumbnail_file || files.video_file
    const body = hasFiles ? toFormData(payload, files) : payload
    const config = hasFiles
      ? {
          onUploadProgress: (e) =>
            e.total && setProgress(Math.round((e.loaded / e.total) * 100)),
        }
      : undefined

    try {
      if (f.id) await admin.updateVideo(f.id, body, config)
      else await admin.createVideo(body, config)
      toast.success('Video saved')
      onSaved()
    } catch (err) {
      const e = err.response?.data?.errors
      toast.error(e ? Object.values(e)[0][0] : 'Could not save video')
    } finally {
      setBusy(false)
      setProgress(0)
    }
  }

  return (
    <Modal open onClose={onClose} title={f.id ? 'Edit video' : 'Add video'} wide>
      <div className="space-y-4">
        <Input label="Title" value={f.title} onChange={(e) => set('title', e.target.value)} />
        <Textarea label="Description" rows={3} value={f.description || ''} onChange={(e) => set('description', e.target.value)} />

        <div className="grid gap-4 sm:grid-cols-2">
          <Select label="Source type" value={f.source_type} onChange={(e) => set('source_type', e.target.value)}>
            <option value="file">File (MP4 URL)</option>
            <option value="embed">Embed (iframe URL)</option>
          </Select>
          <Input label="Source URL" value={f.source_url} onChange={(e) => set('source_url', e.target.value)} placeholder="https://…/video.mp4" />
          <Input label="Thumbnail URL" value={f.thumbnail_url} onChange={(e) => set('thumbnail_url', e.target.value)} />
          <Input label="Duration (seconds)" type="number" value={f.duration} onChange={(e) => set('duration', e.target.value)} />
          <Select label="Category" value={f.category_id} onChange={(e) => set('category_id', e.target.value)}>
            <option value="">— None —</option>
            {categories.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </Select>
          <Select label="Status" value={f.status} onChange={(e) => set('status', e.target.value)}>
            <option value="published">Published</option>
            <option value="draft">Draft</option>
          </Select>
        </div>
        {/* Direct file uploads — override the URLs above */}
        <div className="rounded-xl border border-dashed border-gray-300 p-4 dark:border-gray-700">
          <p className="mb-3 text-sm font-semibold">
            Or upload files{' '}
            <span className="font-normal text-gray-400">— overrides the URLs above</span>
          </p>
          <div className="grid gap-4 sm:grid-cols-2">
            <div>
              <span className="mb-1 block text-sm font-medium text-gray-600 dark:text-gray-300">
                Thumbnail image
              </span>
              <input
                type="file"
                accept="image/*"
                onChange={(e) => setFile('thumbnail_file', e.target.files?.[0] || null)}
                className="block w-full text-sm text-gray-500 file:mr-3 file:rounded-lg file:border-0 file:bg-[var(--brand)] file:px-3 file:py-1.5 file:text-sm file:font-semibold file:text-white hover:file:opacity-90"
              />
              {files.thumbnail_file && (
                <p className="mt-1 truncate text-xs text-emerald-600">✓ {files.thumbnail_file.name}</p>
              )}
            </div>
            <div>
              <span className="mb-1 block text-sm font-medium text-gray-600 dark:text-gray-300">
                Video file (mp4 / webm / ogg)
              </span>
              <input
                type="file"
                accept="video/mp4,video/webm,video/ogg"
                onChange={(e) => {
                  const file = e.target.files?.[0] || null
                  setFile('video_file', file)
                  if (file) set('source_type', 'file')
                }}
                className="block w-full text-sm text-gray-500 file:mr-3 file:rounded-lg file:border-0 file:bg-[var(--brand)] file:px-3 file:py-1.5 file:text-sm file:font-semibold file:text-white hover:file:opacity-90"
              />
              {files.video_file && (
                <p className="mt-1 truncate text-xs text-emerald-600">
                  ✓ {files.video_file.name} ({(files.video_file.size / 1048576).toFixed(1)} MB)
                </p>
              )}
            </div>
          </div>
          {busy && progress > 0 && (
            <div className="mt-3">
              <div className="mb-1 flex justify-between text-xs text-gray-500">
                <span>Uploading…</span>
                <span>{progress}%</span>
              </div>
              <div className="h-2 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-800">
                <div
                  className="h-full rounded-full bg-[var(--brand)] transition-all"
                  style={{ width: `${progress}%` }}
                />
              </div>
            </div>
          )}
          <p className="mt-2 text-xs text-gray-400">
            Large videos may exceed the server upload limit — raise{' '}
            <code>upload_max_filesize</code> / <code>post_max_size</code> in php.ini, or paste a
            hosted URL above.
          </p>
        </div>

        <Input label="Tags (comma-separated)" value={f.tags} onChange={(e) => set('tags', e.target.value)} placeholder="action, 4k, demo" />

        <div className="grid gap-3 sm:grid-cols-2">
          <Toggle label="Exclusive" checked={f.is_exclusive} onChange={(v) => set('is_exclusive', v)} />
          <Toggle label="Live" checked={f.is_live} onChange={(v) => set('is_live', v)} />
        </div>

        {/* Lock configuration */}
        <div className="rounded-xl border border-amber-200 bg-amber-50/50 p-4 dark:border-amber-900/40 dark:bg-amber-900/10">
          <Toggle label="🔒 Lock this video (ad-unlock)" checked={f.is_locked} onChange={(v) => set('is_locked', v)} />
          {f.is_locked && (
            <div className="mt-3 space-y-3">
              <div className="grid gap-3 sm:grid-cols-3">
                <Input label="Required visits" type="number" value={f.required_ad_visits} onChange={(e) => set('required_ad_visits', e.target.value)} />
                <Input label="Return seconds" type="number" value={f.return_seconds} onChange={(e) => set('return_seconds', e.target.value)} />
                <Input label="Unlock expiry (hours)" type="number" value={f.unlock_expiry_hours} onChange={(e) => set('unlock_expiry_hours', e.target.value)} />
              </div>
              <Textarea label="Ad link(s) — one per line" rows={3} value={f.ad_links} onChange={(e) => set('ad_links', e.target.value)} placeholder="https://sponsor.example/ad1" className="font-mono text-xs" />
            </div>
          )}
        </div>

        {/* Ad break */}
        <div className="grid gap-3 sm:grid-cols-2">
          <Toggle label="In-player ad breaks" checked={f.ad_break_enabled} onChange={(v) => set('ad_break_enabled', v)} />
          <Input label="Ad break interval (sec, blank=global)" type="number" value={f.ad_break_interval} onChange={(e) => set('ad_break_interval', e.target.value)} />
        </div>

        {/* Fake stats */}
        <div>
          <p className="mb-2 text-sm font-semibold text-gray-600 dark:text-gray-300">
            Fake base stats <span className="font-normal text-gray-400">(added to real counts)</span>
          </p>
          <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
            <Input label="Views" type="number" value={f.fake_views} onChange={(e) => set('fake_views', e.target.value)} />
            <Input label="Likes" type="number" value={f.fake_likes} onChange={(e) => set('fake_likes', e.target.value)} />
            <Input label="Comments" type="number" value={f.fake_comments} onChange={(e) => set('fake_comments', e.target.value)} />
            <Input label="Shares" type="number" value={f.fake_shares} onChange={(e) => set('fake_shares', e.target.value)} />
          </div>
        </div>

        <div className="flex justify-end gap-2 border-t border-gray-100 pt-4 dark:border-gray-800">
          <Button variant="ghost" onClick={onClose}>
            Cancel
          </Button>
          <Button onClick={save} disabled={busy}>
            {busy ? 'Saving…' : 'Save video'}
          </Button>
        </div>
      </div>
    </Modal>
  )
}
