"use client";

import { User } from "@/api/gen/idb/user/v1/user_pb";
import { ChangeEventHandler, FormEventHandler, MouseEventHandler, useEffect, useState } from "react";
import {
  RequestBody as VerifyRequestBody,
  ResponseBody as VerifyResponseBody,
} from "@/app/api/new-user/verify-username/types";
import {
  RequestBody as SubmitRequestBody,
  ResponseBody as SubmitResponseBody,
} from "@/app/api/new-user/add-ibd-creds/types";

import styles from "./styles.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSpinner } from "@fortawesome/free-solid-svg-icons";

export default function NewUserForm() {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [isUsernameValid, setIsUsernameValid] = useState(false);
  const [isSubmittingUsername, setIsSubmittingUsername] = useState(false);
  const [isSubmittingForm, setIsSubmittingForm] = useState(false);
  const [isCheckingCreds, setIsCheckingCreds] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleUsernameSubmit: FormEventHandler<HTMLFormElement> = (e) => {
    e.preventDefault();
    setIsSubmittingUsername(true);
    setError(null);

    const body: VerifyRequestBody = { username };
    fetch("/api/new-user/verify-username", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    }).then((res) => res.json())
      .then((data) => {
        const { exists } = VerifyResponseBody.parse(data);
        if (exists) {
          setIsUsernameValid(true);
        } else {
          setError("Username does not exist");
        }
        setIsSubmittingUsername(false);
      });
  };
  const handleFormSubmit: FormEventHandler<HTMLFormElement> = (e) => {
    e.preventDefault();
    setIsSubmittingForm(true);
    setError(null);

    const body: SubmitRequestBody = { username, password };
    fetch("/api/new-user/add-ibd-creds", {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    }).then((res) => res.json())
      .then((data) => {
        const {} = SubmitResponseBody.parse(data);
        setIsSubmittingForm(false);
        setIsCheckingCreds(true);

        return fetch("/api/new-user/check-ibd-creds", {
          method: "PUT",
        });
      })
      .then((res) => {
        if (res.status === 200) {
          window.location.href = "/dashboard";
        } else {
          setError("Invalid credentials");
          setIsCheckingCreds(false);
        }
      });
  };

  const handleBack: MouseEventHandler<HTMLButtonElement> = () => {
    setIsUsernameValid(false);
    setPassword("");
    setError(null);
  };

  return (
    <div className="flex items-center justify-center min-h-screen bg-gray-100">
      <div className="w-full max-w-md p-8 space-y-4 bg-white rounded-lg shadow-lg">
        <h1 className="text-2xl font-bold text-center">Set Up Your Account</h1>

        <form onSubmit={isUsernameValid ? handleFormSubmit : handleUsernameSubmit}>
          <div className="mb-4">
            <label htmlFor="username" className="block text-sm font-medium text-gray-700">
              Username
            </label>
            <input
              type="text"
              id="username"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              className={`w-full px-3 py-2 mt-1 border ${
                isUsernameValid ? "border-gray-300 bg-gray-200" : "border-gray-300"
              } rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500`}
              required
              disabled={isUsernameValid}
            />
            {error && !isUsernameValid && (
              <p className="mt-2 text-sm text-red-600">{error}</p>
            )}
          </div>
          {!isUsernameValid && (
            <div className="flex justify-center">
              <button
                type="submit"
                className="px-4 py-2 text-white bg-indigo-600 rounded-md shadow-sm hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                disabled={isSubmittingUsername}
              >
                {isSubmittingUsername ? <FontAwesomeIcon icon={faSpinner} spin /> : "Next"}
              </button>
            </div>
          )}
        </form>

        {isUsernameValid && (
          <form onSubmit={handleFormSubmit}>
            <div className={styles.passwordForm}>
              <div className="mb-4">
                <label htmlFor="password" className="block text-sm font-medium text-gray-700">
                  Password
                </label>
                <input
                  type="password"
                  id="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  className="w-full px-3 py-2 mt-1 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
                  required
                />
              </div>
              {error && isUsernameValid && (
                <p className="mt-2 text-sm text-red-600">{error}</p>
              )}
              <div className="flex justify-between">
                <button
                  type="button"
                  onClick={handleBack}
                  className="px-4 py-2 text-white bg-gray-600 rounded-md shadow-sm hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2"
                >
                  Back
                </button>
                <button
                  type="submit"
                  className="px-4 py-2 text-white bg-indigo-600 rounded-md shadow-sm hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                  disabled={isSubmittingForm}
                >
                  {isSubmittingForm ? (
                    <p><FontAwesomeIcon icon={faSpinner} spin /> Setting Credentials...</p>
                  ) : isCheckingCreds ? (
                    <p><FontAwesomeIcon icon={faSpinner} spin /> Checking Credentials...</p>
                  ) : "Submit"}
                </button>
              </div>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}
