import { useState } from "react"
import { Button } from "../../ui-component/button/button.component"
import { Input } from "../../ui-component/input/input.component"
import styles from "./user-sign-up.styles.module.css"
import { DropdownItems } from "../../ui-component/dropdown/dropdown.component"
import { countryList } from "./country.dictionary"
import { Icon } from "../../ui-component/icon/icon.component"
import { Checkbox } from "../../ui-component/checkbox/checkbox.component"
import { Welcome } from "./welcome.component"
import { useModal } from "../../ui-component/modal"
import { CurrentUserType } from "../../types/user.type"
import { Config } from "../../utils/config"

type FormData = {
  name: string
  email: string
  selectedSkills: string[]
  selectedCountry: string | null
  password: string
  confirmPassword: string
  agreeToTerms: boolean
}

type Errors = Partial<Record<keyof FormData, string>>

export function UserSignUpEngineer({
  goBack,
}: {
  goBack: (value: string) => void
}) {
  // ---------------------------------------------------------------------------
  // states
  // ---------------------------------------------------------------------------
  const modal = useModal()
  const [mode, setMode] = useState<
    "initial" | "country" | "skill" | "password"
  >("initial")
  const [formData, setFormData] = useState<FormData>({
    name: "",
    email: "",
    selectedSkills: [],
    selectedCountry: null,
    password: "",
    confirmPassword: "",
    agreeToTerms: false,
  })
  const [errors, setErrors] = useState<Errors>({})
  const [showPassword, setShowPassword] = useState(false)
  const [showRepeatPassword, setShowRepeatPassword] = useState(false)

  const skills = [
    "Python",
    "Javascript",
    "C++",
    "Java",
    "C#",
    "Node.js",
    "Vue.js",
    "Django",
    ".NET",
    "React",
    "Flutter",
    "Kotlin",
    "Swift",
    "HTML",
    "CSS",
    "AWS",
    "Azure",
    "GCP",
  ]

  // ---------------------------------------------------------------------------
  // effects
  // ---------------------------------------------------------------------------

  // ---------------------------------------------------------------------------
  // functions
  // ---------------------------------------------------------------------------

  function onBack(step: string) {
    if (step === "initial") {
      goBack(mode)
    } else if (step === "country") {
      setMode("initial")
    } else if (step === "skill") {
      setMode("country")
    } else {
      setMode("skill")
    }
  }

  const getUnderlineColor = (index: number) => {
    if (mode === "initial") {
      return index === 1 ? "#5807C9" : "#E9D5FC"
    } else if (mode === "country") {
      return index === 2 ? "#5807C9" : "#E9D5FC"
    } else if (mode === "skill") {
      return index === 3 ? "#5807C9" : "#E9D5FC"
    } else if (mode === "password") {
      return index === 4 ? "#5807C9" : "#E9D5FC"
    }
  }

  const handleSignUp = async () => {
    if (validate()) {
      const userData = {
        name: formData.name,
        email: formData.email,
        country: formData.selectedCountry,
        skills: formData.selectedSkills,
        password: formData.password,
        role: "engineer",
        url: null,
        phone: null,
        position: null,
        contact_person: null,
      }

      try {
        const response = await fetch(`${Config.url}/api/auth/register`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(userData),
          credentials: "include",
        })

        if (response.ok) {
          const result: CurrentUserType = await response.json()
          localStorage.setItem("currentUser", JSON.stringify(result))

          modal.open({
            component: <Welcome />,
            width: "80rem",
          })
        } else {
          const error = await response.json()
          alert(error.message || "Something went wrong!")
        }
      } catch (error) {
        alert("Network error. Please try again.")
      }
    }
  }

  async function checkEmail() {
    if (validate()) {
      const userData = {
        email: formData.email,
      }

      try {
        const response = await fetch(`${Config.url}/api/auth/checkEmail`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(userData),
          credentials: "include",
        })

        if (!response.ok) {
          alert("Login is already exist")
          return
        } else {
          const error = await response.json()
          alert(error.message || "Something went wrong!")
        }
        handleNext()
      } catch (error) {
        alert("Network error. Please try again.")
      }
    }
  }

  const validate = async () => {
    let newErrors: Errors = {}

    if (mode === "initial") {
      if (!formData.name) newErrors.name = "Incorrect input"
      if (formData.name.length > 50)
        newErrors.name = "The name must be at least 50 characters"
      if (!formData.email || formData.email.length > 100)
        if (!formData.email) newErrors.email = "Email is required"
      if (!/\S+@\S+.\S+/.test(formData.email))
        newErrors.email = "Email address is invalid"

      if (checkEmail()) newErrors.email = "Email already exists"
    } else if (mode === "country") {
      if (!formData.selectedCountry)
        newErrors.selectedCountry = "The country is required"
    } else if (mode === "skill") {
      if (!formData.selectedSkills)
        newErrors.selectedSkills = "Skills is required"
    } else if (mode === "password") {
      if (!formData.password) newErrors.password = "Password is required"
      if (formData.password.length < 6)
        newErrors.password = "Password must be at least 6 characters"
      if (formData.password !== formData.confirmPassword)
        newErrors.confirmPassword = "Passwords do not match"
      if (!formData.agreeToTerms)
        newErrors.agreeToTerms = "You must agree to the terms"
    }

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleNext = () => {
    if (validate()) {
      if (mode === "initial") setMode("country")
      else if (mode === "country") setMode("skill")
      else if (mode === "skill") setMode("password")
      else if (mode === "password") {
        modal.open({
          component: <Welcome isCompany={true} />,
          width: "80rem",
        })
      }
    }
  }

  const handleValueChange = (
    field: keyof FormData,
    value: string | boolean,
  ) => {
    setFormData({ ...formData, [field]: value })
  }

  // ---------------------------------------------------------------------------
  return (
    <>
      <div className={styles.backIconWrap} onClick={() => onBack(mode)}>
        <Icon
          name="fal fa-chevron-left"
          className={styles.backIcon}
          size="auto"
        />
        <p className={styles.backIconText}>Back</p>
      </div>
      {/* --------------------------------------------------------------------------- */}
      {/* NAME AND EMAIL  */}
      {/* --------------------------------------------------------------------------- */}
      <div className={styles.titleUnderlineWrap}>
        {[...Array(5)].map((_, index) => (
          <div
            key={index}
            className={styles.titleUnderline}
            style={{
              backgroundColor: getUnderlineColor(index),
            }}
          />
        ))}
      </div>
      {mode === "initial" && (
        <div className={styles.nameAndUrlWrap}>
          <div className={styles.input} style={{ gap: errors.name ? 0 : 0 }}>
            <Input
              mode="primary"
              placeholder="Name"
              buttonClicked={errors.name}
              value={formData.name}
              onValueChange={(value) => handleValueChange("name", value)}
            />
            {errors.name && <span className={styles.error}>{errors.name}</span>}
            <Input
              mode="primary"
              type="email"
              buttonClicked={errors.email}
              placeholder="Email"
              value={formData.email}
              onValueChange={(value) => handleValueChange("email", value)}
            />
            {errors.email && (
              <span className={styles.error}>{errors.email}</span>
            )}
          </div>
          <Button
            className={styles.nextButton}
            disabled={formData.name === "" || formData.email === ""}
            onClick={checkEmail}
          >
            Next
          </Button>
        </div>
      )}

      {/* --------------------------------------------------------------------------- */}
      {/* SELECT COUNTRY  */}
      {/* --------------------------------------------------------------------------- */}

      {mode === "country" && (
        <>
          <div className={styles.countryWrap}>
            <div style={{ margin: "-0.9rem 0" }}>
              <DropdownItems
                key={countryList.length}
                menuClassName={styles.menu}
                checkboxes={false}
                items={countryList}
                mode="secondary"
                itemRender={(country) => (
                  <span key={country.length} className={styles.menuItem}>
                    {country}
                  </span>
                )}
                checked={(country) =>
                  !!formData.selectedCountry &&
                  formData.selectedCountry === country
                }
                onChange={(value) =>
                  handleValueChange("selectedCountry", value)
                }
                placeholder={"Country"}
              />
              {errors.selectedCountry && (
                <span className={styles.error}>{errors.selectedCountry}</span>
              )}
            </div>
            <Button className={styles.nextButton} onClick={handleNext}>
              Next
            </Button>
          </div>
        </>
      )}

      {/* --------------------------------------------------------------------------- */}
      {/* SKILL  */}
      {/* --------------------------------------------------------------------------- */}

      {mode === "skill" && (
        <div className={styles.skillWrap}>
          <h5 className={styles.chooseSkillText}>Choose skills</h5>
          <div className={styles.skillCardWrap}>
            {skills.map((skill, index) => (
              <span
                key={index}
                className={`${styles.skillCard} ${formData.selectedSkills.includes(skill) ? styles.active : ""}`}
                onClick={() => {
                  setFormData((prev) => ({
                    ...prev,
                    selectedSkills: prev.selectedSkills.includes(skill)
                      ? prev.selectedSkills.filter((s) => s !== skill)
                      : [...prev.selectedSkills, skill],
                  }))
                }}
              >
                {skill}
              </span>
            ))}
            {errors.selectedSkills && (
              <span className={styles.error}>you must choose at least one</span>
            )}
          </div>
          <div className={styles.skillBtn}>
            <Button
              className={styles.nextButton}
              style={{ maxWidth: "40rem" }}
              disabled={formData.selectedSkills.length === 0}
              onClick={handleNext}
            >
              Next
            </Button>
          </div>
        </div>
      )}

      {/* --------------------------------------------------------------------------- */}
      {/* PASSWORD */}
      {/* --------------------------------------------------------------------------- */}

      {mode === "password" && (
        <div className={styles.instructionsWrap}>
          <div
            className={styles.input}
            style={{ gap: errors.password ? 0 : "1.2rem" }}
          >
            <Input
              mode="primary"
              type={showPassword ? "text" : "password"}
              placeholder="Create a password"
              iconRight={
                showPassword ? "fa-light fa-eye" : "fa-light fa-eye-slash"
              }
              onIconClick={() => setShowPassword(!showPassword)}
              value={formData.password}
              autofocus={true}
              buttonClicked={errors.password}
              onValueChange={(value) => handleValueChange("password", value)}
            />
            <span className={styles.error}>{errors.password}</span>
            <Input
              mode="primary"
              type={showRepeatPassword ? "text" : "password"}
              iconRight={
                showRepeatPassword ? "fal fa-eye" : "fa-light fa-eye-slash"
              }
              onIconClick={() => setShowRepeatPassword(!showRepeatPassword)}
              placeholder="Repeat password"
              value={formData.confirmPassword}
              buttonClicked={errors.confirmPassword}
              autofocus={true}
              onValueChange={(value) =>
                handleValueChange("confirmPassword", value)
              }
            />
            <span className={styles.error}>{errors.confirmPassword}</span>
          </div>
          <Button
            className={styles.nextButton}
            onClick={handleSignUp}
            disabled={
              formData.password === "" ||
              formData.confirmPassword === "" ||
              !formData.agreeToTerms
            }
          >
            Done
          </Button>
          <div
            className={styles.term}
            onClick={() =>
              setFormData((prev) => ({
                ...prev,
                agreeToTerms: !prev.agreeToTerms,
              }))
            }
          >
            <Checkbox checked={formData.agreeToTerms} color="#07C96C" />
            <span>
              I agree to the processing of personal data in accordance with the
              <span className={styles.privacy}>privacy policy</span>
            </span>
          </div>
        </div>
      )}
    </>
  )
}
if (checkEmail()) newErrors.email = "Email already exists" - This condition will always return true since this 'Promise<void>' is always defined.ts(2801)