'use client';

import { useState, useRef, useCallback } from 'react';
import dynamic from 'next/dynamic';
import { toast } from 'sonner';
import {
  RiAddLine,
  RiEditLine,
  RiDeleteBinLine,
  RiSaveLine,
  RiImageAddLine,
  RiVideoLine,
  RiCloseLine,
  RiFileAddLine,
  RiEyeLine,
} from '@remixicon/react';
import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Spinner } from '@/components/ui/spinners';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  useBlogContentsBilingual,
  useCreateBlogContent,
  useUpdateBlogContent,
  useDeleteBlogContent,
} from '../hooks';
import type { BlogContent } from '../types';

const RichTextEditor = dynamic(() => import('./RichTextEditor'), { ssr: false });

function sanitizeHtml(html: string): string {
  if (!html) return '';
  return html
    .replace(/<script[\s\S]*?<\/script>/gi, '')
    .replace(/on\w+\s*=\s*["'][^"']*["']/gi, '')
    .replace(/on\w+\s*=\s*[^\s>]+/gi, '')
    .replace(/javascript\s*:/gi, '')
    .replace(/data\s*:/gi, 'data-blocked:');
}

function contentToHtml(content: unknown[]): string {
  if (!Array.isArray(content) || content.length === 0) return '';
  const firstBlock = content[0] as Record<string, unknown>;
  const desc = (firstBlock?.description as string) ?? '';
  const subtitle = (firstBlock?.subtitle as string) ?? '';
  const values = (firstBlock?.values as Array<Record<string, string>>) ?? [];
  const valueTexts = values.map(v => v.title || v.url || '').filter(Boolean);

  let html = '';
  if (desc) html += `<p>${desc}</p>`;
  if (subtitle) html += `<p><strong>${subtitle}</strong></p>`;
  if (valueTexts.length > 0) {
    html += '<ul>' + valueTexts.map(v => `<li>${v}</li>`).join('') + '</ul>';
  }
  return html;
}

interface Props {
  blogId: number;
}

interface MediaFile {
  file: File;
  preview: string;
  type: 'image' | 'video';
}

export default function BlogContentManager({ blogId }: Props) {
  const { data: bilingualData, isLoading } = useBlogContentsBilingual(blogId);
  const contents = bilingualData?.en;
  const contentsAr = bilingualData?.ar;
  const createMutation = useCreateBlogContent();
  const updateMutation = useUpdateBlogContent();
  const deleteMutation = useDeleteBlogContent();

  const [isFormOpen, setIsFormOpen] = useState(false);
  const [editingContent, setEditingContent] = useState<BlogContent | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<BlogContent | null>(null);
  const [previewContent, setPreviewContent] = useState<string | null>(null);

  const [form, setForm] = useState({
    title_en: '',
    title_ar: '',
    body_en: '',
    body_ar: '',
    content_type: 'list',
    video_url: '',
    url: '',
  });

  const [mediaFiles, setMediaFiles] = useState<MediaFile[]>([]);
  const [existingAttachment, setExistingAttachment] = useState<string | null>(null);
  const editorImagesRef = useRef<File[]>([]);
  const mediaInputRef = useRef<HTMLInputElement>(null);

  const handleEditorImageUpload = useCallback(async (file: File): Promise<string> => {
    const isValidType = ['image/jpeg', 'image/jpg', 'image/png'].includes(file.type);
    if (!isValidType) {
      toast.error('Only JPG and PNG images are supported');
      return '';
    }
    editorImagesRef.current.push(file);
    const preview = URL.createObjectURL(file);
    setMediaFiles(prev => [...prev, { file, preview, type: 'image' }]);
    return preview;
  }, []);

  const openCreate = () => {
    setEditingContent(null);
    setForm({
      title_en: '',
      title_ar: '',
      body_en: '',
      body_ar: '',
      content_type: 'list',
      video_url: '',
      url: '',
    });
    setMediaFiles([]);
    editorImagesRef.current = [];
    setExistingAttachment(null);
    setIsFormOpen(true);
  };

  const openEdit = (content: BlogContent) => {
    setEditingContent(content);
    const c = content as unknown as Record<string, unknown>;

    const arContent = contentsAr?.find((ac) => ac.id === content.id);
    const arC = arContent as unknown as Record<string, unknown> | undefined;

    const enBody = contentToHtml(c.content as unknown[]);
    const arBody = arC ? contentToHtml(arC.content as unknown[]) : '';

    setForm({
      title_en: String(c.title ?? ''),
      title_ar: arC ? String(arC.title ?? '') : '',
      body_en: enBody,
      body_ar: arBody,
      content_type: String(c.content_type ?? 'list'),
      video_url: String(c.video_url ?? ''),
      url: String(c.url ?? ''),
    });
    setMediaFiles([]);
    editorImagesRef.current = [];
    setExistingAttachment((c.attachment as string) ?? null);
    setIsFormOpen(true);
  };

  const handleMediaAdd = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files) return;

    const newMedia: MediaFile[] = [];
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const isVideo = file.type.startsWith('video/');
      newMedia.push({
        file,
        preview: URL.createObjectURL(file),
        type: isVideo ? 'video' : 'image',
      });
    }
    setMediaFiles(prev => [...prev, ...newMedia]);
    e.target.value = '';
  }, []);

  const removeMedia = (index: number) => {
    setMediaFiles(prev => {
      const removed = prev[index];
      URL.revokeObjectURL(removed.preview);
      return prev.filter((_, i) => i !== index);
    });
  };

  const handleSubmit = () => {
    if (!form.title_en.trim()) {
      toast.error('English title is required');
      return;
    }

    const fd = new FormData();
    fd.append('title_en', form.title_en);
    fd.append('title_ar', form.title_ar || form.title_en);
    fd.append('content_type', form.content_type);

    if (form.video_url.trim()) {
      fd.append('video_url', form.video_url.trim());
    }
    if (form.url.trim()) {
      fd.append('url', form.url.trim());
    }

    const stripEmbeddedMedia = (html: string) => {
      return html
        .replace(/<img[^>]+src="data:[^"]*"[^>]*>/gi, '')
        .replace(/<img[^>]+src="blob:[^"]*"[^>]*>/gi, '')
        .replace(/<video[^>]+src="data:[^"]*"[^>]*>[\s\S]*?<\/video>/gi, '')
        .replace(/<div[^>]*>[\s]*<\/div>/gi, '')
        .trim();
    };

    const cleanBody_en = stripEmbeddedMedia(form.body_en);
    const cleanBody_ar = stripEmbeddedMedia(form.body_ar);

    const safeDesc_en = cleanBody_en.substring(0, 2000);
    const safeDesc_ar = (cleanBody_ar || cleanBody_en).substring(0, 2000);

    const plainBody_en = cleanBody_en.replace(/<[^>]*>/g, '').trim();
    const plainBody_ar = cleanBody_ar.replace(/<[^>]*>/g, '').trim();
    const safeValue_en = (plainBody_en || form.title_en).substring(0, 255);
    const safeValue_ar = (plainBody_ar || plainBody_en || form.title_en).substring(0, 255);

    fd.append('content_en[0][title]', form.title_en);
    fd.append('content_en[0][description]', safeDesc_en);
    fd.append('content_en[0][values][0][title]', safeValue_en);
    if (form.content_type === 'links' && form.url.trim()) {
      fd.append('content_en[0][values][0][url]', form.url.trim());
    }

    fd.append('content_ar[0][title]', form.title_ar || form.title_en);
    fd.append('content_ar[0][description]', safeDesc_ar);
    fd.append('content_ar[0][values][0][title]', safeValue_ar);
    if (form.content_type === 'links' && form.url.trim()) {
      fd.append('content_ar[0][values][0][url]', form.url.trim());
    }

    const imageFiles = mediaFiles.filter(m => m.type === 'image').map(m => m.file);

    if (imageFiles.length > 0) {
      fd.append('attachment', imageFiles[0]);
    }

    if (editingContent) {
      updateMutation.mutate(
        { contentId: editingContent.id, data: fd },
        {
          onSuccess: () => {
            toast.success('Content section updated');
            setIsFormOpen(false);
          },
          onError: (error: unknown) => {
            const resp = (error as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } })?.response?.data;
            if (resp?.errors) {
              const msgs = Object.values(resp.errors).flat();
              toast.error(msgs[0] || 'Validation error');
            } else {
              toast.error(resp?.message ?? 'Failed to update content');
            }
          },
        },
      );
    } else {
      createMutation.mutate(
        { blogId, data: fd },
        {
          onSuccess: () => {
            toast.success('Content section added');
            setIsFormOpen(false);
          },
          onError: (error: unknown) => {
            const resp = (error as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } })?.response?.data;
            if (resp?.errors) {
              const msgs = Object.values(resp.errors).flat();
              toast.error(msgs[0] || 'Validation error');
            } else {
              toast.error(resp?.message ?? 'Failed to add content');
            }
          },
        },
      );
    }
  };

  const handleDelete = () => {
    if (!deleteTarget) return;
    deleteMutation.mutate(deleteTarget.id, {
      onSuccess: () => {
        toast.success('Content section deleted');
        setDeleteTarget(null);
      },
      onError: () => toast.error('Failed to delete content'),
    });
  };

  const isPending = createMutation.isPending || updateMutation.isPending;

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12 text-muted-foreground gap-2">
        <Spinner className="size-4 animate-spin" /> Loading content sections...
      </div>
    );
  }

  return (
    <>
      <div className="space-y-4">
        <div className="flex items-center justify-between">
          <h3 className="font-semibold">Content Sections ({contents?.length ?? 0})</h3>
          <Button size="sm" onClick={openCreate}>
            <RiAddLine className="size-4 mr-1" />
            Add Section
          </Button>
        </div>

        {(!contents || contents.length === 0) ? (
          <div className="text-center py-8 text-muted-foreground border rounded-lg border-dashed">
            <RiFileAddLine className="size-8 mx-auto mb-2 text-muted-foreground/50" />
            <p className="font-medium">No content sections yet</p>
            <p className="text-sm mt-1">Add content sections with rich text, images, and videos.</p>
          </div>
        ) : (
          <div className="space-y-3">
            {contents.map((content) => {
              const c = content as unknown as Record<string, unknown>;
              const rawContent = c.content as Array<Record<string, unknown>> | undefined;
              const firstBlock = rawContent?.[0];
              const description = (firstBlock?.description as string) ?? '';
              const preview = description
                ? sanitizeHtml(description)
                : contentToHtml(rawContent ?? []);
              const videoUrl = c.video_url as string | null;
              const attachment = c.attachment as string | null;

              const getYouTubeEmbedUrl = (url: string) => {
                const match = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]+)/);
                return match ? `https://www.youtube.com/embed/${match[1]}` : null;
              };

              const escAttr = (s: string) => s.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
              const isHttpsUrl = (s: string) => /^https:\/\//i.test(s);

              const buildPreviewHtml = () => {
                let html = sanitizeHtml(preview);
                if (attachment && isHttpsUrl(attachment)) {
                  html += `<div style="margin-top:0.5em"><img src="${escAttr(attachment)}" style="max-width:100%;height:auto;border-radius:0.5rem" /></div>`;
                }
                if (videoUrl) {
                  const embedUrl = getYouTubeEmbedUrl(videoUrl);
                  if (embedUrl) {
                    html += `<div style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%;margin-top:0.5em"><iframe src="${escAttr(embedUrl)}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;border-radius:0.5rem"></iframe></div>`;
                  } else if (isHttpsUrl(videoUrl)) {
                    html += `<div style="margin-top:0.5em"><a href="${escAttr(videoUrl)}" target="_blank" rel="noopener noreferrer">${escAttr(videoUrl)}</a></div>`;
                  }
                }
                return html;
              };

              return (
                <Card key={content.id} className="group">
                  <CardContent className="py-4">
                    <div className="flex items-start justify-between gap-4">
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 mb-1 flex-wrap">
                          <Badge variant={
                            c.content_type === 'table' ? 'info' :
                            c.content_type === 'links' ? 'warning' : 'secondary'
                          }>
                            {String(c.content_type ?? 'list')}
                          </Badge>
                          {videoUrl && <Badge variant="mono">Video</Badge>}
                          <h4 className="font-medium text-sm truncate">{String(c.title ?? '')}</h4>
                        </div>
                        {preview && (
                          <div
                            className="text-sm text-muted-foreground line-clamp-2 prose prose-sm max-w-none"
                            dangerouslySetInnerHTML={{ __html: sanitizeHtml(preview) }}
                          />
                        )}
                        {videoUrl && (
                          <p className="text-xs text-blue-500 mt-1 truncate">{videoUrl}</p>
                        )}
                      </div>

                      {attachment && (
                        <img
                          src={attachment}
                          alt=""
                          className="size-16 rounded object-cover shrink-0 border"
                        />
                      )}

                      <div className="flex gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
                        <Button variant="ghost" size="sm" className="size-8 p-0" title="Preview" onClick={() => setPreviewContent(buildPreviewHtml())}>
                          <RiEyeLine className="size-4" />
                        </Button>
                        <Button variant="ghost" size="sm" className="size-8 p-0" title="Edit" onClick={() => openEdit(content)}>
                          <RiEditLine className="size-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          className="size-8 p-0 text-destructive hover:text-destructive"
                          title="Delete"
                          onClick={() => setDeleteTarget(content)}
                        >
                          <RiDeleteBinLine className="size-4" />
                        </Button>
                      </div>
                    </div>
                  </CardContent>
                </Card>
              );
            })}
          </div>
        )}
      </div>

      <Dialog open={isFormOpen} onOpenChange={setIsFormOpen}>
        <DialogContent className="sm:max-w-4xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editingContent ? 'Edit Content Section' : 'Add Content Section'}</DialogTitle>
            <p className="text-sm text-muted-foreground mt-1">
              Use the rich editor to format text, add images, embed videos, and style your content.
            </p>
          </DialogHeader>

          <div className="space-y-6 py-2">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div className="space-y-1.5">
                <Label>Title (English) *</Label>
                <Input
                  value={form.title_en}
                  onChange={(e) => setForm((p) => ({ ...p, title_en: e.target.value }))}
                  placeholder="Section title in English"
                />
              </div>
              <div className="space-y-1.5">
                <Label>Title (Arabic)</Label>
                <Input
                  dir="rtl"
                  value={form.title_ar}
                  onChange={(e) => setForm((p) => ({ ...p, title_ar: e.target.value }))}
                  placeholder="عنوان القسم بالعربية"
                />
              </div>
            </div>

            <div className="space-y-2">
              <Label>Content (English)</Label>
              <RichTextEditor
                content={form.body_en}
                onChange={(html) => setForm((p) => ({ ...p, body_en: html }))}
                placeholder="Write your content here... Use the toolbar to format text and add images."
                minHeight="250px"
                onImageUpload={handleEditorImageUpload}
                hideVideoUpload
              />
            </div>

            <div className="space-y-2">
              <Label>Content (Arabic)</Label>
              <RichTextEditor
                content={form.body_ar}
                onChange={(html) => setForm((p) => ({ ...p, body_ar: html }))}
                placeholder="اكتب المحتوى هنا..."
                dir="rtl"
                minHeight="200px"
                onImageUpload={handleEditorImageUpload}
                hideVideoUpload
              />
            </div>

            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div className="space-y-1.5">
                <Label>Content Type *</Label>
                <Select
                  value={form.content_type}
                  onValueChange={(v) => setForm((p) => ({ ...p, content_type: v }))}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="list">List</SelectItem>
                    <SelectItem value="table">Table</SelectItem>
                    <SelectItem value="links">Links</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label>Video URL</Label>
                <Input
                  value={form.video_url}
                  onChange={(e) => setForm((p) => ({ ...p, video_url: e.target.value }))}
                  placeholder="https://youtube.com/watch?v=..."
                />
              </div>
            </div>

            {form.content_type === 'links' && (
              <div className="space-y-1.5">
                <Label>External Link URL</Label>
                <Input
                  value={form.url}
                  onChange={(e) => setForm((p) => ({ ...p, url: e.target.value }))}
                  placeholder="https://example.com"
                />
              </div>
            )}

            {form.video_url && (() => {
              const match = form.video_url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]+)/);
              const embedUrl = match ? `https://www.youtube.com/embed/${match[1]}` : null;
              return embedUrl ? (
                <div className="space-y-1.5">
                  <Label>Video Preview</Label>
                  <div className="relative w-full" style={{ paddingBottom: '56.25%' }}>
                    <iframe
                      src={embedUrl}
                      className="absolute inset-0 w-full h-full rounded-lg border"
                      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                      allowFullScreen
                    />
                  </div>
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">Video link: <a href={form.video_url} target="_blank" rel="noopener" className="text-blue-500 underline">{form.video_url}</a></p>
              );
            })()}

            <div className="space-y-2">
              <Label>Image Attachment (JPG, PNG only)</Label>
              <div className="flex flex-wrap gap-3">
                {existingAttachment && (
                  <div className="relative group">
                    <img
                      src={existingAttachment}
                      alt="Existing"
                      className="size-24 rounded-lg object-cover border"
                    />
                    <span className="absolute bottom-1 left-1 text-[10px] bg-black/60 text-white px-1.5 py-0.5 rounded">Existing</span>
                  </div>
                )}
                {mediaFiles.map((media, idx) => (
                  <div key={idx} className="relative group">
                    {media.type === 'video' ? (
                      <div className="size-24 rounded-lg border bg-muted flex items-center justify-center">
                        <RiVideoLine className="size-8 text-muted-foreground" />
                      </div>
                    ) : (
                      <img src={media.preview} alt="" className="size-24 rounded-lg object-cover border" />
                    )}
                    <button
                      type="button"
                      onClick={() => removeMedia(idx)}
                      className="absolute -top-1 -right-1 size-5 bg-destructive text-white rounded-full flex items-center justify-center text-xs opacity-0 group-hover:opacity-100 transition-opacity"
                    >
                      <RiCloseLine className="size-3" />
                    </button>
                  </div>
                ))}
                <button
                  type="button"
                  onClick={() => mediaInputRef.current?.click()}
                  className="size-24 rounded-lg border-2 border-dashed flex flex-col items-center justify-center gap-1 text-muted-foreground hover:border-primary/50 transition-colors"
                >
                  <RiImageAddLine className="size-5" />
                  <span className="text-[10px]">Add Media</span>
                </button>
              </div>
              <input
                ref={mediaInputRef}
                type="file"
                accept="image/jpeg,image/jpg,image/png"
                multiple
                className="hidden"
                onChange={handleMediaAdd}
              />
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setIsFormOpen(false)}>Cancel</Button>
            <Button size="sm" onClick={handleSubmit} disabled={isPending}>
              <RiSaveLine className="size-4 mr-1" />
              {isPending ? 'Saving...' : 'Save'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!previewContent} onOpenChange={(open) => !open && setPreviewContent(null)}>
        <DialogContent className="sm:max-w-2xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Content Preview</DialogTitle>
          </DialogHeader>
          <div
            className="tiptap prose prose-sm max-w-none py-4 [&_iframe]:rounded-lg [&_iframe]:border"
            dangerouslySetInnerHTML={{ __html: previewContent ?? '' }}
          />
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Delete Content Section</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground py-2">
            Are you sure you want to delete this content section? This action cannot be undone.
          </p>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button variant="outline" size="sm" onClick={() => setDeleteTarget(null)}>Cancel</Button>
            <Button variant="destructive" size="sm" onClick={handleDelete} disabled={deleteMutation.isPending}>
              {deleteMutation.isPending ? 'Deleting...' : 'Delete'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
