import {
  deleteFile,
  getAllFilesInProfiles,
  getProfilesData,
  listUserTechnical,
  updateProfileFolder,
  updateProfilesData,
  updateUserTechnical,
} from '@/api/Admin'
import { changePassword } from '@/api/Auth'
import DataTableAll from '@/components/DataTable/DataTable'
import PasswordRequirementInput from '@/components/PasswordRequirementInput/PasswordRequirementInput'
import ProjectInvolvement from '@/components/ProjectInvolvement/ProjectInvolvement'
import { logout } from '@/rtk/dispatches/auth'
import { Xdelete } from '@/rtk/helpers/CRUD'
import { get, post, postImage } from '@/rtk/helpers/apiService'
import { requirementsPassword } from '@/rtk/helpers/variables'
import { useAppDispatch, useAppSelector } from '@/rtk/hooks'
import { getAccessToken, getUser } from '@/rtk/localStorage'
import { success } from '@/rtk/slices/auth'
import {
  Avatar,
  Box,
  Button,
  FileInput,
  Flex,
  Group,
  Loader,
  Modal,
  PasswordInput,
  Stack,
  Text,
  TextInput,
  Title,
} from '@mantine/core'
import { notifications } from '@mantine/notifications'
import {
  IconExchange,
  IconFolder,
  IconPasswordUser,
  IconUserCode,
  IconUserCog,
} from '@tabler/icons-react'
import axios from 'axios'
import moment from 'moment'
import { useCallback, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import classes from './Profile.module.css'

const isCompactMenu = false

type TFileProfile = {
  label: string
  type: string
  value: string
  children?: TFileProfile[]
}
const Profile = () => {
  const user = useAppSelector((state) => state.authentication.user)
  const userData = getUser()

  const [opened, setOpened] = useState(false)
  const [dataChange, setDataChange] = useState({
    password: '',
    new_password: '',
    confirm_password: '',
  })

  const [swapTap, setSwapTab] = useState(false)

  const [avatar, setAvatar] = useState(user.user.avatar)
  const [loading, setLoading] = useState(false)
  const [dataProfile, setDataProfile] = useState<any>([])
  const [countSpam, setCountSpam] = useState(0)

  const [selectedAvatar, setSelectedAvatar] = useState<string | null>(null)
  const navigate = useNavigate()
  const dispatch = useAppDispatch()

  const updateAvatar = async (file: File) => {
    try {
      const res = await postImage(updateProfilesData, file, 'post')
      if (res.status) {
        return res.data
      }
    } catch (error: any) {
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    }
    return []
  }

  const handleAvatarChange = (event: any) => {
    const file = event.target.files[0]
    if (file) {
      setSelectedAvatar(URL.createObjectURL(file)) // Hiển thị ảnh mới đã chọn tạm thời
      const fetchData = async () => {
        const result = await updateAvatar(file)
        notifications.show({
          title: 'Success',
          message: 'Update avatar success',
          color: 'green',
        })
        if (userData) {
          let userObj = JSON.parse(userData)
          userObj.user.avatar = result
          let updatedUserData = JSON.stringify(userObj)
          localStorage.setItem('user', updatedUserData)
          dispatch(success({ user: userObj }))
        }
        //Update avatar
        setAvatar(result ?? [])
      }
      fetchData()
    }
  }
  const passwordRegex =
    /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/

  const getListProfilesData = async () => {
    try {
      const params = {}
      const res = await get(getProfilesData, params)
      if (res.status) {
        return res.data
      }
    } catch (error: any) {
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    }
    return []
  }

  const [cv, setCv] = useState<File>()
  const [idCard, setIdCard] = useState<File>()
  const [transcript, setTranscript] = useState<File>()
  const [universityDiploma, setUniversityDiploma] = useState<File>()
  const [otherFiles, setOtherFiles] = useState([{ file: null, type: '' }])
  const [data, setData] = useState<TFileProfile[]>([])
  const [openedProfile, setOpenedProfile] = useState(false)
  const handleOtherFileChange = (
    index: number,
    field: string,
    value: File | string,
  ) => {
    const updatedFiles: any = [...otherFiles]
    updatedFiles[index][field] = value
    setOtherFiles(updatedFiles)
  }

  const addOtherFileInput = () => {
    setOtherFiles([...otherFiles, { file: null, type: '' }])
  }

  const handleSubmit = async (e: any) => {
    e.preventDefault()
    const formData = new FormData()

    // Append each selected file to FormData
    for (let i = 0; i < otherFiles.length; i++) {
      if (otherFiles[i].file !== null && otherFiles[i].type !== '') {
        formData.append(
          'files[]',
          handleChangeFileName(otherFiles[i].file!, `__${otherFiles[i].type}`)!,
        )
      }
    }

    if (cv) {
      formData.append('files[]', cv)
    }

    if (idCard) {
      formData.append('files[]', idCard)
    }

    if (transcript) {
      formData.append('files[]', transcript)
    }

    if (universityDiploma) {
      formData.append('files[]', universityDiploma)
    }

    const token = await getAccessToken()
    try {
      const response = await axios.post(updateProfileFolder, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          Authorization: `Bearer ${token}`,
        },
      })
      
      if(response.status === 200){
        getAllFile()
        setOtherFiles([])
      }
    } catch (error) {
      console.error('Error uploading files', error)
    }
  }

  const getAllFile = async () => {
    try {
      const res = await get(getAllFilesInProfiles, {
        root_folder: '/storage/profiles/' + JSON.parse(getUser())?.user?.name,
      })
      if (res.status === true) {
        setData(res.data)
      }
    } catch (error) {
      console.log(error)
    }
  }

  const removeFile = async (url: string) => {
    try {
      await Xdelete(deleteFile, {file_url: url}, getAllFile)
    } catch (error) {
      console.log(error)
    }
  }
  useEffect(() => {
    const fetchData = async () => {
      const result = await getListProfilesData()
      setDataProfile(result ?? [])
    }
    fetchData()
    getAllFile()
  }, [])

  const handleChangePassword = async () => {
    try {
      if (countSpam > 5) {
        setLoading(true)
        notifications.show({
          title: 'Error',
          message: 'Password error more than 5 times. Logout after 3s',
          color: 'red',
        })

        setTimeout(() => {
          localStorage.clear()
          window.location.reload()
        }, 3000)
      } else {
        setLoading(true)
        const res = await post(
          changePassword,
          {
            email: user.user.email,
            password: dataChange.password,
            new_password: dataChange.new_password,
            confirm_password: dataChange.confirm_password,
          },
          undefined,
        )

        if (res.status) {
          notifications.show({
            title: 'Success',
            message: 'Reset password success',
            color: 'green',
          })

          setOpened(false)
          setDataChange({
            password: '',
            new_password: '',
            confirm_password: '',
          })
          handleLogout()
        } else {
          notifications.show({
            title: 'Error',
            message: res.errors.password,
            color: 'red',
          })
        }
        setCountSpam(countSpam + 1)
        setLoading(false)
      }

      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (error: any) {
      console.log(error)
      if (error.response.status === 422) {
        const errorMess = error.response.data.message
        notifications.show({
          title: 'Error',
          message: errorMess,
          color: 'red',
        })
      }
      setLoading(false)
    }
  }

  const handleLogout = useCallback(() => {
    dispatch(logout(navigate))
  }, [dispatch, navigate])

  const handleChangeFileName = (e: File, newName: string) => {
    const originalFile = e // Get the original file
    const extend = originalFile.name.split('.')[1]
    if (originalFile) {
      const newFileName = `${newName}.${extend}` // Create new file name
      const newFile = new File([originalFile], newFileName, {
        type: originalFile.type,
      }) // Create new file object

      return newFile // Save the new file object for further processing
    }
  }

  const checkFileExist = (nameField: string) => {
    const file = data.find((f) => f.label.includes(nameField))
    return file
  }

  return (
    <div>
      <div className={classes.title}>
        <h3>
          <Text>Admin/</Text>
          Profile
        </h3>
      </div>

      <Box>
        <Box className={classes.userInfoSection} display="flex">
          <Box className={classes.sidebar}>
            <Title order={3}>User Information</Title>
            <Box
              w={'100%'}
              style={{
                display: 'flex',
                flexFlow: 'column',
                alignItems: 'center',
              }}
            >
              <input
                type="file"
                accept="image/*"
                style={{ display: 'none' }}
                id="avatar-input"
                onChange={handleAvatarChange}
              />
              <Avatar
                src={
                  selectedAvatar
                    ? selectedAvatar
                    : avatar !== ''
                    ? import.meta.env.VITE_BACKEND_URL.includes('local')
                      ? import.meta.env.VITE_BACKEND_URL + 'storage/' + avatar
                      : import.meta.env.VITE_BACKEND_URL +
                        'image/storage/' +
                        avatar
                    : ''
                }
                alt="User Avatar"
                size={150}
                // radius="xl"
                mb={5}
                mt={5}
                onClick={() =>
                  (
                    document.getElementById('avatar-input') as HTMLElement
                  ).click()
                }
                style={{
                  cursor: 'pointer',
                  // border: '2px solid black',
                  borderRadius: '50%',
                }}
              />
            </Box>
            <Box className={classes.userInfo} mt="md">
              <TextInput
                label="Name"
                placeholder="Name"
                mb="md"
                readOnly
                style={{ pointerEvents: 'none' }}
                value={user.user.name}
              />
              <TextInput
                label="Email"
                type="email"
                placeholder="Email"
                mb="md"
                readOnly
                style={{ pointerEvents: 'none' }}
                value={user.user.email}
              />
              <TextInput
                label="Join Date"
                type="text"
                mb="md"
                readOnly
                style={{ pointerEvents: 'none' }}
                value={user.user.createdAt}
              />
              <TextInput
                label="Permission(s)"
                placeholder="Permissions"
                readOnly
                style={{ pointerEvents: 'none' }}
                value={user.user.permission}
              />
            </Box>

            <Box
              w={'100%'}
              style={{
                display: 'flex',
                flexFlow: 'column',
                alignItems: 'center',
                gap: 8,
              }}
              mt={10}
            >
              <Button
                style={{ width: '50%' }}
                onClick={() => setOpened(true)}
                color="green"
              >
                <IconPasswordUser stroke={1.5} />
                Change password
              </Button>

              {swapTap ? (
                <Button
                  style={{ width: '50%' }}
                  onClick={() => setSwapTab(!swapTap)}
                >
                  <IconUserCode stroke={1.5} />
                  Project Involved
                </Button>
              ) : (
                <Button
                  style={{ width: '50%' }}
                  onClick={() => setSwapTab(!swapTap)}
                >
                  <IconUserCog stroke={1.5} />
                  Your Technical
                </Button>
              )}

              <Button
                style={{ width: '50%' }}
                color="orange"
                onClick={() => setOpenedProfile(true)}
              >
                <IconFolder stroke={1.5} />
                Update profile
              </Button>
            </Box>
          </Box>

          {swapTap ? (
            <UserTechnical />
          ) : (
            <Box className={classes.projectInvolvement}>
              <Title order={3}>Project Involved</Title>
              <ProjectInvolvement dataProfile={dataProfile} page="profile" />
            </Box>
          )}
        </Box>

        <Modal
          opened={opened}
          onClose={() => {
            setOpened(false)
            setDataChange({
              password: '',
              new_password: '',
              confirm_password: '',
            })
          }}
          title={
            <Text
              fw={700}
              fz={'1.2rem'}
              className={`${classes.itemLabel} ${
                isCompactMenu ? classes.labelCompactMenu : ''
              }`}
            >
              Change password
            </Text>
          }
        >
          <Box p="sm">
            <TextInput
              label="E-mail"
              value={user.user.email}
              disabled
              mb={'md'}
            ></TextInput>

            <PasswordInput
              label="Current password"
              required
              placeholder="Current password"
              maxLength={32}
              value={dataChange.password}
              onChange={(e) => {
                setDataChange({ ...dataChange, password: e.target.value })
              }}
              error={
                dataChange.password.length < 8 &&
                dataChange.password !== '' &&
                'Length 8 characters or more'
              }
            />

            <PasswordRequirementInput
              requirements={requirementsPassword}
              value={dataChange}
              setValue={setDataChange}
              label="New password"
              placeholder="New password"
              name="new_password"
              mb="md"
            />

            <PasswordInput
              label="Confirm password"
              required
              placeholder="Confirm password"
              maxLength={32}
              value={dataChange.confirm_password}
              onChange={(e) => {
                setDataChange({
                  ...dataChange,
                  confirm_password: e.target.value,
                })
              }}
              error={
                dataChange.new_password !== dataChange.confirm_password &&
                dataChange.confirm_password !== '' &&
                'Password do not match'
              }
            ></PasswordInput>

            <Button
              style={{ float: 'right' }}
              mb={'lg'}
              mt={'lg'}
              loading={loading}
              disabled={
                loading === false &&
                dataChange.password !== '' &&
                passwordRegex.test(dataChange.new_password) &&
                dataChange.new_password === dataChange.confirm_password &&
                dataChange.new_password !== ''
                  ? false
                  : true
              }
              onClick={() => handleChangePassword()}
            >
              Update
            </Button>
          </Box>
        </Modal>

        <Modal
          size={'lg'}
          opened={openedProfile}
          onClose={() => {
            setOpenedProfile(false)
          }}
        >
          <Box>
            <form onSubmit={handleSubmit}>
              <Stack>
                <Box
                  style={{ display: checkFileExist('cv') ? 'flex' : 'none' }}
                >
                  <Text>CV</Text>
                  <a href={checkFileExist('cv')?.value} target="_blank">
                    <Text>{`: ${checkFileExist('cv')?.label}`}</Text>
                  </a>
                  <Button variant="outline" size="xs" color="red" ml={'sm'} onClick={()=>{removeFile(checkFileExist('cv')?.value!)}}>
                    Delete
                  </Button>
                </Box>
                <FileInput
                  label={'CV'}
                  placeholder="Tải lên CV"
                  style={{ display: checkFileExist('cv') ? 'none' : 'block' }}
                  onChange={(e) => {
                    0
                    setCv(handleChangeFileName(e!, 'cv'))
                  }}
                  accept=".pdf,.doc,.docx"
                />
                <Box
                  style={{
                    display: checkFileExist('idCard') ? 'flex' : 'none',
                  }}
                >
                  <Text>CCCD</Text>
                  <a href={checkFileExist('idCard')?.value} target="_blank">
                    <Text>{`: ${checkFileExist('idCard')?.label}`}</Text>
                  </a>
                  <Button variant="outline" size="xs" color="red" ml={'sm'} onClick={()=>{removeFile(checkFileExist('idCard')?.value!)}}>
                    Delete
                  </Button>
                </Box>

                <FileInput
                  label="CCCD"
                  style={{ display: checkFileExist('idCard') ? 'none' : 'block' }}
                  placeholder="Tải lên CCCD"
                  onChange={(e) => {
                    setIdCard(handleChangeFileName(e!, 'idCard'))
                  }}
                  accept=".jpg,.jpeg,.png,.pdf"
                />
                <Box
                  style={{
                    display: checkFileExist('transcript') ? 'flex' : 'none',
                  }}
                >
                  <Text>Bảng điểm</Text>
                  <a href={checkFileExist('transcript')?.value} target="_blank">
                    <Text>{`: ${checkFileExist('transcript')?.label}`}</Text>
                  </a>
                  <Button variant="outline" size="xs" color="red" ml={'sm'} onClick={()=>{removeFile(checkFileExist('transcript')?.value!)}}>
                    Delete
                  </Button>
                </Box>
                <FileInput
                  label="Bảng điểm"
                  style={{ display: checkFileExist('transcript') ? 'none' : 'block' }}
                  placeholder="Tải lên bảng điểm"
                  onChange={(e) => {
                    setTranscript(handleChangeFileName(e!, 'transcript'))
                  }}
                  accept=".pdf"
                />

                <Box
                  style={{
                    display: checkFileExist('universityDiploma')
                      ? 'flex'
                      : 'none',
                  }}
                >
                  <Text>Bằng đại học</Text>
                  <a
                    href={checkFileExist('universityDiploma')?.value}
                    target="_blank"
                  >
                    <Text>{`: ${
                      checkFileExist('universityDiploma')?.label
                    }`}</Text>
                  </a>
                  <Button variant="outline" size="xs" color="red" ml={'sm'} onClick={()=>{removeFile(checkFileExist('universityDiploma')?.value!)}}>
                    Delete
                  </Button>
                </Box>
                <FileInput
                  label="Bằng đại học"
                  style={{ display: checkFileExist('universityDiploma') ? 'none' : 'block' }}
                  placeholder="Tải lên bằng đại học"
                  onChange={(e) => {
                    setUniversityDiploma(
                      handleChangeFileName(e!, 'universityDiploma'),
                    )
                  }}
                  accept=".pdf,.jpg,.jpeg,.png"
                />

                <Text>Danh sách file khác:</Text>
                  <Box>
                    {data.find((f)=>f.label === 'others')?.children?.map((c, index)=>{
                      return <Box key={index}
                      style={{
                        display: 'flex',
                        marginBottom:'5px'
                      }}
                    >
                      <a
                        href={c?.value}
                        target="_blank"
                      >
                        <Text>{`${
                          c?.label
                        }`}</Text>
                      </a>
                      <Button variant="outline" size="xs" color="red" ml={'sm'} onClick={()=>{removeFile(c?.value!)}}>
                        Delete
                      </Button>
                    </Box>
                    })}
                  </Box>
                {otherFiles.map((fileInput, index) => (
                  <Group key={index}>
                    <FileInput
                      placeholder="Chọn file"
                      onChange={(file) =>
                        handleOtherFileChange(index, 'file', file!)
                      }
                      w={'30%'}
                    />
                    <TextInput
                      placeholder="Nhập tên file (không cần phần mở rộng)"
                      value={fileInput.type}
                      w={'65%'}
                      onChange={(e) =>
                        handleOtherFileChange(
                          index,
                          'type',
                          e.currentTarget.value,
                        )
                      }
                    />
                  </Group>
                ))}
                <Button type="button" onClick={addOtherFileInput}>
                  Thêm file khác
                </Button>

                <Button type="submit" color="blue">
                  Save
                </Button>
              </Stack>
            </form>
          </Box>
        </Modal>
      </Box>
    </div>
  )
}

// User Technical
interface DataTechnical {
  id: number
  name: string
  level: number
  point: number
  updated_at: string
}

interface UpdateDataTechnical {
  technical_id: number | string
  point: number | string
}

const UserTechnical = () => {
  const [dataTechnical, setDataTechnical] = useState<DataTechnical[]>([])
  const [loadingTechnical, setLoadingTechnical] = useState(false)
  const [isUpdateTechnical, setIsUpdateTechnical] = useState<
    string[] | number[]
  >([])
  const [updatedDataTechnical, setUpdatedDataTechnical] = useState<
    UpdateDataTechnical[]
  >([])

  useEffect(() => {
    const fetchData = async () => {
      await getListUserTechnical()
    }
    fetchData()
  }, [])

  const columns = [
    {
      name: 'level',
      size: '5%',
      header: 'Level',
      render: (row: any) => {
        return (
          <Box
            style={
              row?.level
                ? row?.level === 1
                  ? { backgroundColor: '#d9d2e9' }
                  : row?.level === 2
                  ? { backgroundColor: '#ffd966' }
                  : { backgroundColor: '#cfe2f3' }
                : { backgroundColor: '' }
            }
            fw={500}
            ta="center"
            p={4}
          >
            {row?.level ? row.level : ''}
          </Box>
        )
      },
    },
    {
      name: 'name',
      size: '45%',
      header: 'Name',
      render: (row: any) => {
        return <Text ta="start">{row?.name}</Text>
      },
    },
    {
      name: 'point',
      size: '10%',
      header: 'Point',
      render: (row: any) => {
        return (
          <TextInput
            mb={'md'}
            value={
              updatedDataTechnical.find(
                (technicalItem: UpdateDataTechnical) =>
                  technicalItem.technical_id === row?.id,
              )?.point
            }
            rightSection={
              isUpdateTechnical.some(
                (item: string | number) => item === row.id,
              ) ? (
                <IconExchange size={16} color="#1c7ed6" />
              ) : (
                ''
              )
            }
            onChange={(e) => {
              const value = e.target.value

              // Ensure the input is between 0 and 3
              if (value === '' || (Number(value) >= 0 && Number(value) <= 3)) {
                setUpdatedDataTechnical((prev: any) =>
                  prev.map((technicalItem: UpdateDataTechnical) => {
                    if (technicalItem.technical_id === row.id) {
                      return {
                        ...technicalItem,
                        point: value,
                      }
                    }
                    return technicalItem
                  }),
                )
                setIsUpdateTechnical((prev) => [...prev, row?.id])
              }
            }}
            onFocus={(e) => e.target.select()}
          />
        )
      },
    },
    {
      name: 'updated_at',
      size: '40%',
      header: 'Last update',
      render: (row: any) => {
        if (row?.updated_at) {
          return (
            <Text ta="start">
              {moment(row?.updated_at).format('HH:mm:ss DD/MM/YYYY')}
            </Text>
          )
        }
      },
    },
  ]

  const getListUserTechnical = async () => {
    try {
      setLoadingTechnical(true)
      const params = {}
      const res = await get(listUserTechnical, params)
      if (res.status) {
        setDataTechnical(res.data)
        setUpdatedDataTechnical(
          res.data?.map((technicalItem: DataTechnical) => {
            return {
              technical_id: technicalItem.id,
              point: technicalItem.point,
            }
          }),
        )
      }
    } catch (error: any) {
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    } finally {
      setLoadingTechnical(false)
    }

    return []
  }

  const handleUpdateUserTechnical = async () => {
    try {
      const res = await post(updateUserTechnical, {
        technicals: updatedDataTechnical,
      })
      if (res.status === true) {
        await getListUserTechnical()

        notifications.show({
          title: 'Success',
          message: res.message,
          color: 'green',
        })
      }
    } catch (error) {
      console.log(error)
    }
  }

  return (
    <Box className={classes.projectInvolvement}>
      <Flex justify="space-between" wrap="wrap">
        {/* Level */}
        <Box px={16} ta="start">
          <Text fw={500}>Level: </Text>

          <Flex gap={8} wrap="wrap">
            <Box p={8} bg="#d9d2e9">
              <span style={{ fontWeight: 500 }}>1:</span> 3-12 Month
            </Box>
            <Box p={8} bg="#ffd966">
              <span style={{ fontWeight: 500 }}>2:</span> 3-5 Year
            </Box>
            <Box p={8} bg="#cfe2f3">
              <span style={{ fontWeight: 500 }}>3:</span> 5 -8 Year
            </Box>
          </Flex>
        </Box>

        {/* Point */}
        <Box px={16} ta="start" mt={{ base: 8, lg: 0 }}>
          <Text fw={500}>Point: </Text>

          <Flex gap={8} wrap="wrap">
            <Box p={8} bg="#FFEA00">
              <span style={{ fontWeight: 500 }}>0:</span> Unknown
            </Box>
            <Box p={8} bg="#FFEA00">
              <span style={{ fontWeight: 500 }}>1:</span> Basic
            </Box>
            <Box p={8} bg="#FFEA00">
              <span style={{ fontWeight: 500 }}>2:</span> Advanced
            </Box>
            <Box p={8} bg="#FFEA00">
              <span style={{ fontWeight: 500 }}>3:</span> Master
            </Box>
          </Flex>
        </Box>
      </Flex>

      <Flex justify="space-between" mt={'lg'}>
        <div></div>
        <Title order={3}>Technicals</Title>

        <Button
          disabled={loadingTechnical || isUpdateTechnical.length === 0}
          onClick={handleUpdateUserTechnical}
        >
          Update
        </Button>
      </Flex>

      {loadingTechnical ? (
        <Box
          style={{
            width: '100%',
            marginTop: '10%',
            textAlign: 'center',
            display: 'block',
          }}
        >
          <Loader size={'sm'} color="green" type="bars" m={'0 auto'} />
          <Text fw={600} c={'gray'} mt={8}>
            Loading Technical...
          </Text>
        </Box>
      ) : (
        <DataTableAll
          data={dataTechnical}
          columns={columns}
          size=""
          searchInput
        />
      )}
    </Box>
  )
}

export default Profile
