'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { formatDistanceToNow } from 'date-fns';
import {
  Plus,
  TrendingUp,
  TrendingDown,
  Activity,
  Clock,
  Calendar,
  Target,
  Copy,
  Check,
  Trophy,
  HeartCrack,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Separator } from '@/components/ui/separator';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';

interface AuthData {
  authenticated: boolean;
  token?: string;
  userId?: string;
}

interface Habit {
  id: number;
  name: string;
  type: 'positive' | 'neutral' | 'negative';
  lastLoggedAt: string | null;
  totalLogs: number;
  logsLastWeek: number;
  logsLastMonth: number;
  createdAt: string;
}

interface HabitsResponse {
  habits: Habit[];
}

interface LogResponse {
  log: {
    id: number;
    habitId: number;
    loggedAt: string;
    note?: string;
  };
}

interface HabitResponse {
  habit: Habit;
}

export default function Dashboard() {
  const router = useRouter();
  const queryClient = useQueryClient();
  const [userToken, setUserToken] = useState<string | null>(null);
  const [showNewHabitDialog, setShowNewHabitDialog] = useState(false);
  const [newHabitName, setNewHabitName] = useState('');
  const [newHabitType, setNewHabitType] = useState<'positive' | 'neutral' | 'negative'>('neutral');
  const [copiedToken, setCopiedToken] = useState(false);

  // Check authentication
  const { data: authData, isLoading: authLoading } = useQuery<AuthData>({
    queryKey: ['auth'],
    queryFn: async (): Promise<AuthData> => {
      const res = await fetch('/api/auth');
      const data = (await res.json()) as AuthData;
      if (!data.authenticated) {
        router.push('/');
      }
      return data;
    },
  });

  useEffect(() => {
    if (authData?.token) {
      setUserToken(authData.token);
    }
  }, [authData]);

  // Fetch habits
  const { data: habitsData, isLoading: habitsLoading } = useQuery<HabitsResponse>({
    queryKey: ['habits'],
    queryFn: async (): Promise<HabitsResponse> => {
      const res = await fetch('/api/habits');
      if (!res.ok) throw new Error('Failed to fetch habits');
      return res.json() as Promise<HabitsResponse>;
    },
    enabled: !!authData?.authenticated,
  });

  // Log habit mutation
  const logHabitMutation = useMutation<LogResponse, Error, number>({
    mutationFn: async (habitId: number): Promise<LogResponse> => {
      const res = await fetch(`/api/habits/${String(habitId)}/log`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({}),
      });
      if (!res.ok) throw new Error('Failed to log habit');
      return res.json() as Promise<LogResponse>;
    },
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['habits'] });
    },
  });

  // Create habit mutation
  const createHabitMutation = useMutation<HabitResponse, Error, { name: string; type: string }>({
    mutationFn: async (data: { name: string; type: string }): Promise<HabitResponse> => {
      const res = await fetch('/api/habits', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      });
      if (!res.ok) throw new Error('Failed to create habit');
      return res.json() as Promise<HabitResponse>;
    },
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['habits'] });
      setShowNewHabitDialog(false);
      setNewHabitName('');
      setNewHabitType('neutral');
    },
  });

  const handleCreateHabit = () => {
    if (newHabitName.trim()) {
      createHabitMutation.mutate({
        name: newHabitName.trim(),
        type: newHabitType,
      });
    }
  };

  const copyToken = () => {
    if (userToken) {
      void navigator.clipboard.writeText(userToken);
      setCopiedToken(true);
      setTimeout(() => {
        setCopiedToken(false);
      }, 2000);
    }
  };

  const getHabitCardClass = (type: string) => {
    switch (type) {
      case 'positive':
        return 'border-emerald-600 bg-emerald-950/50 hover:bg-emerald-900/50 hover:border-emerald-500';
      case 'negative':
        return 'border-red-600 bg-red-950/50 hover:bg-red-900/50 hover:border-red-500';
      default:
        return 'border-zinc-700 bg-zinc-950/50 hover:bg-zinc-900/50 hover:border-zinc-600';
    }
  };

  const getHabitIcon = (type: string) => {
    switch (type) {
      case 'positive':
        return <Trophy className="h-5 w-5 text-emerald-500" />;
      case 'negative':
        return <HeartCrack className="h-5 w-5 text-red-500" />;
      default:
        return <Activity className="h-5 w-5 text-zinc-500" />;
    }
  };

  const getHabitBadgeVariant = (type: string): 'default' | 'secondary' | 'destructive' | 'outline' => {
    switch (type) {
      case 'positive':
        return 'default';
      case 'negative':
        return 'destructive';
      default:
        return 'secondary';
    }
  };

  const getAverageFrequency = (habit: Habit) => {
    const daysSinceCreation = Math.max(
      1,
      Math.floor((Date.now() - new Date(habit.createdAt).getTime()) / (1000 * 60 * 60 * 24)),
    );

    if (daysSinceCreation <= 7) {
      const avg = habit.totalLogs / daysSinceCreation;
      return `${avg.toFixed(1)}/day`;
    } else if (daysSinceCreation <= 30) {
      const weeks = daysSinceCreation / 7;
      const avg = habit.totalLogs / weeks;
      return `${avg.toFixed(1)}/week`;
    } else {
      const months = daysSinceCreation / 30;
      const avg = habit.totalLogs / months;
      return `${avg.toFixed(1)}/month`;
    }
  };

  if (authLoading || habitsLoading) {
    return (
      <div className="flex min-h-screen items-center justify-center bg-black">
        <div className="text-zinc-400">Loading...</div>
      </div>
    );
  }

  const habits = habitsData?.habits ?? [];

  return (
    <div className="min-h-screen bg-black">
      <div className="mx-auto max-w-7xl p-4 md:p-8">
        {/* Header */}
        <div className="mb-8">
          <div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
            <div>
              <h1 className="mb-2 text-4xl font-bold text-white">Track Every Day</h1>
              <p className="text-zinc-400">Build better habits, one day at a time.</p>
            </div>
            <Dialog open={showNewHabitDialog} onOpenChange={setShowNewHabitDialog}>
              <DialogTrigger asChild>
                <Button size="lg" className="bg-emerald-600 hover:bg-emerald-700">
                  <Plus className="mr-2 h-5 w-5" />
                  New Habit
                </Button>
              </DialogTrigger>
              <DialogContent className="border-zinc-800 bg-zinc-950">
                <DialogHeader>
                  <DialogTitle>Create New Habit</DialogTitle>
                  <DialogDescription>
                    Add a new habit to track. Choose whether it&apos;s something you want to do more,
                    less, or just monitor.
                  </DialogDescription>
                </DialogHeader>
                <div className="grid gap-4 py-4">
                  <div className="grid gap-2">
                    <Label htmlFor="name">Habit Name</Label>
                    <Input
                      id="name"
                      placeholder="e.g., Exercise, Read, Meditate..."
                      value={newHabitName}
                      onChange={(e) => {
                        setNewHabitName(e.target.value);
                      }}
                      className="border-zinc-800 bg-zinc-900"
                    />
                  </div>
                  <div className="grid gap-2">
                    <Label htmlFor="type">Habit Type</Label>
                    <Select
                      value={newHabitType}
                      onValueChange={(value: 'positive' | 'neutral' | 'negative') => {
                        setNewHabitType(value);
                      }}
                    >
                      <SelectTrigger className="border-zinc-800 bg-zinc-900">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent className="border-zinc-800 bg-zinc-900">
                        <SelectItem value="positive">
                          <div className="flex items-center gap-2">
                            <TrendingUp className="h-4 w-4 text-emerald-500" />
                            <span>Positive - Something to do more</span>
                          </div>
                        </SelectItem>
                        <SelectItem value="neutral">
                          <div className="flex items-center gap-2">
                            <Activity className="h-4 w-4 text-zinc-500" />
                            <span>Neutral - Just tracking</span>
                          </div>
                        </SelectItem>
                        <SelectItem value="negative">
                          <div className="flex items-center gap-2">
                            <TrendingDown className="h-4 w-4 text-red-500" />
                            <span>Negative - Something to reduce</span>
                          </div>
                        </SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                </div>
                <DialogFooter>
                  <Button
                    variant="outline"
                    onClick={() => {
                      setShowNewHabitDialog(false);
                    }}
                  >
                    Cancel
                  </Button>
                  <Button
                    onClick={handleCreateHabit}
                    disabled={!newHabitName.trim() || createHabitMutation.isPending}
                    className="bg-emerald-600 hover:bg-emerald-700"
                  >
                    {createHabitMutation.isPending ? 'Creating...' : 'Create Habit'}
                  </Button>
                </DialogFooter>
              </DialogContent>
            </Dialog>
          </div>

          {/* Token Alert */}
          {userToken && (
            <Alert className="border-zinc-800 bg-zinc-950">
              <AlertDescription className="flex items-center justify-between">
                <div className="space-y-1">
                  <p className="text-sm text-zinc-400">Your access token:</p>
                  <code className="rounded bg-zinc-900 px-2 py-1 font-mono text-sm text-white">
                    {userToken}
                  </code>
                </div>
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button variant="outline" size="sm" onClick={copyToken} className="ml-4">
                        {copiedToken ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>
                      <p>{copiedToken ? 'Copied!' : 'Copy token'}</p>
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
              </AlertDescription>
            </Alert>
          )}
        </div>

        {/* Habits Grid */}
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
          {habits.map((habit: Habit) => (
            <Card
              key={habit.id}
              className={`transform cursor-pointer transition-all duration-200 hover:scale-[1.02] ${getHabitCardClass(
                habit.type,
              )} ${logHabitMutation.isPending ? 'opacity-75' : ''}`}
              onClick={() => {
                logHabitMutation.mutate(habit.id);
              }}
            >
              <CardHeader className="pb-3">
                <div className="flex items-start justify-between">
                  <CardTitle className="text-lg">{habit.name}</CardTitle>
                  {getHabitIcon(habit.type)}
                </div>
              </CardHeader>
              <CardContent>
                <div className="space-y-3">
                  {/* Last logged */}
                  <div className="flex items-center gap-2 text-sm">
                    <Clock className="h-4 w-4 text-zinc-500" />
                    <span className="text-zinc-400">
                      {habit.lastLoggedAt
                        ? formatDistanceToNow(new Date(habit.lastLoggedAt), { addSuffix: true })
                        : 'Never logged'}
                    </span>
                  </div>

                  <Separator className="bg-zinc-800" />

                  {/* Stats */}
                  <div className="grid grid-cols-2 gap-2">
                    <div className="text-center">
                      <p className="text-2xl font-bold">{habit.totalLogs}</p>
                      <p className="text-xs text-zinc-500">Total</p>
                    </div>
                    <div className="text-center">
                      <p className="text-2xl font-bold">{habit.logsLastWeek}</p>
                      <p className="text-xs text-zinc-500">This week</p>
                    </div>
                  </div>

                  {/* Average frequency badge */}
                  <div className="flex justify-center pt-2">
                    <Badge variant={getHabitBadgeVariant(habit.type)} className="font-normal">
                      <Target className="mr-1 h-3 w-3" />
                      {getAverageFrequency(habit)}
                    </Badge>
                  </div>

                  {/* Motivational message */}
                  {habit.type === 'positive' && habit.totalLogs > 0 && (
                    <p className="pt-2 text-center text-xs text-emerald-400">
                      Keep up the great work! 💪
                    </p>
                  )}

                  {habit.type === 'negative' && habit.lastLoggedAt && (
                    <p className="pt-2 text-center text-xs text-red-400">
                      Stay mindful, you&apos;ve got this! 🎯
                    </p>
                  )}
                </div>
              </CardContent>
            </Card>
          ))}

          {/* Empty state */}
          {habits.length === 0 && (
            <Card className="border-dashed border-zinc-800 bg-zinc-950/50 md:col-span-2 lg:col-span-3 xl:col-span-4">
              <CardContent className="flex flex-col items-center justify-center py-12">
                <Calendar className="mb-4 h-12 w-12 text-zinc-600" />
                <h3 className="mb-2 text-lg font-semibold">No habits yet</h3>
                <p className="mb-4 text-sm text-zinc-500">Start building better habits today</p>
                <Button
                  onClick={() => {
                    setShowNewHabitDialog(true);
                  }}
                  className="bg-emerald-600 hover:bg-emerald-700"
                >
                  <Plus className="mr-2 h-4 w-4" />
                  Create Your First Habit
                </Button>
              </CardContent>
            </Card>
          )}
        </div>
      </div>
    </div>
  );
}
