import {
  getAllBoardByIdProject,
  getAllCriteriasBySprint,
  getAllProject,
  getAllSprintByIdBoard,
  updateSprintReview,
} from '@/api/Admin'
import { get } from '@/rtk/helpers/apiService'
import { update } from '@/rtk/helpers/CRUD'
import {
  Box,
  Button,
  Dialog,
  Group,
  Loader,
  Select,
  Table,
  Text,
  Textarea,
  TextInput,
  Title,
  Tooltip,
} from '@mantine/core'
import { notifications } from '@mantine/notifications'
import { useEffect, useState } from 'react'
import classes from './SprintReview.module.css'

type DataProject = {
  id: number
  name: string
}
type DataSprint = {
  id: number
  name: string

  startDate?: string
  endDate?: string
  completeDate?: string
}

type DataCriteriaSprint = {
  [key: string]: string
  // id?: number
  // name: string
  // expect: string
  // actual: string
  // note: string
  // point?: string
}

interface DataCriteriaUsers {
  [key: string]: string
}
// type DataCriteriaUsers = {
//   id?: number
//   name: string
//   user: string
//   created_by: string
//   note: string
//   point?: string
// }

const SprintReview = () => {
  // const [users, setUsers] = useState<TUser[]>([])
  const [action, setAction] = useState('')
  // const [info, setInfo] = useState('')
  const [activeBtn, setActiveBtn] = useState(false)
  const [loading, setLoading] = useState(false)
  const [loadingProject, setLoadingProject] = useState(true)
  const [isDisabledSprint, setIsDisabledSprint] = useState(true)
  const [criteriaSprint, setCriteriaSprint] = useState<DataCriteriaSprint[]>([])
  const [criteriaUsers, setCriteriaUsers] = useState<DataCriteriaUsers[]>([])
  const [infoBoard, setInfoBoard] = useState('')
  const [filter, setFilter] = useState({
    project: '',
    sprint: '',
  })
  const [dataProject, setDataProject] = useState<DataProject[]>([])
  const [dataSprint, setDataSprint] = useState<DataSprint[]>([])
  const [finalPoint, setFinalPoint] = useState('')
  const getListDataProject = async () => {
    try {
      const params = {}
      const res = await get(getAllProject, params)
      if (res.status) {
        return res.data
      }
    } catch (error: any) {
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    }
    return []
  }

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

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

  const getListCriteriasBySprint = async (id: string) => {
    try {
      const params = {}
      const res = await get(`${getAllCriteriasBySprint}/${id}`, params)
      if (res.status) {
        return res.data
      }
    } catch (error: any) {
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    }
    return []
  }

  useEffect(() => {
    const fetchData = async () => {
      const result = await getListDataProject()
      setDataProject(result ?? [])
      setLoadingProject(false)
    }
    fetchData()
  }, [])

  useEffect(() => {
    if (filter.project) {
      setLoading(true)
      const fetchData = async () => {
        const result = await getBoardByIdProject(filter.project)
        if (result.values[0]) {
          setInfoBoard(result.values[0].id ?? '')
          setLoading(false)
        }
      }
      fetchData()
    } else {
      setIsDisabledSprint(true)
      setDataSprint([])
    }
  }, [filter.project])

  useEffect(() => {
    if (infoBoard != '') {
      const fetchData = async () => {
        const result = await getListDataSprint(infoBoard)
        if (result.values) {
          setDataSprint(
            result.values.filter(
              (item: any) =>
                typeof item.completeDate !== 'undefined' &&
                item.completeDate !== '',
            ) ?? [],
          )
          setIsDisabledSprint(false)
        }
      }
      fetchData()
    }
  }, [infoBoard])

  useEffect(() => {
    setLoading(true)
    setCriteriaSprint([])
    setCriteriaUsers([])
    if (filter.sprint) {
      const fetchData = async () => {
        const result = await getListCriteriasBySprint(filter.sprint)
        if (result) {
          setCriteriaSprint(result.criterias ?? [])
          setCriteriaUsers(result.users ?? [])
          setFinalPoint(result.point ?? '')
          setLoading(false)
        }
      }
      fetchData()
    } else {
      setLoading(false)
    }
  }, [filter])

  const getAll = () => {
    const fetchData = async () => {
      const result = await getListCriteriasBySprint(filter.sprint)
      if (result) {
        setCriteriaSprint(result.criterias ?? [])
        setCriteriaUsers(result.users ?? [])
        setFinalPoint(result.point ?? '')
        setLoading(false)
      }
    }
    fetchData()
  }

  const handleUpdate = async () => {
    const dataSprintSearch = dataSprint.find(
      (item: DataSprint) => item.id == Number(filter.sprint),
    )

    const values = {
      name: dataSprint.find((item: any) => item.id == filter.sprint)?.name,

      start_date: dataSprintSearch?.startDate,
      end_date: dataSprintSearch?.endDate,
      complete_date: dataSprintSearch?.completeDate,

      project_id: filter.project,
      criterias: criteriaSprint,
      users: criteriaUsers,
      finalPoint: finalPoint,
    }
    try {
      const res = await update(
        `${updateSprintReview}/${filter.sprint}`,
        values,
        getAll,
      )
      if (res === true) {
        setAction('')
      }
    } catch (error) {
      console.log(error)
    }
  }

  const pointsOptions = [
    { value: '1', label: '1' },
    { value: '2', label: '2' },
    { value: '3', label: '3' },
    { value: '4', label: '4' },
    { value: '5', label: '5' },
  ]

  const rowStyle = {
    height: '30px', // Điều chỉnh chiều cao hàng
  }

  const handleInputChange = (
    index: number,
    field: keyof DataCriteriaSprint,
    value: string,
  ) => {
    const updatedCriteria = [...criteriaSprint]
    updatedCriteria[index][field] = value
    setCriteriaSprint(updatedCriteria)
  }

  const handleInputChangeUsers = (
    index: number,
    field: keyof DataCriteriaUsers,
    value: any,
  ) => {
    const updatedCriteria = [...criteriaUsers]
    updatedCriteria[index][field] = value
    setCriteriaUsers(updatedCriteria)
  }
  const calculateRowSpan = (users: DataCriteriaUsers[], user_id: any) => {
    return users.filter((item) => item.user_id === user_id).length
  }

  return (
    <div>
      <div className={classes.title}>
        <h3>
          <Text>Admin/</Text>
          Sprint Review
        </h3>
        <Button
          onClick={() => {
            setAction('update')
          }}
          style={{
            display: filter.sprint ? 'block' : 'none',
          }}
        >
          Update
        </Button>
      </div>
      <Box
        style={{
          marginTop: '20%',
          textAlign: 'center',
          display: loadingProject ? 'block' : 'none',
          // display: 'none',
        }}
      >
        <Loader size={'sm'} color="green" type="bars" m={'0 auto'} />
        <Text fw={600} c={'gray'}>
          Loading . . .
        </Text>
      </Box>
      <Box display={'flex'} p={15}>
        <Box
          style={[
            {
              display: 'flex',
              flexFlow: 'column',
            },
            loadingProject ? { display: 'none' } : {},
          ]}
          w={'50%'}
        >
          <Box w="100%" display={'flex'}>
            <Text
              mr={'xs'}
              style={{ alignContent: 'center' }}
              fw={600}
              size={'md'}
            >
              Project:
            </Text>
            <Select
              searchable
              clearable
              w="60%"
              value={filter.project || null}
              size="xs"
              label=""
              data={dataProject.map((project) => ({
                value: project.id.toString(),
                label: project.name,
              }))}
              onChange={(e) => {
                if (e === null) {
                  // Clear project
                  setFilter({ project: '', sprint: '' }) // Clear cả project và sprint
                  setDataSprint([]) // Reset dataSprint để không hiển thị các giá trị sprint cũ
                  setInfoBoard('')
                  setIsDisabledSprint(true) // Vô hiệu hóa Select của sprint
                } else {
                  // Chọn project mới
                  setFilter({ project: e, sprint: '' }) // Clear sprint khi chọn project mới
                  setDataSprint([]) // Xóa dữ liệu sprint khi đổi project
                  setIsDisabledSprint(true) // Vô hiệu hóa lại Select sprint cho đến khi load xong
                }
              }}
            ></Select>
            <Text
              ml={'lg'}
              style={{ alignContent: 'center' }}
              fw={600}
              size={'md'}
            >
              Sprint:
            </Text>
            <Select
              disabled={isDisabledSprint}
              searchable
              clearable
              w="40%"
              value={filter.sprint || null} // Đảm bảo rằng nếu filter.sprint trống, thì giá trị sẽ là null
              size="xs"
              ml={'sm'}
              label=""
              data={dataSprint.map((sprint) => ({
                value: sprint.id.toString(),
                label: sprint.name,
              }))}
              onChange={(e) => {
                setFilter({ ...filter, sprint: e! })
              }}
            ></Select>
          </Box>
        </Box>
        <Box
          style={{
            display: 'flex',
            flexFlow: 'column',
            // backgroundColor: 'yellow',
            alignSelf: 'center',
          }}
          w={'50%'}
        >
          <Text style={{ textAlign: 'center' }} fw={600}>
            {dataProject.find((item: any) => item.id === filter.project)?.name}{' '}
            {dataSprint.find((item: any) => item.id === Number(filter.sprint))
              ?.name
              ? '/'
              : ''}{' '}
            {dataSprint.find((item) => item.id === Number(filter.sprint))?.name}
          </Text>
        </Box>
      </Box>

      <Box>
        {/* Tiêu đề Criteria for Sprint */}
        <Title
          order={4}
          ml="xs"
          style={
            criteriaSprint.length == 0 || loading ? { display: 'none' } : {}
          }
        >
          Criteria for Sprint:
        </Title>
        <Box
          style={{
            marginTop: '20%',
            textAlign: 'center',
            display: loading ? 'block' : 'none',
            // display: 'none',
          }}
        >
          <Loader size={'sm'} color="green" type="bars" m={'0 auto'} />
          <Text fw={600} c={'gray'}>
            Loading . . .
          </Text>
        </Box>
        {/* Bảng Criteria for Sprint */}
        <Table
          striped
          highlightOnHover
          withTableBorder
          withColumnBorders
          // me={'xs'}
          style={
            criteriaSprint.length == 0 || loading ? { display: 'none' } : {}
          }
        >
          <Table.Thead>
            <Table.Tr bg="#228be66b" style={rowStyle}>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                Criteria
              </Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                Expect Result
              </Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                Actual Result
              </Table.Th>
              <Table.Th style={{ textAlign: 'center' }}>Note</Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '100px' }}>
                Point
              </Table.Th>
            </Table.Tr>
          </Table.Thead>
          <Table.Tbody>
            {criteriaSprint.map((item, index) => (
              <Table.Tr key={index} style={rowStyle}>
                {/* TextInput cho trường name */}
                <Table.Td>
                  {/* <TextInput
                    value={item.name}
                    onChange={(e) =>
                      handleInputChange(index, 'name', e.target.value)
                    }
                  /> */}
                  <Tooltip multiline label={item.description}>
                    <span>{item.name}</span>
                  </Tooltip>
                </Table.Td>
                {/* TextInput cho trường expect */}
                <Table.Td>
                  <TextInput
                    value={item.expect}
                    onChange={(e) =>
                      handleInputChange(index, 'expect', e.target.value)
                    }
                  />
                </Table.Td>
                {/* TextInput cho trường actual */}
                <Table.Td>
                  <TextInput
                    value={item.actual}
                    onChange={(e) =>
                      handleInputChange(index, 'actual', e.target.value)
                    }
                  />
                </Table.Td>
                {/* TextInput cho trường note */}
                <Table.Td>
                  <Textarea
                    autosize
                    placeholder="Good performance"
                    value={item.note}
                    onChange={(e) =>
                      handleInputChange(index, 'note', e.target.value)
                    }
                    minRows={2}
                    maxRows={4}
                  />
                </Table.Td>
                <Table.Td>
                  <Select
                    data={pointsOptions}
                    defaultValue=""
                    size="sm"
                    value={item.point == '' ? null : String(item.point)}
                    onChange={(value) =>
                      handleInputChange(index, 'point', value ?? '')
                    }
                  />
                </Table.Td>
              </Table.Tr>
            ))}
            {criteriaSprint.length > 0 && (
              <Table.Tr style={rowStyle}>
                <Table.Td
                  colSpan={1}
                  style={{ textAlign: 'center' }}
                  bg="#d4eac7"
                >
                  <Text fw={600} color="red">
                    {' '}
                    Final result{' '}
                  </Text>
                </Table.Td>
                <Table.Td bg="#d4eac7">
                  <Select
                    data={pointsOptions}
                    defaultValue={'0'}
                    value={finalPoint}
                    onChange={(value) => setFinalPoint(value ?? '')}
                    size="xs"
                    styles={() => ({
                      input: {
                        color: 'red',
                        fontWeight: '600',
                        fontSize: 'initial',
                      },
                    })}
                  />
                </Table.Td>
                <Table.Td colSpan={3}></Table.Td>
              </Table.Tr>
            )}
          </Table.Tbody>
        </Table>

        {/* Tiêu đề Criteria for Users */}
        <Title
          order={4}
          ml="xs"
          mt={'xs'}
          style={
            criteriaUsers.length == 0 || loading ? { display: 'none' } : {}
          }
        >
          Criteria for Users:
        </Title>

        {/* Criteria for Users Table */}
        <Table
          striped
          highlightOnHover
          withTableBorder
          withColumnBorders
          // mt="md"
          style={
            criteriaUsers.length == 0 || loading ? { display: 'none' } : {}
          }
        >
          <Table.Thead>
            <Table.Tr bg="#228be66b" style={rowStyle}>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                User
              </Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                Criteria
              </Table.Th>
              <Table.Th style={{ textAlign: 'center' }}>Note</Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '250px' }}>
                Created by
              </Table.Th>
              <Table.Th style={{ textAlign: 'center', width: '100px' }}>
                Point
              </Table.Th>
            </Table.Tr>
          </Table.Thead>
          <Table.Tbody>
            {(() => {
              let alreadyDisplayed: number[] = []
              return criteriaUsers.map((item: any, index) => {
                // Tính rowSpan cho người dùng hiện tại
                const rowSpan = calculateRowSpan(criteriaUsers, item.user_id)

                const checkUser = alreadyDisplayed.find(
                  (i: any) => i == item.user_id,
                )
                  ? true
                  : false

                alreadyDisplayed.push(item.user_id)

                return (
                  <Table.Tr key={index} style={rowStyle}>
                    {!checkUser && (
                      <Table.Td rowSpan={rowSpan}>{item.user}</Table.Td>
                    )}

                    <Table.Td>
                      <Tooltip multiline label={item.description}>
                        <span>{item.name}</span>
                      </Tooltip>
                    </Table.Td>

                    <Table.Td>
                      <Textarea
                        autosize
                        placeholder="Good performance"
                        value={item.note}
                        onChange={(e) =>
                          handleInputChangeUsers(index, 'note', e.target.value)
                        }
                        minRows={2}
                        maxRows={4}
                      />
                    </Table.Td>

                    <Table.Td>
                      <TextInput
                        value={item.created_by}
                        onChange={(e) =>
                          handleInputChangeUsers(
                            index,
                            'created_by',
                            e.target.value,
                          )
                        }
                      />
                    </Table.Td>

                    <Table.Td>
                      <Select
                        data={pointsOptions}
                        defaultValue=""
                        size="sm"
                        value={item.point == '' ? null : String(item.point)}
                        onChange={(value) =>
                          handleInputChangeUsers(index, 'point', value)
                        }
                      />
                    </Table.Td>
                  </Table.Tr>
                )
              })
            })()}
          </Table.Tbody>
        </Table>
      </Box>
      <Dialog
        className={classes.dialog}
        opened={action === 'update'}
        withCloseButton
        onClose={() => setAction('')}
        size="lg"
        radius="md"
        position={{ top: 30, right: 10 }}
      >
        <Text className={classes.dialogText} size="sm" mb="xs" fw={500}>
          Do you want to update?
          <Group justify="center" m={10}>
            <Button
              disabled={activeBtn}
              fw={700}
              size="xs"
              variant="light"
              onClick={async () => {
                setLoading(true)
                setActiveBtn(true)
                await handleUpdate()
                setActiveBtn(false)
                setAction('')
              }}
            >
              Yes
            </Button>
            <Button
              fw={700}
              size="xs"
              variant="light"
              onClick={() => setAction('')}
            >
              Cancel
            </Button>
          </Group>
        </Text>
      </Dialog>
    </div>
  )
}

export default SprintReview
