"use client";

import { ChangeEvent, FormEvent, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import TodoItem from "./TodoItem";

type Todo = {
  id: string;
  text: string;
  completed: boolean;
};

const Todo = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [input, setInput] = useState<string>("");

  const handleInput = (e: ChangeEvent<HTMLInputElement>) => {
    setInput(e.target.value);
  };

  const handleAdd = () => {
    const trimmedInput = input.trim();

    if (trimmedInput) {
      const isDuplicate = todos.some(
        (todo) => todo.text.toLowerCase() === trimmedInput.toLowerCase()
      );

      if (isDuplicate) {
        alert("Item already exist!");
        setInput("");
        return;
      }

      const newTodo: Todo = {
        id: uuidv4(),
        text: trimmedInput,
        completed: false,
      };

      setTodos((todos) => [...todos, newTodo]);
      setInput("");
    }
  };

  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    handleAdd();
  };

  const handleDelete = (id: string) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  const handleToggle = (id: string) => {
    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    );
  };

  const handleEdit = (id: string, newText: string) => {
    const trimmedInput = newText.trim();

    const isDuplicate = todos.some(
      (todo) =>
        todo.text.toLowerCase() === trimmedInput.toLowerCase() && todo.id !== id
    );

    if (isDuplicate) {
      alert("This item already in the todos!");
      return;
    }

    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, text: trimmedInput } : todo
      )
    );
  };

  const handleClear = () => {
    setTodos([]);
  };

  return (
    <div className="m-4 text-center">
      <h1 className="m-4 text-6xl">Todo</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          placeholder="Enter Todos!"
          value={input}
          onChange={handleInput}
          className="m-1 px-2 py-1 text-2xl border-2 rounded-md"
        />
        <button
          type="submit"
          className="m-2 px-2 py-1 text-2xl border-2 rounded-md bg-blue-500 hover:bg-blue-700 text-white font-medium"
        >
          Add
        </button>
      </form>
      <div>
        <h1 className="m-2 text-3xl">
          {todos.length > 0 ? "Todos are below!" : "List is empty, add todos!"}
        </h1>
        {todos.length > 0 && (
          <>
            <ul>
              {todos.map((todo, index) => (
                <li key={todo.id}>
                  <TodoItem
                    todo={todo}
                    index={index}
                    onDelete={handleDelete}
                    onToggle={handleToggle}
                    onEdit={handleEdit}
                  />
                </li>
              ))}
            </ul>
            <button
              onClick={handleClear}
              className="m-2 px-2 py-1 text-2xl border-2 rounded-md bg-red-500 hover:bg-red-700 text-white font-medium"
            >
              Clear
            </button>
          </>
        )}
      </div>
    </div>
  );
};

export default Todo;

import { ChangeEvent, KeyboardEvent, useState } from "react";

type Todo = {
  id: string;
  text: string;
  completed: boolean;
};

type TodoItemProps = {
  todo: Todo;
  index: number;
  onDelete: (id: string) => void;
  onToggle: (id: string) => void;
  onEdit: (id: string, newText: string) => void;
};

const TodoItem = ({
  todo,
  index,
  onDelete,
  onToggle,
  onEdit,
}: TodoItemProps) => {
  const [isEditing, setIsEditing] = useState(false);
  const [newText, setNewText] = useState(todo.text);

  const handleEditChange = (e: ChangeEvent<HTMLInputElement>) => {
    setNewText(e.target.value);
  };

  const handleEditSubmit = () => {
    const trimmedInput = newText.trim();

    if (trimmedInput === "") {
      alert("Todo cannot be empty!");
      return;
    }

    onEdit(todo.id, trimmedInput);
    setIsEditing(false);
  };

  const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      handleEditSubmit();
    }
  };

  return (
    <div className="flex justify-between w-1/2 m-auto">
      <span className="flex m-1 items-center">
        <input
          type="checkbox"
          checked={todo.completed}
          onChange={() => onToggle(todo.id)}
          className={`m-1 scale-150 cursor-pointer appearance-none w-4 h-4 rounded-xs ${
            todo.completed ? "bg-blue-500" : "bg-gray-400"
          } checked:appearance-auto checked:accent-blue-500`}
        />
        {isEditing ? (
          <input
            type="text"
            placeholder="Enter new todo!"
            value={newText}
            onChange={handleEditChange}
            onKeyDown={handleKeyDown}
            className="m-1 px-2 py-1 text-2xl border-2 rounded-md"
          />
        ) : (
          <h1
            onClick={() => onToggle(todo.id)}
            className={`m-1 text-2xl cursor-pointer ${
              todo.completed ? "line-through text-gray-400" : ""
            }`}
          >
            {index + 1}.{" "}
            {todo.text[0].toUpperCase() + todo.text.slice(1).toLowerCase()}
          </h1>
        )}
      </span>
      <span>
        {isEditing ? (
          <button onClick={handleEditSubmit}>Save</button>
        ) : (
          <button
            onClick={() => setIsEditing(true)}
            className="m-1 px-2 py-1 text-2xl cursor-pointer text-blue-500 hover:text-blue-700"
          >
            Edit
          </button>
        )}
        <button
          onClick={() => onDelete(todo.id)}
          className="m-1 px-2 py-1 text-2xl cursor-pointer text-red-500 hover:text-red-700"
        >
          Delete
        </button>
      </span>
    </div>
  );
};

export default TodoItem;

//this is working fine even I haven't used use-client in TodoItem compoenet?