import { Card, CardContent } from '@/components/ui/card';
import { cn } from '@/lib/utils';
import { Building2, Home, Sparkle, Star } from 'lucide-react';
import {
    Bar,
    BarChart,
    CartesianGrid,
    Cell,
    Legend,
    Line,
    LineChart,
    Pie,
    PieChart,
    ResponsiveContainer,
    Tooltip,
    XAxis,
    YAxis,
} from 'recharts';

/**
 * Single source of truth for channel colors used in the donut and the source comparison
 * bar chart. Hex values mirror the Tailwind classes used by `SourceBadge`.
 */
const SOURCE_COLORS: Record<string, string> = {
    'Airbnb': '#f43f5e',
    'Booking.com': '#3b82f6',
    'Expedia': '#eab308',
    'Vrbo': '#f97316',
    'Trip.com': '#06b6d4',
    'Hometogo': '#10b981',
    'Plum Guide': '#a855f7',
    'Google Travel': '#0ea5e9',
    'TUI Villas': '#f59e0b',
    'Onefinestay': '#78716c',
    'Top Villas': '#d946ef',
    'Agoda': '#ef4444',
    'Travelstaytion': '#14b8a6',
    'All Luxury Apartments': '#ec4899',
    'Thelandlord.tn': '#64748b',
};
const FALLBACK_COLOR = '#9ca3af';

function colorFor(source: string): string {
    return SOURCE_COLORS[source] ?? FALLBACK_COLOR;
}

// ────────────────────────────────────────────────────────────────────────────
// KPI cards
// ────────────────────────────────────────────────────────────────────────────

export interface HeroMetrics {
    total: number;
    average: number | null;
    five_star_count: number;
    five_star_pct: number | null;
    property_count: number;
}

export function KpiCards({ hero, t }: { hero: HeroMetrics; t: (ns: string, k: string) => string }) {
    return (
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
            <KpiCard
                icon={<Star className="h-5 w-5 text-yellow-500" fill="currentColor" stroke="none" />}
                label={t('reviews', 'kpi_average_rating')}
                value={hero.average !== null ? hero.average.toFixed(2) : '—'}
                hint={hero.average !== null ? '/ 5' : ''}
            />
            <KpiCard
                icon={<Home className="h-5 w-5 text-blue-500" />}
                label={t('reviews', 'kpi_total_reviews')}
                value={hero.total.toString()}
            />
            <KpiCard
                icon={<Sparkle className="h-5 w-5 text-emerald-500" />}
                label={t('reviews', 'kpi_five_star_pct')}
                value={hero.five_star_pct !== null ? `${hero.five_star_pct.toFixed(1)}%` : '—'}
                hint={hero.five_star_pct !== null ? `${hero.five_star_count} reviews ≥ 4.5★` : ''}
            />
            <KpiCard
                icon={<Building2 className="h-5 w-5 text-purple-500" />}
                label={t('reviews', 'kpi_properties_reviewed')}
                value={hero.property_count.toString()}
            />
        </div>
    );
}

function KpiCard({ icon, label, value, hint }: { icon: React.ReactNode; label: string; value: string; hint?: string }) {
    return (
        <Card>
            <CardContent className="flex flex-col gap-1 px-5 py-4">
                <div className="flex items-center gap-2 text-sm text-gray-500">
                    {icon}
                    <span>{label}</span>
                </div>
                <div className="text-3xl font-semibold text-gray-900">{value}</div>
                {hint && <div className="text-xs text-gray-400">{hint}</div>}
            </CardContent>
        </Card>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Monthly trend (line + dual axes)
// ────────────────────────────────────────────────────────────────────────────

export interface TrendPoint {
    month: string;
    average: number;
    count: number;
}

export function MonthlyTrendChart({ data, t }: { data: TrendPoint[]; t: (ns: string, k: string) => string }) {
    if (data.length === 0) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }
    return (
        <div className="h-72 w-full">
            <ResponsiveContainer>
                <LineChart data={data} margin={{ top: 8, right: 8, left: 0, bottom: 8 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
                    <XAxis dataKey="month" stroke="#6b7280" fontSize={12} />
                    <YAxis yAxisId="left" domain={[0, 5]} stroke="#eab308" fontSize={12} />
                    <YAxis yAxisId="right" orientation="right" stroke="#3b82f6" fontSize={12} allowDecimals={false} />
                    <Tooltip
                        contentStyle={{ borderRadius: '8px', fontSize: '12px' }}
                        formatter={(value: number, name: string) => [
                            name === 'average' ? value.toFixed(2) : value,
                            name === 'average' ? t('reviews', 'rating') : t('reviews', 'kpi_total_reviews'),
                        ]}
                    />
                    <Legend
                        formatter={(value: string) =>
                            value === 'average' ? t('reviews', 'rating') : t('reviews', 'kpi_total_reviews')
                        }
                    />
                    <Line yAxisId="left" type="monotone" dataKey="average" stroke="#eab308" strokeWidth={2} dot={{ r: 3 }} />
                    <Line yAxisId="right" type="monotone" dataKey="count" stroke="#3b82f6" strokeWidth={2} dot={{ r: 3 }} />
                </LineChart>
            </ResponsiveContainer>
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Source donut
// ────────────────────────────────────────────────────────────────────────────

export interface SourceBreakdownPoint {
    source: string;
    count: number;
}

export function SourceDonut({ data, t }: { data: SourceBreakdownPoint[]; t: (ns: string, k: string) => string }) {
    if (data.length === 0) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }
    return (
        <div className="h-72 w-full">
            <ResponsiveContainer>
                <PieChart>
                    <Pie
                        data={data}
                        dataKey="count"
                        nameKey="source"
                        cx="50%"
                        cy="50%"
                        innerRadius={50}
                        outerRadius={90}
                        paddingAngle={2}
                        label={({ source, percent }) => `${source} ${((percent ?? 0) * 100).toFixed(0)}%`}
                        labelLine={false}
                    >
                        {data.map((entry, idx) => (
                            <Cell key={`cell-${idx}`} fill={colorFor(entry.source)} />
                        ))}
                    </Pie>
                    <Tooltip
                        contentStyle={{ borderRadius: '8px', fontSize: '12px' }}
                        formatter={(value: number) => [value, t('reviews', 'kpi_total_reviews')]}
                    />
                </PieChart>
            </ResponsiveContainer>
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Property ranking table
// ────────────────────────────────────────────────────────────────────────────

export interface PropertyRank {
    property_id: string;
    name: string | null;
    average: number;
    count: number;
}

export function PropertyRankingTable({
    title,
    rows,
    tone,
    t,
}: {
    title: string;
    rows: PropertyRank[];
    tone: 'positive' | 'negative';
    t: (ns: string, k: string) => string;
}) {
    return (
        <Card>
            <CardContent className="px-5 py-4">
                <h3 className="mb-3 text-sm font-semibold text-gray-700">{title}</h3>
                {rows.length === 0 ? (
                    <EmptyState message={t('reviews', 'no_data')} small />
                ) : (
                    <table className="w-full text-sm">
                        <thead>
                            <tr className="border-b text-left text-xs text-gray-500">
                                <th className="py-2">{t('reviews', 'property')}</th>
                                <th className="py-2 text-right">{t('reviews', 'rating')}</th>
                                <th className="py-2 text-right">{t('reviews', 'kpi_total_reviews')}</th>
                            </tr>
                        </thead>
                        <tbody>
                            {rows.map((row) => (
                                <tr key={row.property_id} className="border-b last:border-b-0">
                                    <td className="py-2">{row.name ?? row.property_id}</td>
                                    <td className="py-2 text-right">
                                        <span
                                            className={cn(
                                                'font-semibold',
                                                tone === 'positive' ? 'text-emerald-600' : 'text-rose-600',
                                            )}
                                        >
                                            {row.average.toFixed(2)}
                                        </span>
                                        <span className="text-gray-400"> ★</span>
                                    </td>
                                    <td className="py-2 text-right text-gray-500">{row.count}</td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                )}
            </CardContent>
        </Card>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Category averages (horizontal bars)
// ────────────────────────────────────────────────────────────────────────────

export interface CategoryAverage {
    category: string;
    average: number;
    count: number;
}

export function CategoryBars({ data, t }: { data: CategoryAverage[]; t: (ns: string, k: string) => string }) {
    if (data.length === 0) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }
    const height = Math.max(220, data.length * 36);
    return (
        <div className="w-full" style={{ height: `${height}px` }}>
            <ResponsiveContainer>
                <BarChart data={data} layout="vertical" margin={{ top: 8, right: 16, left: 24, bottom: 8 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" horizontal={false} />
                    <XAxis type="number" domain={[0, 5]} stroke="#6b7280" fontSize={12} />
                    <YAxis dataKey="category" type="category" stroke="#6b7280" fontSize={12} width={140} />
                    <Tooltip
                        contentStyle={{ borderRadius: '8px', fontSize: '12px' }}
                        formatter={(value: number) => [`${value.toFixed(2)} / 5`, t('reviews', 'rating')]}
                    />
                    <Bar dataKey="average" fill="#eab308" radius={[0, 6, 6, 0]} />
                </BarChart>
            </ResponsiveContainer>
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Housekeeper cleanliness (femmes de ménage)
// ────────────────────────────────────────────────────────────────────────────

export interface HousekeeperCleanlinessComment {
    score: number;
    comment: string;
    property: string | null;
    source: string;
    date: string | null;
}

export interface HousekeeperCleanlinessRow {
    housekeeper_id: number | null;
    name: string;
    average: number;
    count: number;
    satisfied: number;
    dissatisfied: number;
    satisfaction_pct: number;
    reliable: boolean;
    worst_comments: HousekeeperCleanlinessComment[];
}

export interface HousekeeperCleanliness {
    rows: HousekeeperCleanlinessRow[];
    threshold: number;
    min_reviews: number;
    total_points: number;
    unassigned_count: number;
}

function scoreTone(score: number, threshold: number): 'good' | 'warn' | 'bad' {
    if (score < threshold) return 'bad';
    if (score < 4) return 'warn';
    return 'good';
}

const TONE_BAR: Record<'good' | 'warn' | 'bad', string> = {
    good: '#10b981',
    warn: '#eab308',
    bad: '#ef4444',
};

const TONE_TEXT: Record<'good' | 'warn' | 'bad', string> = {
    good: 'text-emerald-600',
    warn: 'text-yellow-600',
    bad: 'text-rose-600',
};

export function HousekeeperCleanlinessPanel({
    data,
    t,
}: {
    data: HousekeeperCleanliness;
    t: (ns: string, k: string) => string;
}) {
    if (!data || data.rows.length === 0) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }

    return (
        <div className="space-y-3">
            <p className="text-xs text-gray-500">
                {t('reviews', 'housekeeper_cleanliness_help')}
            </p>
            <div className="space-y-2">
                {data.rows.map((row) => (
                    <HousekeeperRow
                        key={row.housekeeper_id ?? 'unassigned'}
                        row={row}
                        threshold={data.threshold}
                        minReviews={data.min_reviews}
                        t={t}
                    />
                ))}
            </div>
        </div>
    );
}

function HousekeeperRow({
    row,
    threshold,
    minReviews,
    t,
}: {
    row: HousekeeperCleanlinessRow;
    threshold: number;
    minReviews: number;
    t: (ns: string, k: string) => string;
}) {
    const isUnassigned = row.housekeeper_id === null;
    const tone = scoreTone(row.average, threshold);
    const displayName = isUnassigned ? t('reviews', 'housekeeper_unassigned') : row.name;
    const pct = Math.max(0, Math.min(100, (row.average / 5) * 100));

    return (
        <div
            className={cn(
                'rounded-lg border px-4 py-3',
                isUnassigned ? 'border-dashed border-gray-200 bg-gray-50/50' : 'border-gray-100 bg-white',
            )}
        >
            <div className="flex flex-wrap items-center gap-x-4 gap-y-2">
                {/* Name + sample flag */}
                <div className="min-w-[9rem] flex-1">
                    <div className="flex items-center gap-2">
                        <span className={cn('text-sm font-medium', isUnassigned ? 'text-gray-500' : 'text-gray-800')}>
                            {displayName}
                        </span>
                        {!isUnassigned && !row.reliable && (
                            <span className="rounded-full bg-gray-100 px-2 py-0.5 text-[10px] font-medium text-gray-500">
                                {t('reviews', 'housekeeper_low_sample')}
                            </span>
                        )}
                    </div>
                    <div className="mt-1 text-xs text-gray-400">
                        {row.count} {t('reviews', 'housekeeper_reviews_label')}
                    </div>
                </div>

                {/* Score bar */}
                <div className="flex min-w-[10rem] flex-1 items-center gap-2">
                    <div className="h-2.5 flex-1 overflow-hidden rounded-full bg-gray-100">
                        <div className="h-full rounded-full" style={{ width: `${pct}%`, backgroundColor: TONE_BAR[tone] }} />
                    </div>
                    <span className={cn('w-14 text-right text-sm font-semibold', TONE_TEXT[tone])}>
                        {row.average.toFixed(2)}
                        <span className="text-[10px] font-normal text-gray-400"> /5</span>
                    </span>
                </div>

                {/* Satisfaction */}
                <div className="w-24 text-right">
                    <div className={cn('text-sm font-semibold', TONE_TEXT[tone])}>{row.satisfaction_pct.toFixed(0)}%</div>
                    <div className="text-[10px] text-gray-400">{t('reviews', 'housekeeper_satisfaction')}</div>
                </div>
            </div>

            {/* Worst comments (collapsible) */}
            {row.worst_comments.length > 0 && (
                <details className="mt-2 group">
                    <summary className="cursor-pointer list-none text-xs font-medium text-gray-500 hover:text-gray-700">
                        <span className="group-open:hidden">▸ </span>
                        <span className="hidden group-open:inline">▾ </span>
                        {t('reviews', 'housekeeper_show_comments')} ({row.worst_comments.length})
                    </summary>
                    <ul className="mt-2 space-y-2 border-l-2 border-gray-100 pl-3">
                        {row.worst_comments.map((c, idx) => {
                            const cTone = scoreTone(c.score, threshold);
                            return (
                                <li key={idx} className="text-xs">
                                    <div className="flex items-center gap-2">
                                        <span className={cn('font-semibold', TONE_TEXT[cTone])}>{c.score.toFixed(1)}/5</span>
                                        {c.property && <span className="text-gray-400">· {c.property}</span>}
                                        <span className="text-gray-300">· {c.source}</span>
                                    </div>
                                    <p className="mt-0.5 whitespace-pre-line text-gray-600">{c.comment}</p>
                                </li>
                            );
                        })}
                    </ul>
                </details>
            )}
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Rating distribution histogram
// ────────────────────────────────────────────────────────────────────────────

export interface DistributionBucket {
    bucket: string;
    count: number;
}

export function RatingDistributionChart({ data, t }: { data: DistributionBucket[]; t: (ns: string, k: string) => string }) {
    if (data.length === 0 || data.every((d) => d.count === 0)) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }
    const bucketColors: Record<string, string> = {
        '0-1': '#ef4444',
        '1-2': '#f97316',
        '2-3': '#eab308',
        '3-4': '#84cc16',
        '4-5': '#10b981',
    };
    return (
        <div className="h-72 w-full">
            <ResponsiveContainer>
                <BarChart data={data} margin={{ top: 8, right: 8, left: 0, bottom: 8 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
                    <XAxis dataKey="bucket" stroke="#6b7280" fontSize={12} />
                    <YAxis stroke="#6b7280" fontSize={12} allowDecimals={false} />
                    <Tooltip
                        contentStyle={{ borderRadius: '8px', fontSize: '12px' }}
                        formatter={(value: number) => [value, t('reviews', 'kpi_total_reviews')]}
                    />
                    <Bar dataKey="count" radius={[6, 6, 0, 0]}>
                        {data.map((entry, idx) => (
                            <Cell key={`cell-${idx}`} fill={bucketColors[entry.bucket] ?? '#9ca3af'} />
                        ))}
                    </Bar>
                </BarChart>
            </ResponsiveContainer>
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Source comparison bars (avg rating per source)
// ────────────────────────────────────────────────────────────────────────────

export interface SourceAverage {
    source: string;
    average: number;
    count: number;
}

export function SourceComparisonChart({ data, t }: { data: SourceAverage[]; t: (ns: string, k: string) => string }) {
    if (data.length === 0) {
        return <EmptyState message={t('reviews', 'no_data')} />;
    }
    return (
        <div className="h-72 w-full">
            <ResponsiveContainer>
                <BarChart data={data} margin={{ top: 8, right: 8, left: 0, bottom: 8 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
                    <XAxis dataKey="source" stroke="#6b7280" fontSize={12} />
                    <YAxis domain={[0, 5]} stroke="#6b7280" fontSize={12} />
                    <Tooltip
                        contentStyle={{ borderRadius: '8px', fontSize: '12px' }}
                        formatter={(value: number) => [`${value.toFixed(2)} / 5`, t('reviews', 'rating')]}
                    />
                    <Bar dataKey="average" radius={[6, 6, 0, 0]}>
                        {data.map((entry, idx) => (
                            <Cell key={`cell-${idx}`} fill={colorFor(entry.source)} />
                        ))}
                    </Bar>
                </BarChart>
            </ResponsiveContainer>
        </div>
    );
}

// ────────────────────────────────────────────────────────────────────────────
// Shared: empty state
// ────────────────────────────────────────────────────────────────────────────

export function EmptyState({ message, small = false }: { message: string; small?: boolean }) {
    return (
        <div
            className={cn(
                'flex items-center justify-center rounded-md bg-gray-50 text-gray-400',
                small ? 'py-6 text-xs' : 'h-72 text-sm',
            )}
        >
            {message}
        </div>
    );
}

export function StatsSection({
    title,
    children,
    className,
}: {
    title: string;
    children: React.ReactNode;
    className?: string;
}) {
    return (
        <Card className={className}>
            <CardContent className="px-5 py-4">
                <h3 className="mb-3 text-sm font-semibold text-gray-700">{title}</h3>
                {children}
            </CardContent>
        </Card>
    );
}
