
"use client";

import { DashboardLayout } from "@/components/layout/dashboard-layout";
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Gift, Loader2 } from "lucide-react";
import { useState, useEffect } from "react";
import { db } from "@/lib/firebase";
import { doc, getDoc, updateDoc, collection, addDoc, query, where, getDocs, runTransaction, serverTimestamp } from "firebase/firestore";
import { useToast } from "@/hooks/use-toast";
import { useAuth } from "@/hooks/use-auth";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { format } from "date-fns";
import { addEarning } from "@/lib/earnings";

interface BonusSettings {
  dailyBonusEnabled: boolean;
  dailyBonusAmount: number;
  dailyBonusStart: string;
  dailyBonusEnd: string;
}

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

interface BonusTransaction {
    id: string;
    amount: number;
    date: any;
    description: string;
    type: 'signup' | 'daily' | 'task';
}

function Countdown({ endTime }: { endTime: number }) {
  const [timeLeft, setTimeLeft] = useState<string>("--:--:--");

  useEffect(() => {
      const timer = setInterval(() => {
          const now = new Date().getTime();
          const distance = endTime - now;
          
          if (distance < 0) {
              setTimeLeft("00:00:00");
              clearInterval(timer);
              return;
          }

          const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
          const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
          const seconds = Math.floor((distance % (1000 * 60)) / 1000);
          
          setTimeLeft(
              `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
          );

      }, 1000);

      return () => clearInterval(timer);
  }, [endTime]);

  return <div className="text-2xl font-mono font-semibold p-3 bg-muted rounded-lg">{timeLeft}</div>;
}


export default function DailyBonusPage() {
    const { toast } = useToast();
    const { user } = useAuth();
    const [settings, setSettings] = useState<BonusSettings | null>(null);
    const [currency, setCurrency] = useState<CurrencySettings>({ symbol: '$', position: 'left' });
    const [loading, setLoading] = useState(true);
    const [claiming, setClaiming] = useState(false);
    const [canClaim, setCanClaim] = useState(false);
    const [nextBonusTime, setNextBonusTime] = useState<number | null>(null);
    const [lastClaim, setLastClaim] = useState<Date | null>(null);
    const [history, setHistory] = useState<BonusTransaction[]>([]);
    const [loadingHistory, setLoadingHistory] = useState(true);

    useEffect(() => {
        if (!user || !db) {
            setLoading(false);
            setLoadingHistory(false);
            return;
        }

        const fetchSettingsAndStatus = async () => {
            setLoading(true);
            try {
                const bonusDoc = await getDoc(doc(db, 'settings', 'bonus'));
                if (bonusDoc.exists()) {
                    setSettings(bonusDoc.data() as BonusSettings);
                }
                const currencyDoc = await getDoc(doc(db, 'settings', 'currency'));
                if (currencyDoc.exists()) {
                    setCurrency(currencyDoc.data() as CurrencySettings);
                }
                const userDoc = await getDoc(doc(db, 'users', user.uid));
                if (userDoc.exists() && userDoc.data().lastDailyBonusClaim) {
                    setLastClaim(userDoc.data().lastDailyBonusClaim.toDate());
                }

            } catch (error) {
                toast({ variant: 'destructive', title: 'Error', description: 'Failed to fetch bonus settings.' });
            } finally {
                setLoading(false);
            }
        };

        const fetchHistory = async () => {
            setLoadingHistory(true);
            try {
                const q = query(
                    collection(db, 'bonusTransactions'), 
                    where('userId', '==', user.uid),
                    where('type', '==', 'daily')
                );
                const querySnapshot = await getDocs(q);
                const historyData = querySnapshot.docs.map(d => ({id: d.id, ...d.data()}) as BonusTransaction)
                    .sort((a,b) => b.date.seconds - a.date.seconds);
                setHistory(historyData);
            } catch (error) {
                toast({ variant: 'destructive', title: 'Error', description: 'Failed to fetch claim history.' });
            } finally {
                setLoadingHistory(false);
            }
        }

        fetchSettingsAndStatus();
        fetchHistory();
    }, [toast, user]);
    
    useEffect(() => {
        if (!settings) return;

        const now = new Date();
        
        if(lastClaim) {
            const lastClaimDate = new Date(lastClaim);
            if(lastClaimDate.getFullYear() === now.getFullYear() &&
               lastClaimDate.getMonth() === now.getMonth() &&
               lastClaimDate.getDate() === now.getDate()) {
                setCanClaim(false);
                const nextDay = new Date(now);
                nextDay.setDate(now.getDate() + 1);
                const [startHour, startMinute] = settings.dailyBonusStart.split(':').map(Number);
                nextDay.setHours(startHour, startMinute, 0, 0);
                setNextBonusTime(nextDay.getTime());
                return;
            }
        }

        const [startHour, startMinute] = settings.dailyBonusStart.split(':').map(Number);
        const [endHour, endMinute] = settings.dailyBonusEnd.split(':').map(Number);
        
        const startTime = new Date();
        startTime.setHours(startHour, startMinute, 0, 0);
        
        const endTime = new Date();
        endTime.setHours(endHour, endMinute, 0, 0);

        if (now >= startTime && now <= endTime) {
            setCanClaim(true);
            setNextBonusTime(null);
        } else {
            setCanClaim(false);
            let nextStartTime = new Date(startTime);
            if(now > endTime) {
                nextStartTime.setDate(nextStartTime.getDate() + 1);
            }
            setNextBonusTime(nextStartTime.getTime());
        }

    }, [settings, lastClaim]);

    const handleClaim = async () => {
        if (!db || !user || !settings) return;
        setClaiming(true);
        try {
            await runTransaction(db, async (transaction) => {
                const userRef = doc(db, 'users', user.uid);
                const earningRulesDocRef = doc(db, 'settings', 'earningRules');
    
                const [userDoc, earningRulesDoc] = await Promise.all([
                    transaction.get(userRef),
                    transaction.get(earningRulesDocRef),
                ]);
    
                if (!userDoc.exists()) {
                    throw new Error("User not found.");
                }
    
                // Use the centralized earning function
                await addEarning(transaction, user.uid, settings.dailyBonusAmount, userDoc, earningRulesDoc);
    
                // Update the last claim timestamp
                transaction.update(userRef, { lastDailyBonusClaim: new Date() });
                
                // Log the bonus transaction
                const newTransactionRef = doc(collection(db, 'bonusTransactions'));
                transaction.set(newTransactionRef, {
                    userId: user.uid,
                    type: 'daily',
                    amount: settings.dailyBonusAmount,
                    date: serverTimestamp(),
                    description: 'Daily Bonus Claim'
                });
            });
    
            // Optimistically update UI
            setHistory(prevHistory => [{ 
                id: 'temp-' + Date.now(), 
                amount: settings.dailyBonusAmount,
                date: { seconds: Math.floor(Date.now() / 1000) },
                description: 'Daily Bonus Claim',
                type: 'daily'
            }, ...prevHistory]);
            
            toast({ title: 'Success!', description: `You have successfully claimed your daily bonus of ${formatCurrency(settings.dailyBonusAmount)}`});
            setCanClaim(false);
            setLastClaim(new Date());

        } catch (error: any) {
             toast({ variant: 'destructive', title: 'Error', description: `Failed to claim bonus: ${error.message}` });
        } finally {
            setClaiming(false);
        }
    }

    const formatCurrency = (amount: number) => {
        const value = (amount || 0).toFixed(2);
        return currency.position === 'left' ? `${currency.symbol}${value}` : `${value}${currency.symbol}`;
    };

    if (loading) {
        return (
            <DashboardLayout>
                <div className="flex justify-center items-center h-full">
                    <Loader2 className="h-8 w-8 animate-spin" />
                </div>
            </DashboardLayout>
        );
    }
    
    if (!settings || !settings.dailyBonusEnabled) {
        return (
             <DashboardLayout>
                <div className="space-y-6">
                    <div>
                        <h1 className="text-3xl font-bold font-headline tracking-tight">Daily Bonus</h1>
                        <p className="text-muted-foreground">Claim your daily reward for being an active member.</p>
                    </div>
                    <Card>
                        <CardContent className="p-8 text-center text-muted-foreground">
                            The daily bonus is currently not available.
                        </CardContent>
                    </Card>
                </div>
             </DashboardLayout>
        )
    }
    
  return (
    <DashboardLayout>
      <div className="space-y-6">
        <div>
            <h1 className="text-3xl font-bold font-headline tracking-tight">Daily Bonus</h1>
            <p className="text-muted-foreground">Claim your daily reward for being an active member.</p>
        </div>
        <Tabs defaultValue="claim">
            <TabsList className="grid w-full grid-cols-2">
                <TabsTrigger value="claim">Claim Bonus</TabsTrigger>
                <TabsTrigger value="history">Claim History</TabsTrigger>
            </TabsList>
            <TabsContent value="claim">
                <Card className="max-w-md mx-auto mt-6">
                    <CardHeader className="text-center">
                        <Gift className="mx-auto h-16 w-16 text-primary mb-4" />
                        <CardTitle>{canClaim ? "Your Daily Bonus is Ready!" : "Daily Bonus"}</CardTitle>
                        <CardDescription>
                        {canClaim ? "Click the button below to claim your reward." : "Come back later to claim your daily reward."}
                        </CardDescription>
                    </CardHeader>
                    <CardContent className="text-center space-y-4">
                        <div className="text-4xl font-bold text-primary">
                            {formatCurrency(settings.dailyBonusAmount)}
                        </div>
                        <p className="text-muted-foreground">
                            {canClaim ? "Bonus available now!" : "Next bonus available in:"}
                        </p>
                        {nextBonusTime && !canClaim && <Countdown endTime={nextBonusTime} />}

                        <Button size="lg" className="w-full" disabled={!canClaim || claiming} onClick={handleClaim}>
                            {claiming && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                            {canClaim ? 'Claim Now' : (lastClaim ? 'Already Claimed Today' : 'Come Back Later')}
                        </Button>
                    </CardContent>
                </Card>
            </TabsContent>
            <TabsContent value="history">
                 <Card className="mt-6">
                    <CardHeader>
                        <CardTitle>Claim History</CardTitle>
                        <CardDescription>A log of all the daily bonuses you have claimed.</CardDescription>
                    </CardHeader>
                    <CardContent>
                         {loadingHistory ? (
                             <div className="flex justify-center items-center h-48"><Loader2 className="h-8 w-8 animate-spin" /></div>
                         ) : history.length > 0 ? (
                            <Table>
                                <TableHeader>
                                    <TableRow>
                                        <TableHead>Amount</TableHead>
                                        <TableHead className="text-right">Date</TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {history.map((item) => (
                                        <TableRow key={item.id}>
                                            <TableCell>{formatCurrency(item.amount)}</TableCell>
                                            <TableCell className="text-right">{format(new Date(item.date.seconds * 1000), 'PPp')}</TableCell>
                                        </TableRow>
                                    ))}
                                </TableBody>
                            </Table>
                         ) : (
                            <p className="text-center text-muted-foreground p-8">You haven't claimed any daily bonuses yet.</p>
                         )}
                    </CardContent>
                </Card>
            </TabsContent>
        </Tabs>
      </div>
    </DashboardLayout>
  );
}
