'use client';
import { useState, useEffect } from 'react';
import { Flame, MessageSquare, ArrowUp, ArrowDown } from 'lucide-react';
import { getPosts } from '@/actions/forum';
import type { ForumPost } from '@/types/forum';
import Link from 'next/link';
interface ControversialWidgetProps {
limit?: number;
showViewAll?: boolean;
}
/**
* ControversialWidget - Displays most controversial/debated discussions
*
* Controversial = High engagement from both upvotes AND downvotes
*/
export function ControversialWidget({ limit = 5, showViewAll = true }: ControversialWidgetProps) {
const [posts, setPosts] = useState<ForumPost[]>([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const loadControversial = async () => {
const result = await getPosts({
sort: 'controversial',
limit,
offset: 0,
min_upvotes: 3, // Require some minimum engagement
});
if (result.success && result.data) {
setPosts(result.data.data);
}
setIsLoading(false);
};
loadControversial();
}, [limit]);
if (isLoading) {
return (
<div className="bg-background-secondary border-2 border-border-primary rounded-lg p-6">
<div className="animate-pulse space-y-4">
<div className="h-6 bg-background-primary rounded w-1/2" />
<div className="space-y-3">
{[...Array(3)].map((_, i) => (
<div key={i} className="h-4 bg-background-primary rounded" />
))}
</div>
</div>
</div>
);
}
if (posts.length === 0) {
return null;
}
const getControversyScore = (post: ForumPost) => {
// Higher score = more controversial (high both upvotes and downvotes)
return Math.min(post.upvotes_count, post.downvotes_count) + post.reply_count;
};
return (
<div className="bg-background-secondary border-2 border-border-primary rounded-lg p-6">
{/* Header */}
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold text-text-primary flex items-center gap-2">
<Flame className="text-orange-500" size={24} />
Most Debated
</h3>
{showViewAll && (
<Link
href="/forum/discussions?sort=controversial"
className="text-sm text-accent-red hover:underline"
>
View all
</Link>
)}
</div>
{/* Controversial posts */}
<div className="space-y-3">
{posts.map((post) => {
const totalVotes = post.upvotes_count + post.downvotes_count;
const upvotePercent = totalVotes > 0 ? (post.upvotes_count / totalVotes) * 100 : 50;
return (
<Link
key={post.id}
href={
post.post_type === 'bill_comment'
? `/bills/${post.bill_session}/${post.bill_number}#post-${post.id}`
: `/forum/posts/${post.id}`
}
className="
block p-3 rounded-lg bg-background-primary
hover:bg-background-secondary border-2 border-transparent
hover:border-orange-500 transition-all group
"
>
<div className="space-y-2">
{/* Title */}
<h4 className="font-medium text-text-primary group-hover:text-orange-500 transition-colors line-clamp-2">
{post.title || post.content.substring(0, 100)}
</h4>
{/* Vote bar */}
<div className="flex items-center gap-2">
<div className="flex-1 h-2 bg-background-secondary rounded-full overflow-hidden">
<div
className="h-full bg-gradient-to-r from-green-500 to-red-500 transition-all"
style={{ width: `${upvotePercent}%` }}
/>
</div>
</div>
{/* Stats */}
<div className="flex items-center gap-3 text-xs text-text-tertiary">
<span className="flex items-center gap-1 text-green-500">
<ArrowUp size={12} />
{post.upvotes_count}
</span>
<span className="flex items-center gap-1 text-red-500">
<ArrowDown size={12} />
{post.downvotes_count}
</span>
<span className="flex items-center gap-1">
<MessageSquare size={12} />
{post.reply_count}
</span>
{post.post_type === 'bill_comment' && post.bill_number && (
<span className="font-mono bg-background-secondary px-1.5 py-0.5 rounded ml-auto">
{post.bill_number}
</span>
)}
</div>
</div>
</Link>
);
})}
</div>
{/* Legend */}
<div className="mt-4 pt-4 border-t border-border-primary">
<p className="text-xs text-text-tertiary italic">
Discussions with strong opinions on both sides
</p>
</div>
</div>
);
}