     1→'use client';
     2→
     3→import { useState, useCallback, useRef, useEffect } from 'react';
     4→import { motion, AnimatePresence } from 'framer-motion';
     5→import {
     6→  Upload, Image as ImageIcon, Sparkles, Download, ArrowRight,
     7→  Palette, Camera, Layers, SlidersHorizontal, Loader2, Check,
     8→  Trash2, RotateCcw, Eye, Wand2, Sun, Paintbrush, Film,
     9→  Pencil, History, ChevronLeft, X, GripVertical
    10→} from 'lucide-react';
    11→import { Button } from '@/components/ui/button';
    12→import { Textarea } from '@/components/ui/textarea';
    13→import { Progress } from '@/components/ui/progress';
    14→import { Card, CardContent } from '@/components/ui/card';
    15→import {
    16→  Dialog,
    17→  DialogContent,
    18→  DialogHeader,
    19→  DialogTitle,
    20→  DialogTrigger,
    21→} from '@/components/ui/dialog';
    22→import { useAppStore, type PhotoProject } from '@/store/photo-store';
    23→
    24→/* ─── Edit Tool Definitions ─── */
    25→const EDIT_TOOLS = [
    26→  { id: 'oil-painting', label: 'لوحة زيتية', icon: Paintbrush, prompt: 'Transform this image into an oil painting style, with visible brushstrokes and rich, vibrant colors, maintain the composition and subject', color: 'from-amber-500/20 to-orange-600/20' },
    27→  { id: 'cartoon', label: 'رسم كرتوني', icon: Pencil, prompt: 'Transform this image into a cartoon illustration style, with bold outlines, flat colors, and simplified shapes, keep the main subject recognizable', color: 'from-pink-500/20 to-rose-600/20' },
    28→  { id: 'bw', label: 'أبيض وأسود', icon: Camera, prompt: 'Convert this image to a stunning black and white photograph with high contrast and dramatic lighting, professional photography style', color: 'from-gray-500/20 to-gray-700/20' },
    29→  { id: 'golden-hour', label: 'إضاءة ذهبية', icon: Sun, prompt: 'Apply warm golden hour lighting to this image, with beautiful warm tones, soft shadows, and a magical sunset glow, maintain all subjects', color: 'from-yellow-500/20 to-amber-600/20' },
    30→  { id: 'enhance', label: 'تحسين الجودة', icon: Sparkles, prompt: 'Enhance the quality and sharpness of this image, improve colors, add more detail and clarity, make it look professional and high-resolution', color: 'from-emerald-500/20 to-teal-600/20' },
    31→  { id: 'bg-remove', label: 'خلفية احترافية', icon: Layers, prompt: 'Replace the background with a clean, modern, professional studio-like background, keep the main subject exactly the same with proper lighting', color: 'from-cyan-500/20 to-blue-600/20' },
    32→  { id: 'cinematic', label: 'تأثير سينمائي', icon: Film, prompt: 'Apply a cinematic color grading to this image, with deep shadows, teal and orange tones, letterbox style, dramatic and moody atmosphere', color: 'from-violet-500/20 to-purple-600/20' },
    33→  { id: 'illustration', label: 'أسلوب رسومي', icon: Palette, prompt: 'Transform this image into a digital illustration style, clean lines, artistic rendering, vibrant but harmonious colors, maintain the scene composition', color: 'from-fuchsia-500/20 to-pink-600/20' },
    34→];
    35→
    36→/* ─── Header Component ─── */
    37→function Header() {
    38→  const { currentView, setView } = useAppStore();
    39→  return (
    40→    <header className="glass sticky top-0 z-50">
    41→      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
    42→        <button
    43→          onClick={() => setView('home')}
    44→          className="flex items-center gap-3 group"
    45→        >
    46→          <div className="w-9 h-9 rounded-lg bg-primary/20 flex items-center justify-center">
    47→            <Wand2 className="w-5 h-5 text-primary" />
    48→          </div>
    49→          <span className="text-lg font-bold gradient-text">محرر الصور AI</span>
    50→        </button>
    51→        <nav className="flex items-center gap-1">
    52→          <Button
    53→            variant={currentView === 'home' ? 'default' : 'ghost'}
    54→            size="sm"
    55→            onClick={() => setView('home')}
    56→            className="gap-2"
    57→          >
    58→            <ImageIcon className="w-4 h-4" />
    59→            <span className="hidden sm:inline">الرئيسية</span>
    60→          </Button>
    61→          <Button
    62→            variant={currentView === 'gallery' ? 'default' : 'ghost'}
    63→            size="sm"
    64→            onClick={() => setView('gallery')}
    65→            className="gap-2"
    66→          >
    67→            <History className="w-4 h-4" />
    68→            <span className="hidden sm:inline">المعرض</span>
    69→          </Button>
    70→        </nav>
    71→      </div>
    72→    </header>
    73→  );
    74→}
    75→
    76→/* ─── Footer Component ─── */
    77→function Footer() {
    78→  return (
    79→    <footer className="glass mt-auto">
    80→      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex flex-col sm:flex-row items-center justify-between gap-2 text-sm text-muted-foreground">
    81→        <p>محرر الصور بالذكاء الاصطناعي — قوّة الذكاء الاصطناعي بين يديك</p>
    82→        <p>© {new Date().getFullYear()} جميع الحقوق محفوظة</p>
    83→      </div>
    84→    </footer>
    85→  );
    86→}
    87→
    88→/* ─── Upload Area Component ─── */
    89→function UploadArea() {
    90→  const { setOriginalImage, setOriginalFileName, setView, setAnalysis, setEditedImage, setEditError } = useAppStore();
    91→  const [isDragOver, setIsDragOver] = useState(false);
    92→  const [isUploading, setIsUploading] = useState(false);
    93→  const fileInputRef = useRef<HTMLInputElement>(null);
    94→
    95→  const handleFile = useCallback(async (file: File) => {
    96→    if (!file.type.startsWith('image/')) return;
    97→    setIsUploading(true);
    98→    setEditError(null);
    99→    setEditedImage(null);
   100→    setAnalysis(null);
   101→    try {
   102→      const formData = new FormData();
   103→      formData.append('image', file);
   104→
   105→      const res = await fetch('/api/upload', { method: 'POST', body: formData });
   106→      const data = await res.json();
   107→      if (!res.ok) throw new Error(data.error || 'فشل رفع الصورة');
   108→
   109→      setOriginalImage(data.imageUrl);
   110→      setOriginalFileName(file.name);
   111→      setView('editor');
   112→    } catch (err: unknown) {
   113→      const message = err instanceof Error ? err.message : 'حدث خطأ';
   114→      setEditError(message);
   115→    } finally {
   116→      setIsUploading(false);
   117→    }
   118→  }, [setOriginalImage, setOriginalFileName, setView, setEditedImage, setAnalysis, setEditError]);
   119→
   120→  const onDrop = useCallback((e: React.DragEvent) => {
   121→    e.preventDefault();
   122→    setIsDragOver(false);
   123→    const file = e.dataTransfer.files[0];
   124→    if (file) handleFile(file);
   125→  }, [handleFile]);
   126→
   127→  const onDragOver = useCallback((e: React.DragEvent) => {
   128→    e.preventDefault();
   129→    setIsDragOver(true);
   130→  }, []);
   131→
   132→  const onDragLeave = useCallback(() => setIsDragOver(false), []);
   133→
   134→  return (
   135→    <motion.div
   136→      initial={{ opacity: 0, y: 30 }}
   137→      animate={{ opacity: 1, y: 0 }}
   138→      transition={{ duration: 0.6 }}
   139→      className="w-full max-w-2xl mx-auto"
   140→    >
   141→      <div
   142→        onDrop={onDrop}
   143→        onDragOver={onDragOver}
   144→        onDragLeave={onDragLeave}
   145→        onClick={() => fileInputRef.current?.click()}
   146→        className={`
   147→          relative cursor-pointer rounded-2xl border-2 border-dashed p-12 sm:p-16
   148→          transition-all duration-300 text-center
   149→          ${isDragOver
   150→            ? 'upload-area-active border-primary'
   151→            : 'border-muted-foreground/30 hover:border-primary/50 hover:bg-primary/5'
   152→          }
   153→        `}
   154→      >
   155→        <input
   156→          ref={fileInputRef}
   157→          type="file"
   158→          accept="image/*"
   159→          className="hidden"
   160→          onChange={(e) => {
   161→            const file = e.target.files?.[0];
   162→            if (file) handleFile(file);
   163→            e.target.value = '';
   164→          }}
   165→        />
   166→        {isUploading ? (
   167→          <div className="flex flex-col items-center gap-4">
   168→            <Loader2 className="w-12 h-12 text-primary animate-spin" />
   169→            <p className="text-lg text-muted-foreground">جارٍ رفع الصورة...</p>
   170→          </div>
   171→        ) : (
   172→          <div className="flex flex-col items-center gap-4">
   173→            <div className="w-20 h-20 rounded-full bg-primary/10 flex items-center justify-center">
   174→              <Upload className="w-10 h-10 text-primary" />
   175→            </div>
   176→            <div>
   177→              <p className="text-xl font-semibold mb-2">اسحب الصورة هنا أو انقر للاختيار</p>
   178→              <p className="text-muted-foreground text-sm">يدعم: PNG, JPG, WEBP — حتى 10 ميجا</p>
   179→            </div>
   180→          </div>
   181→        )}
   182→      </div>
   183→    </motion.div>
   184→  );
   185→}
   186→
   187→/* ─── Feature Cards ─── */
   188→function FeatureCards() {
   189→  const features = [
   190→    { icon: Sparkles, title: 'تحرير بالذكاء', desc: 'أدوات تعديل ذكية تفهم صورتك وتحسّنها' },
   191→    { icon: Palette, title: 'أنماط فنية', desc: 'حوّل صورك إلى لوحات زيتية أو رسوم كرتونية' },
   192→    { icon: SlidersHorizontal, title: 'مقارنة فورية', desc: 'قارن بين الأصل والنسخة المحرّرة بسهولة' },
   193→    { icon: Download, title: 'تحميل مباشر', desc: 'حمّل الصور المحرّرة بجودة عالية' },
   194→  ];
   195→  return (
   196→    <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 max-w-5xl mx-auto mt-16">
   197→      {features.map((f, i) => (
   198→        <motion.div
   199→          key={f.title}
   200→          initial={{ opacity: 0, y: 20 }}
   201→          animate={{ opacity: 1, y: 0 }}
   202→          transition={{ duration: 0.5, delay: 0.2 + i * 0.1 }}
   203→        >
   204→          <Card className="glass h-full text-center p-4 sm:p-6">
   205→            <CardContent className="p-0 flex flex-col items-center gap-3">
   206→              <div className="w-12 h-12 rounded-xl bg-primary/15 flex items-center justify-center">
   207→                <f.icon className="w-6 h-6 text-primary" />
   208→              </div>
   209→              <h3 className="font-semibold text-sm sm:text-base">{f.title}</h3>
   210→              <p className="text-xs sm:text-sm text-muted-foreground">{f.desc}</p>
   211→            </CardContent>
   212→          </Card>
   213→        </motion.div>
   214→      ))}
   215→    </div>
   216→  );
   217→}
   218→
   219→/* ─── Home View ─── */
   220→function HomeView() {
   221→  return (
   222→    <main className="flex-1 flex flex-col items-center justify-center px-4 py-12">
   223→      <motion.div
   224→        initial={{ opacity: 0, y: -20 }}
   225→        animate={{ opacity: 1, y: 0 }}
   226→        transition={{ duration: 0.5 }}
   227→        className="text-center mb-10"
   228→      >
   229→        <h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-4">
   230→          <span className="gradient-text">محرر الصور</span> بالذكاء الاصطناعي
   231→        </h1>
   232→        <p className="text-lg sm:text-xl text-muted-foreground max-w-xl mx-auto">
   233→          ارفع صورتك واختر التأثير المطلوب — وشاهد الذكاء الاصطناعي يُبدع
   234→        </p>
   235→      </motion.div>
   236→      <UploadArea />
   237→      <FeatureCards />
   238→    </main>
   239→  );
   240→}
   241→
   242→/* ─── Before/After Comparison Slider ─── */
   243→function ComparisonSlider({ original, edited }: { original: string; edited: string }) {
   244→  const containerRef = useRef<HTMLDivElement>(null);
   245→  const [position, setPosition] = useState(50);
   246→  const [containerWidth, setContainerWidth] = useState(0);
   247→  const isDragging = useRef(false);
   248→
   249→  useEffect(() => {
   250→    const el = containerRef.current;
   251→    if (!el) return;
   252→    const observer = new ResizeObserver((entries) => {
   253→      for (const entry of entries) {
   254→        setContainerWidth(entry.contentRect.width);
   255→      }
   256→    });
   257→    observer.observe(el);
   258→    return () => observer.disconnect();
   259→  }, []);
   260→
   261→  const updatePosition = useCallback((clientX: number) => {
   262→    if (!containerRef.current) return;
   263→    const rect = containerRef.current.getBoundingClientRect();
   264→    // RTL: position is measured from the right edge
   265→    const x = clientX - rect.left;
   266→    const pct = Math.min(100, Math.max(0, (x / rect.width) * 100));
   267→    setPosition(pct);
   268→  }, []);
   269→
   270→  const handlePointerDown = useCallback((e: React.PointerEvent) => {
   271→    isDragging.current = true;
   272→    (e.target as HTMLElement).setPointerCapture(e.pointerId);
   273→    updatePosition(e.clientX);
   274→  }, [updatePosition]);
   275→
   276→  const handlePointerMove = useCallback((e: React.PointerEvent) => {
   277→    if (!isDragging.current) return;
   278→    updatePosition(e.clientX);
   279→  }, [updatePosition]);
   280→
   281→  const handlePointerUp = useCallback(() => {
   282→    isDragging.current = false;
   283→  }, []);
   284→
   285→  return (
   286→    <div
   287→      ref={containerRef}
   288→      className="comparison-container rounded-xl overflow-hidden bg-black/50 relative w-full"
   289→      style={{ aspectRatio: 'auto' }}
   290→      onPointerDown={handlePointerDown}
   291→      onPointerMove={handlePointerMove}
   292→      onPointerUp={handlePointerUp}
   293→    >
   294→      {/* Edited image (full width, behind) */}
   295→      <img
   296→        src={edited}
   297→        alt="After"
   298→        className="w-full h-auto block"
   299→        draggable={false}
   300→      />
   301→
   302→      {/* Original image (clipped from right in RTL) */}
   303→      <div
   304→        className="absolute inset-0 overflow-hidden"
   305→        style={{ width: `${position}%` }}
   306→      >
   307→        <img
   308→          src={original}
   309→          alt="Before"
   310→          className="w-full h-auto block"
   311→          style={{ width: containerWidth > 0 ? `${containerWidth}px` : '100%' }}
   312→          draggable={false}
   313→        />
   314→      </div>
   315→
   316→      {/* Slider line */}
   317→      <div
   318→        className="comparison-slider-line"
   319→        style={{ left: `${position}%` }}
   320→      >
   321→        <div className="comparison-slider-handle">
   322→          <GripVertical className="w-5 h-5 text-gray-700" />
   323→        </div>
   324→      </div>
   325→
   326→      {/* Labels */}
   327→      <div className="absolute top-3 right-3 bg-black/60 text-white text-xs px-2 py-1 rounded-md">الأصلي</div>
   328→      <div className="absolute top-3 left-3 bg-primary/80 text-white text-xs px-2 py-1 rounded-md">المحرّر</div>
   329→    </div>
   330→  );
   331→}
   332→
   333→/* ─── Editor View ─── */
   334→function EditorView() {
   335→  const {
   336→    originalImage, editedImage, isEditing, editProgress, editError,
   337→    analysis, customPrompt, setCustomPrompt, setEditedImage,
   338→    setEditProgress, setIsEditing, setEditError, setAnalysis,
   339→    setView, resetEditor, projects, setProjects, originalFileName,
   340→  } = useAppStore();
   341→  const [selectedTool, setSelectedTool] = useState<string | null>(null);
   342→  const [isAnalyzing, setIsAnalyzing] = useState(false);
   343→  const fileInputRef = useRef<HTMLInputElement>(null);
   344→
   345→  const handleAnalyze = useCallback(async () => {
   346→    if (!originalImage) return;
   347→    setIsAnalyzing(true);
   348→    try {
   349→      const res = await fetch('/api/analyze', {
   350→        method: 'POST',
   351→        headers: { 'Content-Type': 'application/json' },
   352→        body: JSON.stringify({ imageUrl: originalImage }),
   353→      });
   354→      const data = await res.json();
   355→      if (!res.ok) throw new Error(data.error || 'فشل التحليل');
   356→      setAnalysis(data.analysis);
   357→    } catch (err: unknown) {
   358→      const message = err instanceof Error ? err.message : 'حدث خطأ';
   359→      setEditError(message);
   360→    } finally {
   361→      setIsAnalyzing(false);
   362→    }
   363→  }, [originalImage, setAnalysis, setEditError]);
   364→
   365→  const handleEdit = useCallback(async (prompt: string, label: string, toolType: string) => {
   366→    if (!originalImage) return;
   367→    setIsEditing(true);
   368→    setEditError(null);
   369→    setEditedImage(null);
   370→    setEditProgress(0);
   371→
   372→    try {
   373→      const res = await fetch('/api/edit', {
   374→        method: 'POST',
   375→        headers: { 'Content-Type': 'application/json' },
   376→        body: JSON.stringify({
   377→          imageUrl: originalImage,
   378→          prompt,
   379→          label,
   380→          toolType,
   381→        }),
   382→      });
   383→
   384→      if (!res.ok) {
   385→        const data = await res.json();
   386→        throw new Error(data.error || 'فشل التعديل');
   387→      }
   388→
   389→      const reader = res.body?.getReader();
   390→      if (!reader) throw new Error('لا يمكن قراءة الاستجابة');
   391→
   392→      const decoder = new TextDecoder();
   393→      let buffer = '';
   394→
   395→      while (true) {
   396→        const { done, value } = await reader.read();
   397→        if (done) break;
   398→
   399→        buffer += decoder.decode(value, { stream: true });
   400→        const lines = buffer.split('\n');
   401→        buffer = lines.pop() || '';
   402→
   403→        for (const line of lines) {
   404→          if (line.startsWith('data: ')) {
   405→            const data = line.slice(6);
   406→            let parsed: Record<string, unknown>;
   407→            try {
   408→              parsed = JSON.parse(data);
   409→            } catch {
   410→              continue; // Skip malformed JSON lines
   411→            }
   412→
   413→            if (parsed.type === 'progress') {
   414→              setEditProgress(parsed.value as number);
   415→            } else if (parsed.type === 'done') {
   416→              setEditedImage(parsed.editedImageUrl as string);
   417→              setEditProgress(100);
   418→              // Refresh gallery
   419→              try {
   420→                const projectsRes = await fetch('/api/projects');
   421→                if (projectsRes.ok) {
   422→                  const projectsData = await projectsRes.json();
   423→                  setProjects(projectsData);
   424→                }
   425→              } catch { /* ignore gallery refresh failure */ }
   426→            } else if (parsed.type === 'error') {
   427→              throw new Error(parsed.message as string);
   428→            }
   429→          }
   430→        }
   431→      }
   432→    } catch (err: unknown) {
   433→      const message = err instanceof Error ? err.message : 'حدث خطأ أثناء التعديل';
   434→      setEditError(message);
   435→    } finally {
   436→      setIsEditing(false);
   437→      setSelectedTool(null);
   438→    }
   439→  }, [originalImage, setIsEditing, setEditError, setEditedImage, setEditProgress, setProjects]);
   440→
   441→  const handleCustomEdit = useCallback(() => {
   442→    if (!customPrompt.trim()) return;
   443→    handleEdit(customPrompt.trim(), 'تعديل مخصص', 'custom');
   444→  }, [customPrompt, handleEdit]);
   445→
   446→  const handleNewImage = useCallback(() => {
   447→    resetEditor();
   448→    setView('home');
   449→  }, [resetEditor, setView]);
   450→
   451→  const handleReupload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
   452→    const file = e.target.files?.[0];
   453→    if (!file || !file.type.startsWith('image/')) return;
   454→    const formData = new FormData();
   455→    formData.append('image', file);
   456→    try {
   457→      const res = await fetch('/api/upload', { method: 'POST', body: formData });
   458→      const data = await res.json();
   459→      if (!res.ok) throw new Error(data.error);
   460→      useAppStore.getState().setOriginalImage(data.imageUrl);
   461→      useAppStore.getState().setOriginalFileName(file.name);
   462→      useAppStore.getState().setEditedImage(null);
   463→      useAppStore.getState().setAnalysis(null);
   464→    } catch {}
   465→    e.target.value = '';
   466→  }, []);
   467→
   468→  const handleDownload = useCallback(() => {
   469→    if (!editedImage) return;
   470→    const a = document.createElement('a');
   471→    a.href = editedImage;
   472→    a.download = `edited-${originalFileName || 'image.png'}`;
   473→    a.click();
   474→  }, [editedImage, originalFileName]);
   475→
   476→  return (
   477→    <main className="flex-1 px-4 py-6 max-w-7xl mx-auto w-full">
   478→      {/* Top bar */}
   479→      <div className="flex items-center justify-between mb-6">
   480→        <Button variant="ghost" onClick={handleNewImage} className="gap-2">
   481→          <ChevronLeft className="w-4 h-4" />
   482→          صورة جديدة
   483→        </Button>
   484→        {editedImage && (
   485→          <Button onClick={handleDownload} className="gap-2">
   486→            <Download className="w-4 h-4" />
   487→            تحميل الصورة
   488→          </Button>
   489→        )}
   490→      </div>
   491→
   492→      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
   493→        {/* Image Preview (2/3 width on desktop) */}
   494→        <div className="lg:col-span-2">
   495→          <Card className="glass overflow-hidden">
   496→            <CardContent className="p-0 relative">
   497→              {/* Image display */}
   498→              <div className="relative min-h-[300px] sm:min-h-[400px] flex items-center justify-center bg-black/30">
   499→                {isEditing && (
   500→                  <div className="absolute inset-0 z-20 flex flex-col items-center justify-center bg-black/50 backdrop-blur-sm">
   501→                    <Loader2 className="w-12 h-12 text-primary animate-spin mb-4" />
   502→                    <p className="text-lg font-semibold mb-2">جارٍ التعديل بالذكاء الاصطناعي...</p>
   503→                    <Progress value={editProgress} className="w-48 h-2" />
   504→                    <p className="text-sm text-muted-foreground mt-2">{editProgress}%</p>
   505→                  </div>
   506→                )}
   507→
   508→                {editedImage ? (
   509→                  <ComparisonSlider original={originalImage!} edited={editedImage} />
   510→                ) : (
   511→                  <img
   512→                    src={originalImage!}
   513→                    alt="Original"
   514→                    className="max-w-full max-h-[70vh] object-contain mx-auto"
   515→                  />
   516→                )}
   517→              </div>
   518→
   519→              {/* Image info bar */}
   520→              <div className="p-3 border-t border-border/50 flex items-center justify-between text-sm text-muted-foreground">
   521→                <span className="truncate max-w-[60%]">{originalFileName || 'صورة'}</span>
   522→                <Button variant="ghost" size="sm" className="gap-1 text-xs h-8" onClick={() => fileInputRef.current?.click()}>
   523→                  <RotateCcw className="w-3 h-3" />
   524→                  تغيير الصورة
   525→                </Button>
   526→                <input ref={fileInputRef} type="file" accept="image/*" className="hidden" onChange={handleReupload} />
   527→              </div>
   528→            </CardContent>
   529→          </Card>
   530→
   531→          {/* Analysis section */}
   532→          <div className="mt-4">
   533→            <Button
   534→              variant="outline"
   535→              onClick={handleAnalyze}
   536→              disabled={isAnalyzing || !originalImage}
   537→              className="w-full gap-2 mb-3"
   538→            >
   539→              {isAnalyzing ? (
   540→                <Loader2 className="w-4 h-4 animate-spin" />
   541→              ) : (
   542→                <Eye className="w-4 h-4" />
   543→              )}
   544→              تحليل الصورة بالذكاء الاصطناعي
   545→            </Button>
   546→            <AnimatePresence>
   547→              {analysis && (
   548→                <motion.div
   549→                  initial={{ opacity: 0, height: 0 }}
   550→                  animate={{ opacity: 1, height: 'auto' }}
   551→                  exit={{ opacity: 0, height: 0 }}
   552→                >
   553→                  <Card className="glass">
   554→                    <CardContent className="p-4">
   555→                      <h3 className="text-sm font-semibold mb-2 flex items-center gap-2">
   556→                        <Eye className="w-4 h-4 text-primary" />
   557→                        نتيجة التحليل
   558→                      </h3>
   559→                      <p className="text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap">{analysis}</p>
   560→                    </CardContent>
   561→                  </Card>
   562→                </motion.div>
   563→              )}
   564→            </AnimatePresence>
   565→          </div>
   566→        </div>
   567→
   568→        {/* Tools Panel (1/3 width on desktop) */}
   569→        <div className="lg:col-span-1 space-y-4">
   570→          {/* Quick Tools */}
   571→          <Card className="glass">
   572→            <CardContent className="p-4">
   573→              <h3 className="font-semibold mb-3 flex items-center gap-2">
   574→                <Wand2 className="w-4 h-4 text-primary" />
   575→                أدوات التحرير السريعة
   576→              </h3>
   577→              <div className="grid grid-cols-2 gap-2">
   578→                {EDIT_TOOLS.map((tool) => {
   579→                  const Icon = tool.icon;
   580→                  const isLoading = isEditing && selectedTool === tool.id;
   581→                  return (
   582→                    <button
   583→                      key={tool.id}
   584→                      onClick={() => {
   585→                        if (isEditing) return;
   586→                        setSelectedTool(tool.id);
   587→                        handleEdit(tool.prompt, tool.label, 'quick-tool');
   588→                      }}
   589→                      disabled={isEditing}
   590→                      className={`
   591→                        tool-card relative flex flex-col items-center gap-2 p-3 rounded-xl
   592→                        border border-border/50 text-center transition-all
   593→                        ${isLoading ? 'ring-2 ring-primary' : 'hover:border-primary/40'}
   594→                        ${isEditing ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
   595→                      `}
   596→                    >
   597→                      <div className={`w-10 h-10 rounded-lg bg-gradient-to-br ${tool.color} flex items-center justify-center`}>
   598→                        {isLoading ? (
   599→                          <Loader2 className="w-5 h-5 text-primary animate-spin" />
   600→                        ) : (
   601→                          <Icon className="w-5 h-5 text-foreground" />
   602→                        )}
   603→                      </div>
   604→                      <span className="text-xs font-medium">{tool.label}</span>
   605→                    </button>
   606→                  );
   607→                })}
   608→              </div>
   609→            </CardContent>
   610→          </Card>
   611→
   612→          {/* Custom Prompt */}
   613→          <Card className="glass">
   614→            <CardContent className="p-4">
   615→              <h3 className="font-semibold mb-3 flex items-center gap-2">
   616→                <Pencil className="w-4 h-4 text-primary" />
   617→                تعديل مخصص
   618→              </h3>
   619→              <Textarea
   620→                value={customPrompt}
   621→                onChange={(e) => setCustomPrompt(e.target.value)}
   622→                placeholder="صِف التعديل الذي تريده... مثال: غيّر الخلفية إلى شاطئ عند الغروب"
   623→                className="min-h-[100px] resize-none mb-3"
   624→                disabled={isEditing}
   625→              />
   626→              <Button
   627→                onClick={handleCustomEdit}
   628→                disabled={isEditing || !customPrompt.trim()}
   629→                className="w-full gap-2"
   630→              >
   631→                {isEditing ? (
   632→                  <Loader2 className="w-4 h-4 animate-spin" />
   633→                ) : (
   634→                  <Sparkles className="w-4 h-4" />
   635→                )}
   636→                تطبيق التعديل
   637→              </Button>
   638→            </CardContent>
   639→          </Card>
   640→
   641→          {/* Error display */}
   642→          <AnimatePresence>
   643→            {editError && (
   644→              <motion.div
   645→                initial={{ opacity: 0, y: 10 }}
   646→                animate={{ opacity: 1, y: 0 }}
   647→                exit={{ opacity: 0, y: -10 }}
   648→              >
   649→                <Card className="border-destructive/50 bg-destructive/10">
   650→                  <CardContent className="p-4 flex items-start gap-3">
   651→                    <X className="w-5 h-5 text-destructive mt-0.5 shrink-0" />
   652→                    <div>
   653→                      <p className="text-sm font-medium text-destructive">حدث خطأ</p>
   654→                      <p className="text-xs text-muted-foreground mt-1">{editError}</p>
   655→                    </div>
   656→                  </CardContent>
   657→                </Card>
   658→              </motion.div>
   659→            )}
   660→          </AnimatePresence>
   661→        </div>
   662→      </div>
   663→    </main>
   664→  );
   665→}
   666→
   667→/* ─── Gallery View ─── */
   668→function GalleryView() {
   669→  const { projects, setProjects, setView, setOriginalImage, setOriginalFileName, setEditedImage, setAnalysis } = useAppStore();
   670→  const [isLoading, setIsLoading] = useState(true);
   671→
   672→  useEffect(() => {
   673→    const loadProjects = async () => {
   674→      try {
   675→        const res = await fetch('/api/projects');
   676→        if (res.ok) {
   677→          const data = await res.json();
   678→          setProjects(data);
   679→        }
   680→      } catch {}
   681→      setIsLoading(false);
   682→    };
   683→    loadProjects();
   684→  }, [setProjects]);
   685→
   686→  const handleDelete = useCallback(async (id: string) => {
   687→    try {
   688→      const res = await fetch(`/api/projects/${id}`, { method: 'DELETE' });
   689→      if (res.ok) {
   690→        setProjects(projects.filter((p) => p.id !== id));
   691→      }
   692→    } catch {}
   693→  }, [projects, setProjects]);
   694→
   695→  const handleOpen = useCallback((project: PhotoProject) => {
   696→    const lastEdit = project.edits?.[project.edits.length - 1];
   697→    if (lastEdit?.editedPath) {
   698→      setOriginalImage(lastEdit.originalPath);
   699→      setEditedImage(lastEdit.editedPath);
   700→      setOriginalFileName(project.title);
   701→      setAnalysis(null);
   702→      setView('editor');
   703→    } else if (lastEdit) {
   704→      setOriginalImage(lastEdit.originalPath);
   705→      setEditedImage(null);
   706→      setOriginalFileName(project.title);
   707→      setAnalysis(null);
   708→      setView('editor');
   709→    }
   710→  }, [setOriginalImage, setEditedImage, setOriginalFileName, setAnalysis, setView]);
   711→
   712→  if (isLoading) {
   713→    return (
   714→      <main className="flex-1 flex items-center justify-center">
   715→        <Loader2 className="w-8 h-8 text-primary animate-spin" />
   716→      </main>
   717→    );
   718→  }
   719→
   720→  return (
   721→    <main className="flex-1 px-4 py-8 max-w-6xl mx-auto w-full">
   722→      <motion.div
   723→        initial={{ opacity: 0, y: -10 }}
   724→        animate={{ opacity: 1, y: 0 }}
   725→        className="text-center mb-8"
   726→      >
   727→        <h2 className="text-3xl font-bold mb-2">
   728→          <span className="gradient-text">المعرض</span>
   729→        </h2>
   730→        <p className="text-muted-foreground">جميع مشاريع تعديل الصور السابقة</p>
   731→      </motion.div>
   732→
   733→      {projects.length === 0 ? (
   734→        <motion.div
   735→          initial={{ opacity: 0 }}
   736→          animate={{ opacity: 1 }}
   737→          className="text-center py-20"
   738→        >
   739→          <div className="w-20 h-20 rounded-full bg-muted/30 flex items-center justify-center mx-auto mb-4">
   740→            <ImageIcon className="w-10 h-10 text-muted-foreground" />
   741→          </div>
   742→          <p className="text-lg text-muted-foreground mb-4">لا توجد مشاريع بعد</p>
   743→          <Button onClick={() => setView('home')} className="gap-2">
   744→            <Upload className="w-4 h-4" />
   745→            ابدأ بتعديل صورة
   746→          </Button>
   747→        </motion.div>
   748→      ) : (
   749→        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
   750→          {projects.map((project, i) => {
   751→            const lastEdit = project.edits?.[project.edits.length - 1];
   752→            const thumbnail = lastEdit?.editedPath || lastEdit?.originalPath || '';
   753→            return (
   754→              <motion.div
   755→                key={project.id}
   756→                initial={{ opacity: 0, y: 20 }}
   757→                animate={{ opacity: 1, y: 0 }}
   758→                transition={{ delay: i * 0.05 }}
   759→              >
   760→                <Card className="glass overflow-hidden group cursor-pointer hover:border-primary/40 transition-all" onClick={() => handleOpen(project)}>
   761→                  <div className="aspect-video bg-black/30 relative overflow-hidden">
   762→                    {thumbnail ? (
   763→                      <img src={thumbnail} alt={project.title} className="w-full h-full object-cover" />
   764→                    ) : (
   765→                      <div className="w-full h-full flex items-center justify-center">
   766→                        <ImageIcon className="w-8 h-8 text-muted-foreground" />
   767→                      </div>
   768→                    )}
   769→                    <div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-colors flex items-center justify-center">
   770→                      <span className="opacity-0 group-hover:opacity-100 transition-opacity bg-white/20 backdrop-blur-sm px-3 py-1.5 rounded-lg text-sm font-medium">
   771→                        فتح المشروع
   772→                      </span>
   773→                    </div>
   774→                  </div>
   775→                  <CardContent className="p-3 flex items-center justify-between">
   776→                    <div>
   777→                      <p className="font-medium text-sm truncate">{project.title}</p>
   778→                      <p className="text-xs text-muted-foreground">
   779→                        {new Date(project.createdAt).toLocaleDateString('ar-EG')}
   780→                        {project.edits?.length ? ` — ${project.edits.length} تعديل` : ''}
   781→                      </p>
   782→                    </div>
   783→                    <Button
   784→                      variant="ghost"
   785→                      size="icon"
   786→                      className="h-8 w-8 text-muted-foreground hover:text-destructive shrink-0"
   787→                      onClick={(e) => {
   788→                        e.stopPropagation();
   789→                        handleDelete(project.id);
   790→                      }}
   791→                    >
   792→                      <Trash2 className="w-4 h-4" />
   793→                    </Button>
   794→                  </CardContent>
   795→                </Card>
   796→              </motion.div>
   797→            );
   798→          })}
   799→        </div>
   800→      )}
   801→    </main>
   802→  );
   803→}
   804→
   805→/* ─── Main Client Component ─── */
   806→export default function HomeClient() {
   807→  const { currentView, editError, setEditError } = useAppStore();
   808→
   809→  // Dismiss errors on click outside
   810→  useEffect(() => {
   811→    if (editError) {
   812→      const timer = setTimeout(() => setEditError(null), 8000);
   813→      return () => clearTimeout(timer);
   814→    }
   815→  }, [editError, setEditError]);
   816→
   817→  return (
   818→    <div className="min-h-screen flex flex-col">
   819→      <Header />
   820→      <AnimatePresence mode="wait">
   821→        {currentView === 'home' && (
   822→          <motion.div key="home" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1">
   823→            <HomeView />
   824→          </motion.div>
   825→        )}
   826→        {currentView === 'editor' && (
   827→          <motion.div key="editor" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1 flex flex-col">
   828→            <EditorView />
   829→          </motion.div>
   830→        )}
   831→        {currentView === 'gallery' && (
   832→          <motion.div key="gallery" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1">
   833→            <GalleryView />
   834→          </motion.div>
   835→        )}
   836→      </AnimatePresence>
   837→      <Footer />
   838→    </div>
   839→  );
   840→}