'use client'; import { ArrowLeft, Factory, Plus, X } from 'lucide-react'; import * as React from 'react'; import { Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer, Legend, Tooltip, } from 'recharts'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Link } from '@/i18n/navigation'; import { useIndustrialCompare, useIndustrialParksSearch, } from '@/lib/hooks/use-khu-cong-nghiep'; import { type IndustrialParkDetail, type IndustrialParkListItem, PARK_STATUS_COLORS, PARK_STATUS_LABELS, REGION_LABELS, } from '@/lib/khu-cong-nghiep-api'; const CHART_COLORS = ['#3b82f6', '#ef4444', '#10b981', '#f59e0b']; const RADAR_METRICS = [ { key: 'occupancy', label: 'Lấp đầy' }, { key: 'area', label: 'Diện tích' }, { key: 'rent', label: 'Giá thuê' }, { key: 'infrastructure', label: 'Hạ tầng' }, { key: 'connectivity', label: 'Kết nối' }, ] as const; function normalizeScore(park: IndustrialParkDetail, metric: string): number { switch (metric) { case 'occupancy': return park.occupancyRate; case 'area': return Math.min((park.totalAreaHa / 1000) * 100, 100); case 'rent': { const rent = park.landRentUsdM2Year ?? 0; return rent > 0 ? Math.min((rent / 150) * 100, 100) : 0; } case 'infrastructure': { const count = park.infrastructure ? Object.keys(park.infrastructure).length : 0; return Math.min((count / 10) * 100, 100); } case 'connectivity': { const conns = park.connectivity ? Object.keys(park.connectivity).length : 0; return Math.min((conns / 8) * 100, 100); } default: return 0; } } function buildRadarData(parks: IndustrialParkDetail[]) { return RADAR_METRICS.map((metric) => { const entry: Record = { metric: metric.label }; parks.forEach((park, i) => { entry[`park${i}`] = Math.round(normalizeScore(park, metric.key)); }); return entry; }); } export function ParkCompareClient() { const [selectedIds, setSelectedIds] = React.useState([]); const [searchQuery, setSearchQuery] = React.useState(''); const [showPicker, setShowPicker] = React.useState(false); const { data: searchResults } = useIndustrialParksSearch({ q: searchQuery || undefined, limit: 20, }); const { data: compareData, isLoading } = useIndustrialCompare(selectedIds); const addPark = (park: IndustrialParkListItem) => { if (selectedIds.length >= 4) return; if (selectedIds.includes(park.id)) return; setSelectedIds((prev) => [...prev, park.id]); setShowPicker(false); setSearchQuery(''); }; const removePark = (id: string) => { setSelectedIds((prev) => prev.filter((pid) => pid !== id)); }; const radarData = compareData ? buildRadarData(compareData) : []; return (
{/* Header */}

So Sánh Khu Công Nghiệp

Chọn 2–4 KCN để so sánh chi tiết

{/* Park selection */}
{selectedIds.map((id, i) => { const park = compareData?.find((p) => p.id === id); return ( {park?.name ?? 'Đang tải...'} ); })} {selectedIds.length < 4 && (
{showPicker && (
setSearchQuery(e.target.value)} className="w-full rounded-md border bg-background px-3 py-2 text-sm" autoFocus />
{searchResults?.data .filter((p) => !selectedIds.includes(p.id)) .map((park) => ( ))} {searchResults?.data.length === 0 && (

Không tìm thấy KCN

)}
)}
)}
{/* Content */} {selectedIds.length < 2 ? (

Chọn ít nhất 2 KCN để so sánh

Sử dụng nút “Thêm KCN” ở trên để bắt đầu

) : isLoading ? (
{Array.from({ length: 2 }).map((_, i) => (
))}
) : compareData ? (
{/* Radar Chart */} Biểu đồ radar so sánh {compareData.map((park, i) => ( ))} {/* Comparison Table */} Chi tiết so sánh {compareData.map((park, i) => ( ))} ( {PARK_STATUS_LABELS[p.status]} )} /> REGION_LABELS[p.region]} /> p.province} /> `${p.totalAreaHa.toLocaleString()} ha`} /> `${p.leasableAreaHa.toLocaleString()} ha`} /> `${p.occupancyRate}%`} /> `${p.remainingAreaHa.toLocaleString()} ha`} /> String(p.tenantCount)} /> p.establishedYear ? String(p.establishedYear) : '—'} /> p.landRentUsdM2Year ? `$${p.landRentUsdM2Year}` : '—'} /> p.rbfRentUsdM2Month ? `$${p.rbfRentUsdM2Month}` : '—'} /> p.managementFeeUsd ? `$${p.managementFeeUsd}` : '—'} /> p.developer} /> (
{p.targetIndustries.slice(0, 4).map((ind) => ( {ind} ))} {p.targetIndustries.length > 4 && ( +{p.targetIndustries.length - 4} )}
)} /> (
{p.certifications?.map((cert) => ( {cert} )) ?? '—'}
)} />
Tiêu chí {park.name}
) : null}
); } function CompareRow({ label, parks, render, }: { label: string; parks: IndustrialParkDetail[]; render: (park: IndustrialParkDetail) => React.ReactNode; }) { return ( {label} {parks.map((park) => ( {render(park)} ))} ); }