import { api } from "@code/backend/convex/_generated/api";
import type { Id } from "@code/backend/convex/_generated/dataModel";
import { Button } from "@code/ui/components/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@code/ui/components/card";
import { Checkbox } from "@code/ui/components/checkbox";
import { Input } from "@code/ui/components/input";
import { useMutation, useQuery } from "convex/react";
import { Loader2, Trash2 } from "lucide-react";
import { useState } from "react";
import type { FormEvent, ReactNode } from "react";

export default function Todos() {
  const [newTodoText, setNewTodoText] = useState("");

  const todos = useQuery(api.todos.getAll);
  const createTodo = useMutation(api.todos.create);
  const toggleTodo = useMutation(api.todos.toggle);
  const deleteTodo = useMutation(api.todos.deleteTodo);

  const handleAddTodo = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const text = newTodoText.trim();
    if (!text) {
      return;
    }
    await createTodo({ text });
    setNewTodoText("");
  };

  const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
    void toggleTodo({ completed: !currentCompleted, id });
  };

  const handleDeleteTodo = (id: Id<"todos">) => {
    void deleteTodo({ id });
  };

  let todoContent: ReactNode;
  if (todos === undefined) {
    todoContent = (
      <div className="flex justify-center py-4">
        <Loader2 className="h-6 w-6 animate-spin" />
      </div>
    );
  } else if (todos.length === 0) {
    todoContent = (
      <p className="py-4 text-center">No todos yet. Add one above!</p>
    );
  } else {
    todoContent = (
      <ul className="space-y-2">
        {todos.map((todo) => (
          <li
            className="flex items-center justify-between rounded-md border p-2"
            key={todo._id}
          >
            <div className="flex items-center space-x-2">
              <Checkbox
                checked={todo.completed}
                id={`todo-${todo._id}`}
                onCheckedChange={() =>
                  handleToggleTodo(todo._id, todo.completed)
                }
              />
              <label
                className={
                  todo.completed
                    ? "text-muted-foreground line-through"
                    : undefined
                }
                htmlFor={`todo-${todo._id}`}
              >
                {todo.text}
              </label>
            </div>
            <Button
              aria-label="Delete todo"
              onClick={() => handleDeleteTodo(todo._id)}
              size="icon"
              variant="ghost"
            >
              <Trash2 className="h-4 w-4" />
            </Button>
          </li>
        ))}
      </ul>
    );
  }

  return (
    <div className="mx-auto w-full max-w-md py-10">
      <Card>
        <CardHeader>
          <CardTitle>Todo List</CardTitle>
          <CardDescription>Manage your tasks efficiently</CardDescription>
        </CardHeader>
        <CardContent>
          <form
            className="mb-6 flex items-center space-x-2"
            onSubmit={handleAddTodo}
          >
            <Input
              onChange={(event) => setNewTodoText(event.target.value)}
              placeholder="Add a new task..."
              value={newTodoText}
            />
            <Button disabled={!newTodoText.trim()} type="submit">
              Add
            </Button>
          </form>

          {todoContent}
        </CardContent>
      </Card>
    </div>
  );
}
