'use client';

import { useEffect, useRef, useState } from 'react';
import Link from 'next/link';
import { ArrowLeft, ChevronDown, ChevronUp, Film, Globe, Image as ImageIcon, Pencil, Trash2, Check, X, Upload, Youtube, Play } from 'lucide-react';
import toast from 'react-hot-toast';
import { Post, LocalizedString } from '@/types';
import { api } from '@/lib/api';
import { getYouTubeId, getYouTubeThumbnail } from '@/lib/youtube';
import Button from '@/components/ui/Button';
import Input, { Textarea, Select } from '@/components/ui/Input';
import ImageUploader from '@/components/ui/ImageUploader';
import TagInput from '@/components/ui/TagInput';
import RichTextEditor from '@/components/RichTextEditor';
import LanguageTabs, { useLanguageTabs, Lang } from '@/components/ui/LanguageTabs';

interface PostFormProps {
  initialData?: Post;
  onSave: (data: Partial<Post>) => void;
  isSaving: boolean;
}

const emptyLS = (): LocalizedString => ({ en: '', zh: '' });

function asLS(val: unknown): LocalizedString {
  if (val && typeof val === 'object' && 'en' in val) return val as LocalizedString;
  if (typeof val === 'string') return { en: val, zh: '' };
  return emptyLS();
}

export default function PostForm({ initialData, onSave, isSaving }: PostFormProps) {
  const { activeLang, setActiveLang } = useLanguageTabs();
  const [title, setTitle] = useState<LocalizedString>(asLS(initialData?.title));
  const [content, setContent] = useState<LocalizedString>(asLS(initialData?.content));
  const [excerpt, setExcerpt] = useState<LocalizedString>(asLS(initialData?.excerpt));
  const [category, setCategory] = useState(initialData?.category ?? 'General');
  const [tags, setTags] = useState<string[]>(initialData?.tags ?? []);
  const [status, setStatus] = useState<Post['status']>(initialData?.status ?? 'draft');
  const [featuredImage, setFeaturedImage] = useState(initialData?.featuredImage ?? '');
  const [videoUrl, setVideoUrl] = useState(initialData?.videoUrl ?? '');
  const [videoThumbnail, setVideoThumbnail] = useState(initialData?.videoThumbnail ?? '');
  const [mediaType, setMediaType] = useState<'image' | 'video'>(initialData?.videoUrl ? 'video' : 'image');
  const [videoSource, setVideoSource] = useState<'youtube' | 'upload'>(
    () => (initialData?.videoUrl && !getYouTubeId(initialData.videoUrl)) ? 'upload' : 'youtube'
  );
  const [isUploadingVideo, setIsUploadingVideo] = useState(false);
  const videoInputRef = useRef<HTMLInputElement>(null);
  const [seoTitle, setSeoTitle] = useState(initialData?.seo?.title ?? '');
  const [seoDesc, setSeoDesc] = useState(initialData?.seo?.description ?? '');
  const [seoKeywords, setSeoKeywords] = useState<string[]>(initialData?.seo?.keywords ?? []);
  const [seoOpen, setSeoOpen] = useState(false);
  const [categories, setCategories] = useState<string[]>([]);
  const [customCategory, setCustomCategory] = useState(false);
  const [managingCategories, setManagingCategories] = useState(false);
  const [editingCat, setEditingCat] = useState<string | null>(null);
  const [editingCatValue, setEditingCatValue] = useState('');

  const loadCategories = () => {
    api.getCategories().then((cats) => {
      const list = cats.length ? cats : ['General'];
      if (category && !list.includes(category)) list.push(category);
      setCategories(list);
    }).catch(() => setCategories(['General']));
  };

  useEffect(() => {
    loadCategories();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleRenameCategory = async (oldName: string) => {
    const newName = editingCatValue.trim();
    if (!newName || newName === oldName) { setEditingCat(null); return; }
    try {
      await api.renameCategory(oldName, newName);
      if (category === oldName) setCategory(newName);
      setEditingCat(null);
      loadCategories();
    } catch { alert('Failed to rename category'); }
  };

  const handleDeleteCategory = async (name: string) => {
    if (categories.length <= 1) { alert('Cannot delete the only category'); return; }
    if (!confirm(`Delete "${name}"? All posts in this category will be moved to "General".`)) return;
    try {
      await api.deleteCategory(name, 'General');
      if (category === name) setCategory('General');
      loadCategories();
    } catch { alert('Failed to delete category'); }
  };

  const updateLS = (setter: React.Dispatch<React.SetStateAction<LocalizedString>>, lang: Lang, value: string) => {
    setter((prev) => ({ ...prev, [lang]: value }));
  };

  const API_BASE = (process.env.NEXT_PUBLIC_API_URL || '').replace('/api', '');
  const resolveUrl = (url: string) => {
    if (!url) return '';
    if (url.startsWith('http')) return url;
    return `${API_BASE}${url}`;
  };

  const extractVideoThumbnail = (src: string): Promise<Blob | null> => {
    return new Promise((resolve) => {
      const video = document.createElement('video');
      video.crossOrigin = 'anonymous';
      video.muted = true;
      video.preload = 'metadata';
      video.src = src;

      video.onloadeddata = () => {
        video.currentTime = 1;
      };
      video.onseeked = () => {
        try {
          const canvas = document.createElement('canvas');
          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;
          canvas.getContext('2d')!.drawImage(video, 0, 0);
          canvas.toBlob((blob) => resolve(blob), 'image/jpeg', 0.85);
        } catch {
          resolve(null);
        }
      };
      video.onerror = () => resolve(null);
    });
  };

  const handleVideoUpload = async (file: File) => {
    if (!file.type.startsWith('video/')) {
      toast.error('Please select a video file');
      return;
    }

    setIsUploadingVideo(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      const media = await api.uploadMedia(formData);
      const uploadedUrl = media.url;
      setVideoUrl(uploadedUrl);

      const fullUrl = resolveUrl(uploadedUrl);
      const thumbBlob = await extractVideoThumbnail(fullUrl);
      if (thumbBlob) {
        const thumbForm = new FormData();
        thumbForm.append('file', thumbBlob, 'video-thumbnail.jpg');
        const thumbMedia = await api.uploadMedia(thumbForm);
        setVideoThumbnail(thumbMedia.url);
      }
      toast.success('Video uploaded');
    } catch {
      toast.error('Video upload failed');
    } finally {
      setIsUploadingVideo(false);
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    onSave({
      title,
      content,
      excerpt: excerpt.en || excerpt.zh ? excerpt : undefined,
      category,
      tags,
      status,
      featuredImage: mediaType === 'image' ? (featuredImage || undefined) : undefined,
      videoUrl: mediaType === 'video' ? (videoUrl || undefined) : undefined,
      videoThumbnail: mediaType === 'video'
        ? (videoThumbnail || getYouTubeThumbnail(videoUrl) || undefined)
        : undefined,
      seo: {
        title: seoTitle || undefined,
        description: seoDesc || undefined,
        keywords: seoKeywords.length ? seoKeywords : undefined,
      },
    });
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-5">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link href="/posts" className="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg">
            <ArrowLeft size={18} />
          </Link>
          <h1 className="text-2xl font-bold text-gray-900">
            {initialData ? 'Edit Post' : 'New Post'}
          </h1>
        </div>
        <div className="flex items-center gap-3">
          <Select
            value={status}
            onChange={(e) => setStatus(e.target.value as Post['status'])}
            options={[
              { value: 'draft', label: 'Draft' },
              { value: 'published', label: 'Published' },
              { value: 'archived', label: 'Archived' },
            ]}
            className="w-36"
          />
          <Button type="submit" isLoading={isSaving}>
            {initialData ? 'Save changes' : 'Create post'}
          </Button>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
        <div className="lg:col-span-2 space-y-5">
          <div className="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
            <LanguageTabs activeLang={activeLang} onChange={setActiveLang} />

            <Input
              id="title"
              label={`Title (${activeLang.toUpperCase()})`}
              value={title[activeLang]}
              onChange={(e) => updateLS(setTitle, activeLang, e.target.value)}
              required={activeLang === 'en'}
              placeholder={activeLang === 'en' ? 'Post title' : '新聞標題'}
            />

            {initialData?.slug && (
              <p className="text-xs text-gray-400">Slug: <code className="text-gray-600">{initialData.slug}</code></p>
            )}

            <div className="space-y-1.5">
              <label className="block text-sm font-medium text-gray-700">
                Content ({activeLang.toUpperCase()}) {activeLang === 'en' && <span className="text-red-500">*</span>}
              </label>
              <RichTextEditor
                key={activeLang}
                value={content[activeLang]}
                onChange={(val) => updateLS(setContent, activeLang, val)}
                placeholder={activeLang === 'en' ? 'Write your article content here...' : '在此撰寫新聞內容...'}
              />
            </div>

            <Textarea
              label={`Excerpt (${activeLang.toUpperCase()})`}
              value={excerpt[activeLang]}
              onChange={(e) => updateLS(setExcerpt, activeLang, e.target.value)}
              rows={3}
              placeholder={activeLang === 'en' ? 'Short summary (auto-generated if empty)' : '簡短摘要（留空自動生成）'}
              hint="Maximum 300 characters"
              maxLength={300}
            />
          </div>
        </div>

        <div className="space-y-5">
          <div className="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
            <div className="space-y-1.5">
              <div className="flex items-center justify-between">
                <label className="block text-sm font-medium text-gray-700">Category</label>
                <div className="flex items-center gap-2">
                  <button
                    type="button"
                    className="text-xs text-blue-600 hover:text-blue-700"
                    onClick={() => { setCustomCategory(!customCategory); setManagingCategories(false); }}
                  >
                    {customCategory ? 'Choose existing' : '+ New'}
                  </button>
                  <button
                    type="button"
                    className="text-xs text-gray-400 hover:text-gray-600"
                    onClick={() => { setManagingCategories(!managingCategories); setCustomCategory(false); setEditingCat(null); }}
                  >
                    {managingCategories ? 'Done' : 'Manage'}
                  </button>
                </div>
              </div>
              {customCategory ? (
                <Input
                  value={category}
                  onChange={(e) => setCategory(e.target.value)}
                  placeholder="Type a new category name"
                />
              ) : (
                <Select
                  value={category}
                  onChange={(e) => setCategory(e.target.value)}
                  options={categories.map((c) => ({ value: c, label: c }))}
                />
              )}
            </div>

            {managingCategories && (
              <div className="border border-gray-200 rounded-lg divide-y divide-gray-100">
                {categories.map((cat) => (
                  <div key={cat} className="flex items-center gap-2 px-3 py-2 text-sm">
                    {editingCat === cat ? (
                      <>
                        <input
                          type="text"
                          value={editingCatValue}
                          onChange={(e) => setEditingCatValue(e.target.value)}
                          onKeyDown={(e) => { if (e.key === 'Enter') handleRenameCategory(cat); if (e.key === 'Escape') setEditingCat(null); }}
                          className="flex-1 px-2 py-1 text-sm border border-blue-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-400"
                          autoFocus
                        />
                        <button type="button" onClick={() => handleRenameCategory(cat)} className="p-1 text-green-600 hover:bg-green-50 rounded" title="Save">
                          <Check size={14} />
                        </button>
                        <button type="button" onClick={() => setEditingCat(null)} className="p-1 text-gray-400 hover:bg-gray-100 rounded" title="Cancel">
                          <X size={14} />
                        </button>
                      </>
                    ) : (
                      <>
                        <span className="flex-1 text-gray-700">{cat}</span>
                        <button
                          type="button"
                          onClick={() => { setEditingCat(cat); setEditingCatValue(cat); }}
                          className="p-1 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded"
                          title="Rename"
                        >
                          <Pencil size={13} />
                        </button>
                        <button
                          type="button"
                          onClick={() => handleDeleteCategory(cat)}
                          className="p-1 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded"
                          title="Delete"
                        >
                          <Trash2 size={13} />
                        </button>
                      </>
                    )}
                  </div>
                ))}
              </div>
            )}

            <TagInput label="Tags" value={tags} onChange={setTags} />
          </div>

          <div className="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
            <div className="flex items-center gap-1 p-1 bg-gray-100 rounded-lg">
              <button
                type="button"
                onClick={() => { setMediaType('image'); setVideoUrl(''); }}
                className={`flex-1 flex items-center justify-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-md transition-colors ${
                  mediaType === 'image' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-500 hover:text-gray-700'
                }`}
              >
                <ImageIcon size={13} /> Image
              </button>
              <button
                type="button"
                onClick={() => { setMediaType('video'); setFeaturedImage(''); }}
                className={`flex-1 flex items-center justify-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-md transition-colors ${
                  mediaType === 'video' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-500 hover:text-gray-700'
                }`}
              >
                <Film size={13} /> Video
              </button>
            </div>

            {mediaType === 'image' ? (
              <ImageUploader
                label="Featured Image"
                value={featuredImage}
                onChange={setFeaturedImage}
              />
            ) : (
              <>
                <div className="flex items-center gap-1 p-0.5 bg-gray-50 rounded-md border border-gray-200">
                  <button
                    type="button"
                    onClick={() => { setVideoSource('youtube'); setVideoUrl(''); setVideoThumbnail(''); }}
                    className={`flex-1 flex items-center justify-center gap-1 px-2 py-1 text-[11px] font-semibold rounded transition-colors ${
                      videoSource === 'youtube' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-400 hover:text-gray-600'
                    }`}
                  >
                    <Youtube size={12} /> YouTube URL
                  </button>
                  <button
                    type="button"
                    onClick={() => { setVideoSource('upload'); setVideoUrl(''); setVideoThumbnail(''); }}
                    className={`flex-1 flex items-center justify-center gap-1 px-2 py-1 text-[11px] font-semibold rounded transition-colors ${
                      videoSource === 'upload' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-400 hover:text-gray-600'
                    }`}
                  >
                    <Upload size={12} /> Upload MP4
                  </button>
                </div>

                {videoSource === 'youtube' ? (
                  <>
                    <Input
                      label="YouTube Video URL"
                      value={videoUrl}
                      onChange={(e) => setVideoUrl(e.target.value)}
                      placeholder="https://www.youtube.com/watch?v=..."
                      hint="Paste a YouTube URL — the thumbnail is stored automatically"
                    />
                    {(() => {
                      const id = getYouTubeId(videoUrl);
                      if (!id) return null;
                      const thumb = getYouTubeThumbnail(videoUrl);
                      return (
                        <>
                          <div className="relative w-full rounded-lg overflow-hidden bg-black" style={{ aspectRatio: '16/9' }}>
                            <iframe
                              src={`https://www.youtube.com/embed/${id}`}
                              className="absolute inset-0 w-full h-full"
                              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                              allowFullScreen
                            />
                          </div>
                          {thumb && (
                            <div className="space-y-2">
                              <p className="text-xs font-medium text-gray-500">Cover thumbnail (auto-derived)</p>
                              {/* eslint-disable-next-line @next/next/no-img-element */}
                              <img src={thumb} alt="YouTube thumbnail" className="w-full rounded-lg object-cover" />
                            </div>
                          )}
                        </>
                      );
                    })()}
                  </>
                ) : (
                  <>
                    {videoUrl ? (
                      <div className="space-y-3">
                        <div className="relative w-full rounded-lg overflow-hidden bg-black" style={{ aspectRatio: '16/9' }}>
                          <video
                            src={resolveUrl(videoUrl)}
                            className="absolute inset-0 w-full h-full object-contain"
                            controls
                            preload="metadata"
                          />
                        </div>
                        {videoThumbnail && (
                          <div className="space-y-2">
                            <p className="text-xs font-medium text-gray-500">Cover thumbnail (auto-generated from first frame)</p>
                            {/* eslint-disable-next-line @next/next/no-img-element */}
                            <img src={resolveUrl(videoThumbnail)} alt="Video thumbnail" className="w-full rounded-lg object-cover" />
                          </div>
                        )}
                        <button
                          type="button"
                          onClick={() => { setVideoUrl(''); setVideoThumbnail(''); }}
                          className="text-xs text-red-500 hover:text-red-700"
                        >
                          Remove video
                        </button>
                      </div>
                    ) : (
                      <div
                        onClick={() => videoInputRef.current?.click()}
                        className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
                          isUploadingVideo
                            ? 'border-blue-300 bg-blue-50'
                            : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
                        }`}
                      >
                        {isUploadingVideo ? (
                          <div className="flex flex-col items-center gap-2">
                            <div className="w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
                            <p className="text-xs text-gray-500">Uploading & generating thumbnail...</p>
                          </div>
                        ) : (
                          <>
                            <Upload size={20} className="mx-auto text-gray-400 mb-1.5" />
                            <p className="text-xs text-gray-500">
                              Drop a video or <span className="text-blue-600">click to upload</span>
                            </p>
                            <p className="text-[10px] text-gray-400 mt-1">MP4 or WebM, up to 100 MB</p>
                          </>
                        )}
                      </div>
                    )}
                    <input
                      ref={videoInputRef}
                      type="file"
                      className="hidden"
                      accept="video/mp4,video/webm"
                      onChange={(e) => {
                        const file = e.target.files?.[0];
                        if (file) handleVideoUpload(file);
                        e.target.value = '';
                      }}
                    />
                  </>
                )}
              </>
            )}
          </div>

          <div className="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
            <div>
              <h3 className="text-sm font-semibold text-gray-900">Social Media & Search</h3>
              <p className="text-xs text-gray-400 mt-0.5">
                Controls how this post appears when shared on Facebook, WhatsApp, X, etc. and in Google search results.
              </p>
            </div>

            <div className="border border-gray-200 rounded-lg overflow-hidden">
              {(() => {
                const previewImg = featuredImage || videoThumbnail || getYouTubeThumbnail(videoUrl);
                if (previewImg) return (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={previewImg.startsWith('http') ? previewImg : `${process.env.NEXT_PUBLIC_API_URL?.replace('/api', '') || ''}${previewImg}`}
                    alt="Preview"
                    className="w-full h-32 object-cover"
                  />
                );
                return (
                  <div className="w-full h-32 bg-gray-50 flex items-center justify-center">
                    <ImageIcon size={24} className="text-gray-300" />
                  </div>
                );
              })()}
              <div className="p-3 space-y-1 bg-gray-50">
                <div className="flex items-center gap-1 text-[10px] text-gray-400 uppercase tracking-wide">
                  <Globe size={10} />
                  golflifestyle.com.hk
                </div>
                <p className="text-sm font-semibold text-gray-900 line-clamp-2 leading-snug">
                  {seoTitle || title.en || 'Post title'}
                </p>
                <p className="text-xs text-gray-500 line-clamp-2 leading-relaxed">
                  {seoDesc || excerpt.en || 'Post description will appear here...'}
                </p>
              </div>
            </div>

            <Input
              label="Sharing Title"
              value={seoTitle}
              onChange={(e) => setSeoTitle(e.target.value)}
              placeholder="Leave empty to use the post title"
              hint="Custom title shown on Facebook, WhatsApp, Google, etc."
            />
            <Textarea
              label="Sharing Description"
              value={seoDesc}
              onChange={(e) => setSeoDesc(e.target.value)}
              rows={3}
              placeholder="Leave empty to use the excerpt"
              hint="Short summary shown below the title when shared."
            />

            <div>
              <button
                type="button"
                className="text-xs text-gray-400 hover:text-gray-600 transition-colors"
                onClick={() => setSeoOpen(!seoOpen)}
              >
                {seoOpen ? '▾ Hide keywords' : '▸ Advanced: Search keywords'}
              </button>
              {seoOpen && (
                <div className="mt-2">
                  <TagInput label="Keywords" value={seoKeywords} onChange={setSeoKeywords} />
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </form>
  );
}
