'use client';

import { useState, useEffect, useCallback, useMemo } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  ArrowLeft,
  ShieldCheck,
  ShieldAlert,
  ShieldX,
  AlertTriangle,
  Phone,
  Wallet,
  Smartphone,
  Facebook,
  User,
  CreditCard,
  MapPin,
  Calendar,
  Eye,
  TrendingUp,
  Clock,
  ExternalLink,
  ImageIcon,
  X,
  Search,
  FileText,
  AlertCircle,
  Tag,
  Share2,
  Copy,
  MessageSquare,
  Send,
  Bookmark,
  ThumbsUp,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { Skeleton } from '@/components/ui/skeleton';
import { Textarea } from '@/components/ui/textarea';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import {
  Dialog,
  DialogContent,
  DialogTitle,
  DialogDescription,
} from '@/components/ui/dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useAppStore } from '@/store/app-store';
import { toast } from 'sonner';
import type { ScamReportType } from '@/types';

// ─── Helpers ────────────────────────────────────────────────────────────────────

function formatBDT(amount: number): string {
  if (amount >= 10000000) return `৳${(amount / 10000000).toFixed(1)}Cr`;
  if (amount >= 100000) return `৳${(amount / 100000).toFixed(1)}L`;
  if (amount >= 1000) return `৳${(amount / 1000).toFixed(1)}K`;
  return `৳${amount.toLocaleString('en-BD')}`;
}

function timeAgo(dateStr: string): string {
  const now = new Date();
  const date = new Date(dateStr);
  const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
  if (seconds < 60) return 'Just now';
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months}mo ago`;
  return `${Math.floor(months / 12)}y ago`;
}

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('en-BD', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
}

// ─── Comment Type ────────────────────────────────────────────────────────────

interface CommentType {
  id: string;
  content: string;
  createdAt: string;
  user: {
    id: string;
    name: string | null;
    email: string;
  };
}

// ─── Risk Config ────────────────────────────────────────────────────────────────

const riskConfig: Record<string, { label: string; color: string; bg: string; border: string; icon: React.ElementType; ringColor: string }> = {
  low: {
    label: 'Low Risk',
    color: 'text-emerald-600 dark:text-emerald-400',
    bg: 'bg-emerald-500/10',
    border: 'border-emerald-500/30',
    icon: ShieldCheck,
    ringColor: '#10b981',
  },
  medium: {
    label: 'Medium Risk',
    color: 'text-yellow-600 dark:text-yellow-400',
    bg: 'bg-yellow-500/10',
    border: 'border-yellow-500/30',
    icon: ShieldAlert,
    ringColor: '#eab308',
  },
  high: {
    label: 'High Risk',
    color: 'text-orange-600 dark:text-orange-400',
    bg: 'bg-orange-500/10',
    border: 'border-orange-500/30',
    icon: ShieldX,
    ringColor: '#f97316',
  },
  critical: {
    label: 'Critical Risk',
    color: 'text-red-600 dark:text-red-400',
    bg: 'bg-red-500/10',
    border: 'border-red-500/30',
    icon: AlertTriangle,
    ringColor: '#ef4444',
  },
};

// ─── Status Config ──────────────────────────────────────────────────────────────

const statusConfig: Record<string, { label: string; color: string; bg: string; border: string }> = {
  pending: {
    label: 'Pending',
    color: 'text-yellow-600 dark:text-yellow-400',
    bg: 'bg-yellow-500/10',
    border: 'border-yellow-500/30',
  },
  verified: {
    label: 'Verified',
    color: 'text-emerald-600 dark:text-emerald-400',
    bg: 'bg-emerald-500/10',
    border: 'border-emerald-500/30',
  },
  suspicious: {
    label: 'Suspicious',
    color: 'text-orange-600 dark:text-orange-400',
    bg: 'bg-orange-500/10',
    border: 'border-orange-500/30',
  },
  rejected: {
    label: 'Rejected',
    color: 'text-red-600 dark:text-red-400',
    bg: 'bg-red-500/10',
    border: 'border-red-500/30',
  },
};

// ─── Linked Entity Type Config ──────────────────────────────────────────────────

const linkedEntityTypeConfig: Record<string, { label: string; icon: React.ElementType; color: string; bg: string; hoverBg: string }> = {
  phone: { label: 'Phone', icon: Phone, color: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-500/10', hoverBg: 'hover:bg-blue-500/20' },
  bkash: { label: 'bKash', icon: Wallet, color: 'text-pink-600 dark:text-pink-400', bg: 'bg-pink-500/10', hoverBg: 'hover:bg-pink-500/20' },
  nagad: { label: 'Nagad', icon: Smartphone, color: 'text-orange-600 dark:text-orange-400', bg: 'bg-orange-500/10', hoverBg: 'hover:bg-orange-500/20' },
  facebook: { label: 'Facebook', icon: Facebook, color: 'text-blue-700 dark:text-blue-300', bg: 'bg-blue-500/10', hoverBg: 'hover:bg-blue-500/20' },
  seller: { label: 'Seller', icon: User, color: 'text-purple-600 dark:text-purple-400', bg: 'bg-purple-500/10', hoverBg: 'hover:bg-purple-500/20' },
};

// ─── Risk Gauge Component ────────────────────────────────────────────────────

function RiskGauge({ riskScore, riskLevel }: { riskScore: number; riskLevel: string }) {
  const risk = riskConfig[riskLevel] || riskConfig.low;
  const circumference = 2 * Math.PI * 45; // radius = 45
  const offset = circumference - (riskScore / 100) * circumference;

  return (
    <div className="flex flex-col items-center gap-2">
      <div className="relative w-28 h-28">
        <svg className="w-full h-full -rotate-90" viewBox="0 0 100 100">
          {/* Background circle */}
          <circle
            cx="50"
            cy="50"
            r="45"
            fill="none"
            stroke="currentColor"
            className="text-muted/30"
            strokeWidth="8"
          />
          {/* Risk arc */}
          <circle
            cx="50"
            cy="50"
            r="45"
            fill="none"
            stroke={risk.ringColor}
            strokeWidth="8"
            strokeLinecap="round"
            strokeDasharray={circumference}
            strokeDashoffset={offset}
            className="transition-all duration-1000 ease-out"
            style={{ animation: 'risk-gauge-fill 1s ease-out' }}
          />
        </svg>
        <div className="absolute inset-0 flex flex-col items-center justify-center">
          <span className="text-2xl font-bold">{riskScore}</span>
          <span className="text-[10px] text-muted-foreground uppercase tracking-wider">Risk</span>
        </div>
      </div>
      <Badge variant="outline" className={`text-xs ${risk.color} ${risk.bg} ${risk.border}`}>
        {risk.label}
      </Badge>
    </div>
  );
}

// ─── Detail Loading Skeleton ────────────────────────────────────────────────────

function DetailLoadingSkeleton() {
  return (
    <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
      <div className="flex items-center gap-3">
        <Skeleton className="h-10 w-10 rounded-lg" />
        <div className="space-y-2 flex-1">
          <Skeleton className="h-7 w-3/4" />
          <div className="flex gap-2">
            <Skeleton className="h-6 w-20 rounded-full" />
            <Skeleton className="h-6 w-24 rounded-full" />
          </div>
        </div>
      </div>
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
        {Array.from({ length: 4 }).map((_, i) => (
          <Card key={i}>
            <CardContent className="p-4">
              <Skeleton className="h-4 w-16 mb-2" />
              <Skeleton className="h-6 w-24" />
            </CardContent>
          </Card>
        ))}
      </div>
      <Card>
        <CardContent className="p-6 space-y-4">
          <Skeleton className="h-5 w-32" />
          <Skeleton className="h-4 w-full" />
          <Skeleton className="h-4 w-full" />
          <Skeleton className="h-4 w-3/4" />
        </CardContent>
      </Card>
    </div>
  );
}

// ─── Share Button Component ────────────────────────────────────────────────────

function ShareButton({ report }: { report: ScamReportType }) {
  const riskLabel = riskConfig[report.riskLevel]?.label || report.riskLevel;
  const amountStr = report.amountLost > 0 ? formatBDT(report.amountLost) : 'N/A';
  const shareText = `⚠️ Scam Alert: ${report.title} - Risk Level: ${riskLabel} | Amount Lost: ৳${amountStr} | Reported on ScamChecker BD`;

  const handleCopyLink = useCallback(() => {
    const text = `${shareText}\n\nView details: ${window.location.href}`;
    navigator.clipboard.writeText(text).then(() => {
      toast.success('Report details copied to clipboard!');
    }).catch(() => {
      toast.error('Failed to copy');
    });
  }, [shareText]);

  const handleCopyText = useCallback(() => {
    navigator.clipboard.writeText(shareText).then(() => {
      toast.success('Share text copied!');
    }).catch(() => {
      toast.error('Failed to copy');
    });
  }, [shareText]);

  const handleShareFacebook = useCallback(() => {
    const url = `https://www.facebook.com/sharer/sharer.php?quote=${encodeURIComponent(shareText)}`;
    window.open(url, '_blank', 'width=600,height=400');
  }, [shareText]);

  const handleShareWhatsApp = useCallback(() => {
    const url = `https://wa.me/?text=${encodeURIComponent(shareText)}`;
    window.open(url, '_blank');
  }, [shareText]);

  const handleShareTwitter = useCallback(() => {
    const url = `https://twitter.com/intent/tweet?text=${encodeURIComponent(shareText)}`;
    window.open(url, '_blank', 'width=600,height=400');
  }, [shareText]);

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button
          variant="outline"
          size="sm"
          className="gap-1.5 border-emerald-500/30 text-emerald-600 hover:bg-emerald-500/10 dark:text-emerald-400"
        >
          <Share2 className="h-4 w-4" />
          <span className="hidden sm:inline">Share</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className="w-52">
        <DropdownMenuItem onClick={handleCopyLink} className="gap-2 cursor-pointer">
          <Copy className="h-4 w-4" />
          Copy Link & Details
        </DropdownMenuItem>
        <DropdownMenuItem onClick={handleCopyText} className="gap-2 cursor-pointer">
          <FileText className="h-4 w-4" />
          Copy as Text
        </DropdownMenuItem>
        <DropdownMenuItem onClick={handleShareFacebook} className="gap-2 cursor-pointer">
          <Facebook className="h-4 w-4 text-blue-600" />
          Share on Facebook
        </DropdownMenuItem>
        <DropdownMenuItem onClick={handleShareWhatsApp} className="gap-2 cursor-pointer">
          <Smartphone className="h-4 w-4 text-green-500" />
          Share on WhatsApp
        </DropdownMenuItem>
        <DropdownMenuItem onClick={handleShareTwitter} className="gap-2 cursor-pointer">
          <svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
          Share on X/Twitter
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

// ─── Comments Section Component ─────────────────────────────────────────────────

function CommentsSection({ reportId }: { reportId: string }) {
  const user = useAppStore((s) => s.user);
  const navigate = useAppStore((s) => s.navigate);
  const [comments, setComments] = useState<CommentType[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [newComment, setNewComment] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    let cancelled = false;
    fetch(`/api/reports/${reportId}/comments`)
      .then((res) => {
        if (!res.ok) throw new Error('Network error');
        return res.json();
      })
      .then((data) => {
        if (cancelled) return;
        if (data.success) {
          setComments(data.data || []);
        }
        setIsLoading(false);
      })
      .catch(() => {
        if (!cancelled) {
          setIsLoading(false);
          toast.error('Failed to load comments');
        }
      });
    return () => { cancelled = true; };
  }, [reportId]);

  const handleSubmitComment = useCallback(async () => {
    if (!user) {
      toast.error('Please login to comment');
      navigate('login');
      return;
    }
    if (!newComment.trim()) {
      toast.error('Comment cannot be empty');
      return;
    }
    setIsSubmitting(true);
    try {
      const res = await fetch(`/api/reports/${reportId}/comments`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId: user.id, content: newComment.trim() }),
      });
      if (!res.ok) throw new Error('Network error');
      const data = await res.json();
      if (data.success) {
        setComments((prev) => [data.data, ...prev]);
        setNewComment('');
        toast.success('Comment added!');
      } else {
        toast.error(data.error || 'Failed to add comment');
      }
    } catch {
      toast.error('Failed to add comment. Please try again.');
    } finally {
      setIsSubmitting(false);
    }
  }, [user, newComment, reportId, navigate]);

  return (
    <Card className="border-border/50">
      <CardHeader>
        <CardTitle className="text-lg flex items-center gap-2">
          <MessageSquare className="h-5 w-5 text-emerald-500" />
          Comments ({comments.length})
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex gap-3">
          <Avatar className="h-8 w-8 shrink-0">
            <AvatarFallback className="bg-emerald-500/20 text-emerald-500 text-xs">
              {user ? (user.name || user.email)[0].toUpperCase() : '?'}
            </AvatarFallback>
          </Avatar>
          <div className="flex-1 space-y-2">
            <Textarea
              value={newComment}
              onChange={(e) => setNewComment(e.target.value)}
              placeholder={user ? 'Share your thoughts or additional info about this scam...' : 'Login to comment...'}
              className="min-h-[80px] resize-none text-sm"
              disabled={!user || isSubmitting}
            />
            <div className="flex justify-end">
              <Button
                size="sm"
                onClick={handleSubmitComment}
                disabled={!user || !newComment.trim() || isSubmitting}
                className="gap-1.5 bg-emerald-600 hover:bg-emerald-700 dark:bg-emerald-500 dark:hover:bg-emerald-600"
              >
                <Send className="h-3.5 w-3.5" />
                {isSubmitting ? 'Posting...' : 'Post Comment'}
              </Button>
            </div>
          </div>
        </div>

        <Separator />

        {isLoading ? (
          <div className="space-y-3">
            {[1, 2].map((i) => (
              <div key={i} className="flex gap-3">
                <Skeleton className="h-8 w-8 rounded-full shrink-0" />
                <div className="flex-1 space-y-2">
                  <Skeleton className="h-4 w-24" />
                  <Skeleton className="h-4 w-full" />
                </div>
              </div>
            ))}
          </div>
        ) : comments.length === 0 ? (
          <div className="text-center py-6">
            <MessageSquare className="h-8 w-8 text-muted-foreground/40 mx-auto mb-2" />
            <p className="text-sm text-muted-foreground">No comments yet. Be the first to share your thoughts!</p>
          </div>
        ) : (
          <div className="space-y-4 max-h-96 overflow-y-auto pr-1 custom-scrollbar">
            {comments.map((comment) => (
              <div key={comment.id} className="flex gap-3">
                <Avatar className="h-8 w-8 shrink-0">
                  <AvatarFallback className="bg-emerald-500/20 text-emerald-500 text-xs">
                    {(comment.user.name || comment.user.email)[0].toUpperCase()}
                  </AvatarFallback>
                </Avatar>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-1">
                    <span className="text-sm font-medium">
                      {comment.user.name || 'Anonymous'}
                    </span>
                    <span className="text-xs text-muted-foreground">
                      {timeAgo(comment.createdAt)}
                    </span>
                  </div>
                  <p className="text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap">
                    {comment.content}
                  </p>
                </div>
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// ─── Related Reports Component ────────────────────────────────────────────────

function RelatedReports({ report }: { report: ScamReportType }) {
  const navigate = useAppStore((s) => s.navigate);
  const setSelectedReportId = useAppStore((s) => s.setSelectedReportId);

  // Compute search terms outside of effect
  const searchTerms = useMemo(() => {
    const terms: string[] = [];
    if (report.scammerPhone) terms.push(report.scammerPhone);
    if (report.bKashNumber) terms.push(report.bKashNumber);
    if (report.nagadNumber) terms.push(report.nagadNumber);
    return terms;
  }, [report.scammerPhone, report.bKashNumber, report.nagadNumber]);

  const [related, setRelated] = useState<ScamReportType[]>([]);
  const [isLoading, setIsLoading] = useState(() => searchTerms.length > 0);

  useEffect(() => {
    if (searchTerms.length === 0) return;

    let cancelled = false;
    const searchTerm = searchTerms[0]; // Use the first entity for search
    fetch(`/api/search?q=${encodeURIComponent(searchTerm)}`)
      .then((res) => {
        if (!res.ok) throw new Error('Network error');
        return res.json();
      })
      .then((data) => {
        if (cancelled) return;
        if (data.success) {
          // Get related reports from search results, excluding current
          const reports: ScamReportType[] = [];
          if (data.data?.entities) {
            for (const entity of data.data.entities) {
              if (entity.relatedReports) {
                for (const r of entity.relatedReports) {
                  if (r.id !== report.id && !reports.find((existing) => existing.id === r.id)) {
                    reports.push(r);
                  }
                }
              }
            }
          }
          // Also check reports array
          if (data.data?.reports) {
            for (const r of data.data.reports) {
              if (r.id !== report.id && !reports.find((existing) => existing.id === r.id)) {
                reports.push(r);
              }
            }
          }
          setRelated(reports.slice(0, 5));
        }
        setIsLoading(false);
      })
      .catch(() => {
        if (!cancelled) setIsLoading(false);
      });

    return () => { cancelled = true; };
  }, [report]);

  const handleReportClick = useCallback((reportId: string) => {
    setSelectedReportId(reportId);
    navigate('report-detail');
  }, [setSelectedReportId, navigate]);

  if (!isLoading && related.length === 0) return null;

  return (
    <Card className="border-border/50">
      <CardHeader>
        <CardTitle className="text-lg flex items-center gap-2">
          <AlertTriangle className="h-5 w-5 text-amber-500" />
          Related Reports
        </CardTitle>
      </CardHeader>
      <CardContent>
        {isLoading ? (
          <div className="space-y-3">
            {[1, 2].map((i) => (
              <div key={i} className="flex gap-3">
                <Skeleton className="h-4 w-3/4" />
                <Skeleton className="h-4 w-20" />
              </div>
            ))}
          </div>
        ) : (
          <div className="space-y-2 max-h-72 overflow-y-auto custom-scrollbar">
            {related.map((r) => {
              const risk = riskConfig[r.riskLevel] || riskConfig.low;
              return (
                <button
                  key={r.id}
                  onClick={() => handleReportClick(r.id)}
                  className="w-full text-left p-3 rounded-lg border border-border/50 hover:border-emerald-500/20 hover:bg-emerald-500/5 transition-all group"
                >
                  <div className="flex items-center justify-between gap-2">
                    <h4 className="text-sm font-medium line-clamp-1 group-hover:text-emerald-500 transition-colors">
                      {r.title}
                    </h4>
                    <Badge variant="outline" className={`text-[10px] shrink-0 ${risk.color} ${risk.bg} ${risk.border}`}>
                      {risk.label}
                    </Badge>
                  </div>
                  <div className="flex items-center gap-3 mt-1 text-xs text-muted-foreground">
                    {r.amountLost > 0 && <span>{formatBDT(r.amountLost)}</span>}
                    <span>{timeAgo(r.createdAt)}</span>
                    <span>{r.views} views</span>
                  </div>
                </button>
              );
            })}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// ─── Main ReportDetailPage Component ────────────────────────────────────────────

export function ReportDetailPage() {
  const user = useAppStore((s) => s.user);
  const navigate = useAppStore((s) => s.navigate);
  const selectedReportId = useAppStore((s) => s.selectedReportId);
  const setSearchQuery = useAppStore((s) => s.setSearchQuery);

  const [reportData, setReportData] = useState<{
    id: string | null;
    report: ScamReportType | null;
    upvotes: number;
    fetched: boolean;
  }>({ id: null, report: null, upvotes: 0, fetched: false });
  const [hasUpvoted, setHasUpvoted] = useState(() => {
    if (typeof window === 'undefined' || !selectedReportId) return false;
    return !!localStorage.getItem(`upvoted_${selectedReportId}`);
  });
  const [evidencePreviewOpen, setEvidencePreviewOpen] = useState(false);
  const [previewUrl, setPreviewUrl] = useState('');
  const [previewName, setPreviewName] = useState('');
  const [isBookmarked, setIsBookmarked] = useState(false);
  const [bookmarkId, setBookmarkId] = useState<string | null>(null);
  const [isBookmarkLoading, setIsBookmarkLoading] = useState(false);

  const report = reportData.id === selectedReportId ? reportData.report : null;
  const upvotes = reportData.id === selectedReportId ? reportData.upvotes : 0;
  const isLoading = !!selectedReportId && (reportData.id !== selectedReportId || !reportData.fetched);

  // Fetch report
  useEffect(() => {
    if (!selectedReportId) return;
    if (reportData.id === selectedReportId && reportData.fetched) return;

    let cancelled = false;
    fetch(`/api/reports/${selectedReportId}`)
      .then((res) => {
        if (!res.ok) throw new Error('Network error');
        return res.json();
      })
      .then((data) => {
        if (cancelled) return;
        if (data.success) {
          setReportData({ id: selectedReportId, report: data.data, upvotes: data.data.upvotes, fetched: true });
        } else {
          setReportData({ id: selectedReportId, report: null, upvotes: 0, fetched: true });
          toast.error('Report not found');
        }
      })
      .catch(() => {
        if (!cancelled) {
          setReportData({ id: selectedReportId, report: null, upvotes: 0, fetched: true });
          toast.error('Failed to load report. Please try again.');
        }
      });

    return () => { cancelled = true; };
  }, [selectedReportId, reportData.id, reportData.fetched]);

  // Check bookmark status
  useEffect(() => {
    if (!user || !selectedReportId) return;
    let cancelled = false;
    fetch(`/api/bookmarks?userId=${user.id}`)
      .then((res) => {
        if (!res.ok) throw new Error('Network error');
        return res.json();
      })
      .then((data) => {
        if (cancelled) return;
        if (data.success) {
          const bookmarks = data.data || [];
          const existing = bookmarks.find((b: { reportId: string | null; id: string }) => b.reportId === selectedReportId);
          if (existing) {
            setIsBookmarked(true);
            setBookmarkId(existing.id);
          }
        }
      })
      .catch(() => {
        // Silently fail for bookmark check
      });
    return () => { cancelled = true; };
  }, [user, selectedReportId]);

  const handleUpvote = useCallback(async () => {
    if (!selectedReportId || hasUpvoted) return;
    try {
      const res = await fetch(`/api/reports/${selectedReportId}/upvote`, { method: 'POST' });
      if (!res.ok) throw new Error('Network error');
      const data = await res.json();
      if (data.success) {
        setReportData((prev) => ({ ...prev, upvotes: data.data.upvotes }));
        setHasUpvoted(true);
        localStorage.setItem(`upvoted_${selectedReportId}`, 'true');
        toast.success('Upvoted!');
      }
    } catch {
      toast.error('Failed to upvote');
    }
  }, [selectedReportId, hasUpvoted]);

  const handleBookmarkToggle = useCallback(async () => {
    if (!user) {
      toast.error('Please login to bookmark reports');
      navigate('login');
      return;
    }
    if (!selectedReportId) return;

    setIsBookmarkLoading(true);
    try {
      if (isBookmarked && bookmarkId) {
        // Remove bookmark
        const res = await fetch(`/api/bookmarks/${bookmarkId}`, { method: 'DELETE' });
        if (!res.ok) throw new Error('Network error');
        const data = await res.json();
        if (data.success) {
          setIsBookmarked(false);
          setBookmarkId(null);
          toast.success('Bookmark removed');
        } else {
          toast.error('Failed to remove bookmark');
        }
      } else {
        // Add bookmark
        const res = await fetch('/api/bookmarks', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ userId: user.id, reportId: selectedReportId }),
        });
        if (!res.ok) throw new Error('Network error');
        const data = await res.json();
        if (data.success) {
          setIsBookmarked(true);
          setBookmarkId(data.data.id);
          toast.success('Report bookmarked!');
        } else if (data.error?.includes('already')) {
          toast.info('Already bookmarked');
        } else {
          toast.error(data.error || 'Failed to bookmark');
        }
      }
    } catch {
      toast.error('Failed to update bookmark. Please try again.');
    } finally {
      setIsBookmarkLoading(false);
    }
  }, [user, selectedReportId, isBookmarked, bookmarkId, navigate]);

  const handleEntitySearch = useCallback(
    (query: string) => {
      setSearchQuery(query);
      navigate('search');
    },
    [setSearchQuery, navigate]
  );

  const handleEvidencePreview = useCallback((url: string, name: string) => {
    setPreviewUrl(url);
    setPreviewName(name);
    setEvidencePreviewOpen(true);
  }, []);

  // No report ID
  if (!isLoading && !selectedReportId) {
    return (
      <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center">
        <Card className="border-dashed">
          <CardContent className="py-16">
            <div className="inline-flex p-4 rounded-full bg-red-500/10 mb-4">
              <AlertCircle className="h-8 w-8 text-red-500" />
            </div>
            <h2 className="text-xl font-semibold mb-2">Report Not Found</h2>
            <p className="text-muted-foreground mb-6">
              No report was selected. Please go back and select a report to view.
            </p>
            <Button
              onClick={() => navigate('home')}
              className="bg-emerald-600 hover:bg-emerald-700"
            >
              <ArrowLeft className="h-4 w-4" />
              Back to Home
            </Button>
          </CardContent>
        </Card>
      </div>
    );
  }

  if (isLoading) {
    return <DetailLoadingSkeleton />;
  }

  if (!report) {
    return (
      <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center">
        <Card className="border-dashed">
          <CardContent className="py-16">
            <div className="inline-flex p-4 rounded-full bg-red-500/10 mb-4">
              <AlertCircle className="h-8 w-8 text-red-500" />
            </div>
            <h2 className="text-xl font-semibold mb-2">Report Not Found</h2>
            <p className="text-muted-foreground mb-6">
              The report you&apos;re looking for doesn&apos;t exist or has been removed.
            </p>
            <Button
              onClick={() => navigate('home')}
              className="bg-emerald-600 hover:bg-emerald-700"
            >
              <ArrowLeft className="h-4 w-4" />
              Back to Home
            </Button>
          </CardContent>
        </Card>
      </div>
    );
  }

  const risk = riskConfig[report.riskLevel] || riskConfig.low;
  const status = statusConfig[report.status] || statusConfig.pending;
  const RiskIcon = risk.icon;

  // Gather entity details
  const entityDetails: { type: string; value: string; label: string; icon: React.ElementType; color: string; bg: string }[] = [];
  if (report.scammerPhone) {
    entityDetails.push({ type: 'phone', value: report.scammerPhone, label: 'Phone Number', icon: Phone, color: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-500/10' });
  }
  if (report.bKashNumber) {
    entityDetails.push({ type: 'bkash', value: report.bKashNumber, label: 'bKash Number', icon: Wallet, color: 'text-pink-600 dark:text-pink-400', bg: 'bg-pink-500/10' });
  }
  if (report.nagadNumber) {
    entityDetails.push({ type: 'nagad', value: report.nagadNumber, label: 'Nagad Number', icon: Smartphone, color: 'text-orange-600 dark:text-orange-400', bg: 'bg-orange-500/10' });
  }
  if (report.facebookUrl) {
    entityDetails.push({ type: 'facebook', value: report.facebookUrl, label: 'Facebook', icon: Facebook, color: 'text-blue-700 dark:text-blue-300', bg: 'bg-blue-500/10' });
  }
  if (report.sellerName) {
    entityDetails.push({ type: 'seller', value: report.sellerName, label: 'Seller Name', icon: User, color: 'text-purple-600 dark:text-purple-400', bg: 'bg-purple-500/10' });
  }

  return (
    <div className="min-h-screen bg-background pb-20">
      {/* Header */}
      <div className="border-b bg-gradient-to-b from-emerald-950/10 via-transparent to-transparent dark:from-emerald-950/30 dark:via-transparent dark:to-transparent">
        <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 pt-4 pb-4">
          <Button
            variant="ghost"
            onClick={() => navigate('search')}
            className="gap-2 text-muted-foreground hover:text-emerald-500 hover:bg-emerald-500/10 -ml-2"
          >
            <ArrowLeft className="h-4 w-4" />
            Back to Search
          </Button>
        </div>
      </div>

      <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6">
        {/* Report Header + Risk Gauge */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4 }}
        >
          <div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
            <div className="flex-1 min-w-0">
              <div className="flex flex-wrap items-center gap-2 mb-2">
                <Badge variant="outline" className={`text-xs ${status.color} ${status.bg} ${status.border}`}>
                  {status.label}
                </Badge>
                <Badge variant="outline" className={`text-xs ${risk.color} ${risk.bg} ${risk.border}`}>
                  <RiskIcon className="h-3 w-3" />
                  {risk.label}
                </Badge>
                {report.category && (
                  <Badge variant="secondary" className="text-xs">
                    {report.category.name}
                  </Badge>
                )}
              </div>
              <h1 className="text-2xl sm:text-3xl font-bold leading-tight">{report.title}</h1>
              <div className="flex items-center gap-1.5 text-sm text-muted-foreground mt-2">
                <Eye className="h-4 w-4" />
                {report.views} views
                {report.reportCount > 1 && (
                  <span className="ml-2 flex items-center gap-1 text-amber-600 dark:text-amber-400">
                    <AlertTriangle className="h-3.5 w-3.5" />
                    {report.reportCount} reports
                  </span>
                )}
              </div>
            </div>

            {/* Risk Gauge */}
            <div className="shrink-0">
              <RiskGauge riskScore={report.riskScore} riskLevel={report.riskLevel} />
            </div>
          </div>
        </motion.div>

        {/* Key Info Cards */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.1 }}
        >
          <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
            <Card className="border-border/50">
              <CardContent className="p-4">
                <div className="flex items-center gap-2 text-muted-foreground mb-1">
                  <CreditCard className="h-4 w-4" />
                  <span className="text-xs font-medium">Amount Lost</span>
                </div>
                <p className="text-lg sm:text-xl font-bold text-red-500 dark:text-red-400">
                  {report.amountLost > 0 ? formatBDT(report.amountLost) : '৳0'}
                </p>
              </CardContent>
            </Card>

            <Card className="border-border/50">
              <CardContent className="p-4">
                <div className="flex items-center gap-2 text-muted-foreground mb-1">
                  <MapPin className="h-4 w-4" />
                  <span className="text-xs font-medium">District</span>
                </div>
                <p className="text-lg sm:text-xl font-bold">
                  {report.district || 'N/A'}
                </p>
              </CardContent>
            </Card>

            <Card className="border-border/50">
              <CardContent className="p-4">
                <div className="flex items-center gap-2 text-muted-foreground mb-1">
                  <FileText className="h-4 w-4" />
                  <span className="text-xs font-medium">Category</span>
                </div>
                <p className="text-lg sm:text-xl font-bold">
                  {report.category?.name || report.scamType || 'N/A'}
                </p>
              </CardContent>
            </Card>

            <Card className="border-border/50">
              <CardContent className="p-4">
                <div className="flex items-center gap-2 text-muted-foreground mb-1">
                  <Calendar className="h-4 w-4" />
                  <span className="text-xs font-medium">Report Date</span>
                </div>
                <p className="text-lg sm:text-xl font-bold">
                  {timeAgo(report.createdAt)}
                </p>
              </CardContent>
            </Card>
          </div>
        </motion.div>

        {/* Scammer Details */}
        {entityDetails.length > 0 && (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.4, delay: 0.15 }}
          >
            <Card className="border-border/50 border-2">
              <CardHeader className="pb-0">
                <CardTitle className="text-lg flex items-center gap-2">
                  <AlertTriangle className="h-5 w-5 text-orange-500" />
                  Scammer Details
                </CardTitle>
              </CardHeader>
              <CardContent className="pt-2">
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                  {entityDetails.map((entity) => {
                    const EntityIcon = entity.icon;
                    const isFacebook = entity.type === 'facebook';
                    return (
                      <div
                        key={`${entity.type}:${entity.value}`}
                        className="flex items-center justify-between gap-3 p-3 rounded-lg border border-border/50 hover:border-emerald-500/20 transition-all group"
                      >
                        <div className="flex items-center gap-3 min-w-0">
                          <div className={`p-2 rounded-lg ${entity.bg} shrink-0`}>
                            <EntityIcon className={`h-4 w-4 ${entity.color}`} />
                          </div>
                          <div className="min-w-0">
                            <p className="text-xs text-muted-foreground">{entity.label}</p>
                            <p className="font-medium text-sm truncate">{entity.value}</p>
                          </div>
                        </div>
                        <div className="shrink-0">
                          {isFacebook ? (
                            <a
                              href={entity.value}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="inline-flex items-center gap-1.5 text-xs text-blue-600 dark:text-blue-400 hover:underline"
                            >
                              <ExternalLink className="h-3.5 w-3.5" />
                              Open
                            </a>
                          ) : (
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => handleEntitySearch(entity.value)}
                              className="gap-1.5 text-xs text-emerald-600 dark:text-emerald-400 hover:text-emerald-700 hover:bg-emerald-500/10"
                            >
                              <Search className="h-3.5 w-3.5" />
                              Search
                            </Button>
                          )}
                        </div>
                      </div>
                    );
                  })}
                </div>
              </CardContent>
            </Card>
          </motion.div>
        )}

        {/* Description */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.2 }}
        >
          <Card className="border-border/50">
            <CardHeader className="pb-0">
              <CardTitle className="text-lg flex items-center gap-2">
                <FileText className="h-5 w-5 text-muted-foreground" />
                Description
              </CardTitle>
            </CardHeader>
            <CardContent className="pt-2">
              <p className="text-muted-foreground leading-relaxed whitespace-pre-wrap">
                {report.description}
              </p>
            </CardContent>
          </Card>
        </motion.div>

        {/* Evidence Gallery */}
        {report.evidence && report.evidence.length > 0 && (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.4, delay: 0.25 }}
          >
            <Card className="border-border/50">
              <CardHeader className="pb-0">
                <CardTitle className="text-lg flex items-center gap-2">
                  <ImageIcon className="h-5 w-5 text-muted-foreground" />
                  Evidence ({report.evidence.length})
                </CardTitle>
              </CardHeader>
              <CardContent className="pt-2">
                <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3">
                  {report.evidence.map((ev) => (
                    <button
                      key={ev.id}
                      onClick={() => handleEvidencePreview(ev.fileUrl, ev.fileName)}
                      className="group relative aspect-square rounded-lg border border-border/50 overflow-hidden hover:border-emerald-500/30 transition-all focus:outline-none focus:ring-2 focus:ring-emerald-500/50"
                    >
                      <div className="absolute inset-0 bg-muted flex items-center justify-center">
                        {ev.fileType === 'image' ? (
                          <img
                            src={ev.fileUrl}
                            alt={ev.fileName}
                            className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
                            loading="lazy"
                          />
                        ) : (
                          <div className="flex flex-col items-center gap-1 text-muted-foreground">
                            <FileText className="h-8 w-8" />
                            <span className="text-xs truncate max-w-[80%]">{ev.fileName}</span>
                          </div>
                        )}
                      </div>
                      <div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors flex items-center justify-center">
                        <Search className="h-6 w-6 text-white opacity-0 group-hover:opacity-100 transition-opacity" />
                      </div>
                    </button>
                  ))}
                </div>
              </CardContent>
            </Card>
          </motion.div>
        )}

        {/* Linked Entities */}
        {report.linkedEntities && report.linkedEntities.length > 0 && (
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.4, delay: 0.3 }}
          >
            <Card className="border-border/50">
              <CardHeader className="pb-0">
                <CardTitle className="text-lg flex items-center gap-2">
                  <Tag className="h-5 w-5 text-muted-foreground" />
                  Linked Entities
                </CardTitle>
              </CardHeader>
              <CardContent className="pt-2">
                <div className="flex flex-wrap gap-2">
                  {report.linkedEntities.map((entity) => {
                    const entityConf = linkedEntityTypeConfig[entity.entityType] || linkedEntityTypeConfig.phone;
                    const EntityIcon = entityConf.icon;
                    return (
                      <button
                        key={entity.id}
                        onClick={() => handleEntitySearch(entity.entityValue)}
                        className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-border/50 ${entityConf.bg} ${entityConf.hoverBg} transition-all hover:border-emerald-500/30 text-sm`}
                      >
                        <EntityIcon className={`h-3.5 w-3.5 ${entityConf.color}`} />
                        <span className="font-medium">{entity.entityValue}</span>
                        {entity.reportCount !== undefined && entity.reportCount > 0 && (
                          <Badge variant="secondary" className="text-[10px] h-4 px-1">
                            {entity.reportCount}
                          </Badge>
                        )}
                      </button>
                    );
                  })}
                </div>
              </CardContent>
            </Card>
          </motion.div>
        )}

        {/* Related Reports */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.35 }}
        >
          <RelatedReports report={report} />
        </motion.div>

        {/* Reporter Info */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.4 }}
        >
          <Separator />
          <div className="flex items-center gap-2 text-sm text-muted-foreground py-2">
            <User className="h-4 w-4" />
            <span>
              Reported by{' '}
              <span className="font-medium text-foreground">
                {report.reporter?.name || 'Anonymous'}
              </span>{' '}
              on {formatDate(report.createdAt)}
            </span>
          </div>
        </motion.div>

        {/* Comments Section */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.45 }}
        >
          <CommentsSection reportId={report.id} />
        </motion.div>

        {/* Disclaimer */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.4, delay: 0.5 }}
        >
          <Card className="border-yellow-500/20 bg-yellow-500/5">
            <CardContent className="p-4">
              <div className="flex gap-3">
                <AlertCircle className="h-5 w-5 text-yellow-600 dark:text-yellow-400 shrink-0 mt-0.5" />
                <p className="text-sm text-yellow-700 dark:text-yellow-300 leading-relaxed">
                  This report is based on user-submitted information. ScamChecker BD does not verify individual claims.
                </p>
              </div>
            </CardContent>
          </Card>
        </motion.div>
      </div>

      {/* Floating Action Bar */}
      <div className="fixed bottom-0 left-0 right-0 z-30 bg-background/95 backdrop-blur-lg border-t border-border">
        <div className="max-w-4xl mx-auto px-4 py-3">
          <div className="flex items-center justify-between gap-2">
            <div className="flex items-center gap-2 min-w-0">
              <h3 className="text-sm font-medium truncate hidden sm:block">{report.title}</h3>
              <Badge variant="outline" className={`text-[10px] shrink-0 ${risk.color} ${risk.bg} ${risk.border}`}>
                {risk.label}
              </Badge>
            </div>
            <div className="flex items-center gap-1.5 shrink-0">
              <Button
                variant={hasUpvoted ? 'default' : 'outline'}
                size="sm"
                onClick={handleUpvote}
                disabled={hasUpvoted}
                className={`gap-1.5 ${
                  hasUpvoted
                    ? 'bg-emerald-600 hover:bg-emerald-700 text-white'
                    : 'border-emerald-500/30 text-emerald-600 hover:bg-emerald-500/10 dark:text-emerald-400'
                }`}
              >
                <ThumbsUp className="h-3.5 w-3.5" />
                {upvotes}
              </Button>
              <Button
                variant={isBookmarked ? 'default' : 'outline'}
                size="sm"
                onClick={handleBookmarkToggle}
                disabled={isBookmarkLoading}
                className={`gap-1.5 ${
                  isBookmarked
                    ? 'bg-amber-500 hover:bg-amber-600 text-white'
                    : 'border-amber-500/30 text-amber-600 hover:bg-amber-500/10 dark:text-amber-400'
                }`}
              >
                <Bookmark className={`h-3.5 w-3.5 ${isBookmarked ? 'fill-current' : ''}`} />
                <span className="hidden sm:inline">{isBookmarked ? 'Saved' : 'Save'}</span>
              </Button>
              <ShareButton report={report} />
            </div>
          </div>
        </div>
      </div>

      {/* Evidence Preview Dialog */}
      <Dialog open={evidencePreviewOpen} onOpenChange={setEvidencePreviewOpen}>
        <DialogContent className="sm:max-w-3xl p-0 overflow-hidden">
          <DialogTitle className="sr-only">{previewName}</DialogTitle>
          <DialogDescription className="sr-only">Evidence preview for {previewName}</DialogDescription>
          <div className="relative bg-black/90 flex items-center justify-center min-h-[300px] max-h-[80vh]">
            {previewUrl && (
              <img
                src={previewUrl}
                alt={previewName}
                className="max-w-full max-h-[80vh] object-contain"
              />
            )}
          </div>
          <div className="p-3 border-t bg-background">
            <p className="text-sm font-medium truncate">{previewName}</p>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
