

"use client";

import { useState, useEffect, useCallback } from "react";
import { DashboardLayout } from "@/components/layout/dashboard-layout";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useAuth } from "@/hooks/use-auth";
import { Copy, Gift, Loader2, Users } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { db } from "@/lib/firebase";
import { doc, getDoc, collection, query, where, getDocs, orderBy, addDoc, serverTimestamp } from "firebase/firestore";
import { Progress } from "@/components/ui/progress";
import Link from "next/link";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { format } from 'date-fns';
import { Badge } from "@/components/ui/badge";

interface ReferralSettings {
    refEarnHeader?: string;
    refEarnDescription?: string;
    refAccessEnabled?: boolean;
    refAccessCondition?: 'min_deposit' | 'min_investment';
    refAccessAmount?: number;
    depositCommissionEnabled?: boolean;
    depositLevels?: CommissionLevel[];
    investmentCommissionEnabled?: boolean;
    investmentLevels?: CommissionLevel[];
    interestCommissionEnabled?: boolean;
    interestLevels?: CommissionLevel[];
    stakingCommissionEnabled?: boolean;
    stakingLevels?: CommissionLevel[];
}

interface CommissionLevel {
  id: string;
  value: number;
  type: 'fixed' | 'percentage';
}

interface UserStats {
    totalDeposits: number;
    totalInvestments: number;
}

interface CurrencySettings {
  symbol: string;
  position: 'left' | 'right';
}

interface CommissionHistoryItem {
    id: string;
    amount: number;
    type: 'deposit' | 'investment' | 'interest' | 'referral' | 'staking';
    level: number;
    date: any;
    referredUsername: string;
}

export default function RefAndEarnPage() {
    const { user } = useAuth();
    const { toast } = useToast();
    const [referralLink, setReferralLink] = useState("");
    const [settings, setSettings] = useState<ReferralSettings | null>(null);
    const [userStats, setUserStats] = useState<UserStats>({ totalDeposits: 0, totalInvestments: 0 });
    const [currency, setCurrency] = useState<CurrencySettings>({ symbol: '$', position: 'left' });
    const [loading, setLoading] = useState(true);
    const [referralData, setReferralData] = useState<{ totalCommissions: number, totalReferrals: number }>({ totalCommissions: 0, totalReferrals: 0 });
    const [commissionHistory, setCommissionHistory] = useState<CommissionHistoryItem[]>([]);
    const [notificationSettings, setNotificationSettings] = useState<any>(null);

    const fetchAllData = useCallback(async () => {
        if (!user || !db) {
            setLoading(false);
            return;
        }
        setLoading(true);
        try {
            setReferralLink(`${window.location.origin}/signup?ref=${user.uid}`);

            const referralSettingsDoc = await getDoc(doc(db, "settings", "referral"));
            const referralSettings = referralSettingsDoc.exists() ? referralSettingsDoc.data() as ReferralSettings : null;
            setSettings(referralSettings);
            
            const currencyDoc = await getDoc(doc(db, "settings", "currency"));
            if(currencyDoc.exists()) setCurrency(currencyDoc.data() as CurrencySettings);

             const notificationSettingsDoc = await getDoc(doc(db, 'settings', 'notifications'));
             if (notificationSettingsDoc.exists()) {
                setNotificationSettings(notificationSettingsDoc.data());
             }

            const depositsQuery = query(collection(db, "deposits"), where("userId", "==", user.uid), where("status", "==", "completed"));
            const depositsSnapshot = await getDocs(depositsQuery);
            const totalDeposits = depositsSnapshot.docs.reduce((sum, doc) => sum + doc.data().amount, 0);

            const investmentsQuery = query(collection(db, "userInvestments"), where("userId", "==", user.uid), where("status", "==", "active"));
            const investmentsSnapshot = await getDocs(investmentsQuery);
            const totalInvestments = investmentsSnapshot.docs.reduce((sum, doc) => sum + doc.data().amount, 0);
            
            setUserStats({ totalDeposits, totalInvestments });

            const commissionsQuery = query(collection(db, "referralCommissions"), where("referrerId", "==", user.uid));
            const commissionsSnapshot = await getDocs(commissionsQuery);
            const totalCommissions = commissionsSnapshot.docs.reduce((sum, doc) => sum + doc.data().amount, 0);

            const validCommissions = commissionsSnapshot.docs.filter(doc => doc.data().amount > 0);

            const historyPromises = validCommissions.map(async (commissionDoc) => {
                const commissionData = commissionDoc.data();
                let referredUsername = 'Unknown User';
                if (commissionData.referredUserId) {
                    const userDoc = await getDoc(doc(db, "users", commissionData.referredUserId));
                    if (userDoc.exists()) {
                        referredUsername = userDoc.data().username || `User ${commissionData.referredUserId.slice(0, 5)}`;
                    }
                }
                return {
                    id: commissionDoc.id,
                    amount: commissionData.amount,
                    type: commissionData.type,
                    level: commissionData.level,
                    date: commissionData.date,
                    referredUsername,
                } as CommissionHistoryItem;
            });

            const commissionHistoryData = await Promise.all(historyPromises);
             commissionHistoryData.sort((a,b) => b.date.seconds - a.date.seconds);
            setCommissionHistory(commissionHistoryData);
            
            const maxLevels = Math.max(
                referralSettings?.depositLevels?.length || 0,
                referralSettings?.investmentLevels?.length || 0,
                referralSettings?.interestLevels?.length || 0,
                referralSettings?.stakingLevels?.length || 0
            );

            let allReferralsCount = 0;
            const fetchReferralsRecursively = async (parentIds: string[], currentLevel: number) => {
                if (currentLevel > maxLevels || parentIds.length === 0) {
                    return;
                }
                const q = query(collection(db, "users"), where("referredBy", "in", parentIds));
                const snapshot = await getDocs(q);
                const newReferralsCount = snapshot.size;
                if (newReferralsCount > 0) {
                    allReferralsCount += newReferralsCount;
                    const newIds = snapshot.docs.map(d => d.id);
                    await fetchReferralsRecursively(newIds, currentLevel + 1);
                }
            };

            await fetchReferralsRecursively([user.uid], 1);
            setReferralData({ totalCommissions, totalReferrals: allReferralsCount });

        } catch (error) {
            console.error("Error fetching referral data:", error);
            toast({ variant: "destructive", title: "Error", description: "Could not fetch referral data." });
        } finally {
            setLoading(false);
        }
    }, [user, toast]);

    useEffect(() => {
        fetchAllData();
    }, [fetchAllData]);

    const copyToClipboard = () => {
        navigator.clipboard.writeText(referralLink).then(() => {
            toast({ title: "Copied!", description: "Referral link copied to clipboard." });
        });
    };

    const formatCurrency = (amount: number) => {
        const value = amount.toFixed(2);
        return currency.position === 'left' ? `${currency.symbol}${value}` : `${value}${currency.symbol}`;
    }
    
    const renderRequirementCard = () => {
        if (!settings || !settings.refAccessEnabled || !settings.refAccessAmount) return null;
        
        const isDepositCondition = settings.refAccessCondition === 'min_deposit';
        const targetAmount = settings.refAccessAmount;
        const currentAmount = isDepositCondition ? userStats.totalDeposits : userStats.totalInvestments;
        
        const progress = Math.min(100, (currentAmount / targetAmount) * 100);
        const amountNeeded = Math.max(0, targetAmount - currentAmount);

        if (progress >= 100) return null;

        return (
            <Card>
                <CardHeader>
                    <CardTitle className="flex items-center gap-2">
                        <Gift className="text-primary"/> Unlock Your Referral Link
                    </CardTitle>
                    <CardDescription>
                        You're almost there! You need to {isDepositCondition ? 'deposit' : 'invest'} at least {formatCurrency(targetAmount)} to start earning from referrals.
                    </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                    <Progress value={progress} />
                    <div className="text-center text-sm text-muted-foreground">
                        {progress.toFixed(0)}% Complete
                    </div>
                    <p className="text-center font-semibold">
                        You need {formatCurrency(amountNeeded)} more to unlock your link.
                    </p>
                    <div className="flex justify-center gap-4">
                        <Button asChild>
                            <Link href={isDepositCondition ? "/dashboard/finance/deposit" : "/dashboard/investment"}>
                                {isDepositCondition ? 'Deposit Now' : 'Invest Now'}
                            </Link>
                        </Button>
                    </div>
                </CardContent>
            </Card>
        )
    }
    
    const canViewReferralLink = !settings?.refAccessEnabled || (settings.refAccessAmount && 
        (settings.refAccessCondition === 'min_deposit' ? userStats.totalDeposits >= settings.refAccessAmount : userStats.totalInvestments >= settings.refAccessAmount)
    );

    const CommissionTable = ({ title, levels }: { title: string; levels: CommissionLevel[] | undefined }) => (
        <div>
            <h4 className="font-semibold mb-2">{title}</h4>
            {levels && levels.length > 0 ? (
                 <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead>Level</TableHead>
                            <TableHead className="text-right">Commission</TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {levels.map((level, index) => (
                            <TableRow key={level.id}>
                                <TableCell>Level {index + 1}</TableCell>
                                <TableCell className="text-right">{level.type === 'fixed' ? formatCurrency(level.value) : `${level.value}%`}</TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            ) : <p className="text-sm text-muted-foreground">Not enabled.</p>}
        </div>
    );

    if(loading) {
        return (
            <DashboardLayout>
                <div className="flex items-center justify-center p-16">
                    <Loader2 className="h-12 w-12 animate-spin text-primary" />
                </div>
            </DashboardLayout>
        )
    }

    return (
        <DashboardLayout>
            <div className="space-y-6">
                <div>
                    <h1 className="text-3xl font-bold font-headline tracking-tight">{settings?.refEarnHeader || "Refer & Earn"}</h1>
                    <p className="text-muted-foreground">{settings?.refEarnDescription || "Share your referral link with friends and earn commissions."}</p>
                </div>

                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                     <Card>
                        <CardHeader>
                            <CardTitle>Total Commissions</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <p className="text-4xl font-bold text-primary">{formatCurrency(referralData.totalCommissions)}</p>
                        </CardContent>
                     </Card>
                      <Card>
                        <CardHeader>
                            <CardTitle>Total Referrals</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <p className="text-4xl font-bold text-primary">{referralData.totalReferrals}</p>
                        </CardContent>
                     </Card>
                </div>
                
                {canViewReferralLink ? (
                     <Card>
                        <CardHeader>
                            <CardTitle>Your Referral Link</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <div className="flex items-center gap-2">
                                <Input value={referralLink} readOnly />
                                <Button onClick={copyToClipboard} size="icon" variant="outline">
                                    <Copy className="h-4 w-4" />
                                </Button>
                            </div>
                        </CardContent>
                    </Card>
                ) : (
                    renderRequirementCard()
                )}

                <Card>
                     <CardHeader>
                        <CardTitle>Commission Structure</CardTitle>
                        <CardDescription>
                           This is how you earn commissions from your referrals.
                        </CardDescription>
                    </CardHeader>
                    <CardContent className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
                        {settings?.depositCommissionEnabled && <CommissionTable title="On Deposit" levels={settings.depositLevels} />}
                        {settings?.investmentCommissionEnabled && <CommissionTable title="On Investment" levels={settings.investmentLevels} />}
                        {settings?.stakingCommissionEnabled && <CommissionTable title="On Staking" levels={settings.stakingLevels} />}
                        {settings?.interestCommissionEnabled && <CommissionTable title="On Interest Return" levels={settings.interestLevels} />}
                    </CardContent>
                </Card>

                 <Card>
                    <CardHeader><CardTitle>Commission History</CardTitle></CardHeader>
                    <CardContent>
                        {commissionHistory.length > 0 ? (
                            <Table>
                                <TableHeader>
                                    <TableRow>
                                        <TableHead>From User</TableHead>
                                        <TableHead>Type</TableHead>
                                        <TableHead>Level</TableHead>
                                        <TableHead>Amount</TableHead>
                                        <TableHead className="text-right">Date</TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {commissionHistory.map(item => (
                                        <TableRow key={item.id}>
                                            <TableCell>{item.referredUsername}</TableCell>
                                            <TableCell><Badge variant="secondary" className="capitalize">{item.type}</Badge></TableCell>
                                            <TableCell><Badge>Level {item.level}</Badge></TableCell>
                                            <TableCell className="font-semibold text-primary">{formatCurrency(item.amount)}</TableCell>
                                            <TableCell className="text-right">{item.date ? format(item.date.toDate(), 'PP') : 'N/A'}</TableCell>
                                        </TableRow>
                                    ))}
                                </TableBody>
                            </Table>
                        ) : (
                            <p className="text-center text-muted-foreground p-8">You haven't earned any commissions yet.</p>
                        )}
                    </CardContent>
                </Card>
            </div>
        </DashboardLayout>
    );
}
