import {
  deleteNote,
  getListMaster,
  getTheTimesheet,
  updateMultipleUserWorkingTime,
  updateNote,
  updateWorkingDays,
} from '@/api/Admin'
import { update, Xdelete } from '@/rtk/helpers/CRUD'
import { get } from '@/rtk/helpers/apiService'
import {
  Box,
  Button,
  Drawer,
  Image,
  Menu,
  MultiSelect,
  Select,
  Table,
  Text,
  Textarea,
  TextInput,
  Tooltip,
} from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import {
  IconCheck,
  IconExclamationMark,
  IconPointFilled,
  IconTrash,
  IconX,
} from '@tabler/icons-react'
import moment from 'moment'
import { useEffect, useState } from 'react'

import classes from './Timekeeping.module.css'

interface User {
  id: number
  name: string
  email: string
  email_verified_at: string | null
  permission: string
  remember_token: string | null
  created_at: string | null
  updated_at: string | null
}

interface DataReason {
  id: number
  c_code: string
  c_name: string
}

interface DataTimeType {
  id: number
  c_code: string
  c_name: string
}

interface HistoryValue {
  id: number
  name: string
  user_id: number
  status: string
  time_string: string
  image: string
  created_at: string
  updated_at: string
}

interface NoteValue {
  id: number
  note: string
  reason: string
  timeType: string
  reasonName: string
  timeTypeName: string
}

interface History {
  values: HistoryValue[]
  total: number
  day: number
  notes: NoteValue[]
}

interface UserData {
  user: User
  history: History[]
}

const Timekeeping = () => {
  const [opened1, { open: open1, close: close1 }] = useDisclosure(false)
  const [opened2, { open: open2, close: close2 }] = useDisclosure(false)
  const [disableBtn, setDisableBtn] = useState(false)
  const [daysInMonth, setDaysInMonth] = useState(
    Array.from({ length: 31 }, (_, index) => index + 1),
  )
  const [customAddData, setCustomAddData] = useState<{
    data: string[]
    type: string
    day: number
  }>({
    data: [],
    type: '',
    day: 0,
  })
  const [customAddNotes, setCustomAddNotes] = useState<{
    user: {
      id: number
      name: string
    }
    type: string
    reason: string
    note: string
    day: number
    notes: NoteValue[]
  }>({
    user: {
      id: 0,
      name: '',
    },
    type: '',
    reason: '',
    note: '',
    day: 0,
    notes: [],
  })

  const [workingDays, setWorkingDays] = useState(30)
  const [data, setData] = useState<UserData[]>([])
  const [date, setDate] = useState({
    month: (new Date().getMonth() + 1).toString(),
    year: new Date().getFullYear().toString(),
  })

  const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
  const [dataReason, setDataReason] = useState<DataReason[]>([])

  const getListMasterByType = async (type: string) => {
    try {
      const params = {
        type: type,
      }
      const res = await get(getListMaster, 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 resultTimeType = await getListMasterByType('TIME_TYPE')
      setDataTimeType(resultTimeType)

      const resultReason = await getListMasterByType('REASON')
      setDataReason(resultReason)
    }

    fetchData()
  }, [])

  const getTimeSheet = async () => {
    try {
      const res = await get(getTheTimesheet, {
        month: date.month,
        year: date.year,
      })
      if (res.status) {
        setData(
          res.data.filter((u: UserData) => u.user.permission.includes('staff')),
        )

        if (
          res.data.find(
            (item: UserData) => item.user.id === customAddNotes.user.id,
          )?.user.id
        ) {
          setCustomAddNotes({
            ...customAddNotes,
            notes: (res.data
              .find((item: UserData) => item.user.id === customAddNotes.user.id)
              ?.history?.find(
                (itemHistory: History) =>
                  itemHistory.day === customAddNotes.day,
              )?.notes ?? []) as NoteValue[],
          })
        }

        setDaysInMonth(
          Array.from({ length: getDaysInMonth() }, (_, index) => index + 1),
        )

        setWorkingDays(res.working_days ?? 30)
      }
    } catch (error: any) {
      console.log(error)
      notifications.show({
        title: 'Error',
        message: error.message ?? error,
        color: 'red',
      })
    }
  }

  function getDayName(dateString: string) {
    // Tạo đối tượng Date từ chuỗi ngày tháng năm
    const date = new Date(dateString)

    // Lấy ngày trong tuần (0-6)
    const dayNumber = date.getDay()

    // Mảng chứa các tên ngày bằng tiếng Việt
    const daysInVietnamese = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']

    // Trả về tên ngày bằng tiếng Việt
    return daysInVietnamese[dayNumber]
  }

  function getDaysInMonth() {
    // Tạo một đối tượng Date cho ngày đầu tiên của tháng tiếp theo
    // Chú ý: tháng trong đối tượng Date là từ 0 (tháng 1) đến 11 (tháng 12)
    const days = new Date(parseInt(date.year), parseInt(date.month), 0)
    // Trả về ngày, tức là số ngày trong tháng
    return days.getDate()
  }

  const updateMultipleUser = async (
    users: number[],
    day: number,
    type: string,
  ) => {
    try {
      await update(
        updateMultipleUserWorkingTime,
        {
          users: users,
          year: date.year,
          month: date.month,
          day: day,
          type: type,
        },
        getTimeSheet,
      )

      setDisableBtn(false)
    } catch (error) {
      console.log(error)
    }
  }

  const updateInfoNote = async (
    users: {
      id: number
      name: string
    },
    day: number,
    type: string,
    reason: string,
    note: string,
  ) => {
    try {
      await update(
        updateNote,
        {
          month: date.month,
          year: date.year,
          users: users,
          type: type,
          reason: reason,
          note: note,
          day: day,
        },
        getTimeSheet,
      )

      setDisableBtn(false)
    } catch (error) {
      console.log(error)
    }
  }

  const handleUpdateWorkingDays = async () => {
    try {
      await update(
        updateWorkingDays,
        {
          working_days: workingDays,
          year: date.year,
          month: date.month,
        },
        getTimeSheet,
      )
    } catch (error) {
      console.log(error)
    }
  }
  // const handleUpdateCacheMonth = async () => {
  //   try {
  //     await update(
  //       updateCacheMonth,
  //       {
  //         year: date.year,
  //         month: date.month,
  //       },
  //       getTimeSheet,
  //     )
  //   } catch (error) {
  //     console.log(error)
  //   }
  // }

  useEffect(() => {
    getTimeSheet()
  }, [date])

  const showTooltipNote = (user: UserData, d: number) => {
    return user.history
      .find((h) => h.day === d && h.notes && h.notes.length > 0)
      ?.notes.map((v, index) => {
        return (
          <p key={index}>
            - {v.reasonName} ({v.timeTypeName}): {v.note}
          </p>
        )
      })
  }
  const showTooltipAllNote = (user: UserData) => {
    return (
      <table style={{ borderCollapse: 'collapse', width: '100%' }}>
        <tbody>
          {user.history
            .filter((h) => h.notes && h.notes.length > 0)
            .map((h, index) => (
              <tr key={index} className={classes.historyRow}>
                <td
                  style={{
                    border: '0',
                    verticalAlign: 'top',
                    fontWeight: 'bold',
                  }}
                >
                  Day {h.day}:
                </td>
                <td style={{ border: '0', paddingLeft: '10px' }}>
                  {h.notes.map((v, noteIndex) => (
                    <p key={noteIndex} style={{ margin: '0' }}>
                      - {v.reasonName} ({v.timeTypeName}): {v.note}
                    </p>
                  ))}
                </td>
              </tr>
            ))}
        </tbody>
      </table>
    )
  }

  const showTooltip = (user: UserData, total: number, d: number) => {
    return (
      <div key={d}>
        {`Total: ${(total / 60 / 60).toFixed(1)}h`}
        {user.history
          .find((h) => h.day === d)
          ?.values.map((v) => {
            return (
              <Box
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                }}
                key={v.id}
              >
                <p>{v.status + ': ' + v.time_string}</p>{' '}
                {v.image && (
                  <Image
                    w={100}
                    h={100}
                    src={
                      import.meta.env.VITE_BACKEND_URL.includes('local')
                        ? import.meta.env.VITE_BACKEND_URL +
                          'storage/' +
                          v.image
                        : import.meta.env.VITE_BACKEND_URL +
                          'image/storage/' +
                          v.image
                    }
                  />
                )}
              </Box>
            )
          })}
        {showTooltipNote(user, d)}
      </div>
    )
  }

  const handleDelete = async (id: number) => {
    try {
      await Xdelete(
        deleteNote,
        { id: id, month: date.month, year: date.year },
        getTimeSheet,
      )
    } catch (error) {
      console.log(error)
    }
  }

  const handleOpenNote = (user: UserData, d: number) => {
    open2()
    setCustomAddNotes({
      ...customAddNotes,
      day: d,
      user: {
        id: user.user.id,
        name: user.user.name,
      },
      notes:
        user.history.find((h) => h.day === d && h.notes && h.notes.length > 0)
          ?.notes ?? [],
    })
  }

  return (
    <div>
      <div className={classes.title}>
        <h3>
          Timekeeping
        </h3>
      </div>
      <Drawer
        opened={opened1}
        onClose={close1}
        position="right"
        title={<strong>Add custom worklog</strong>}
      >
        <MultiSelect
          mb={'md'}
          searchable
          label="User(s)"
          data={data.map((user) => {
            return { value: user.user.id.toString(), label: user.user.name }
          })}
          onChange={(e) => {
            setCustomAddData({ ...customAddData, data: e })
          }}
        />
        <Select
          mb={'md'}
          label="Type"
          data={[
            { value: 'half', label: 'Half day' },
            { value: 'one', label: 'A day' },
          ]}
          onChange={(e) => {
            setCustomAddData({ ...customAddData, type: e! })
          }}
        />
        <Button
          onClick={() => {
            setDisableBtn(true)
            if (
              customAddData.type === '' ||
              customAddData.data.length === 0 ||
              customAddData.day === 0
            ) {
              notifications.show({
                title: 'Error',
                message: 'Input data required',
                color: 'red',
              })
              setDisableBtn(false)
            } else {
              updateMultipleUser(
                customAddData.data.map((u) => parseInt(u)),
                customAddData.day,
                customAddData.type,
              )
            }
          }}
          disabled={disableBtn}
        >
          Submit
        </Button>
      </Drawer>

      {/* Form Save Note */}
      <Drawer
        opened={opened2}
        onClose={close2}
        position="right"
        title={<strong>Save Note</strong>}
      >
        <p>
          <span style={{ fontWeight: 'bold' }}>User</span>:{' '}
          {customAddNotes.user.name}
          <span style={{ paddingLeft: '10px', paddingRight: '10px' }}>|</span>
          <span style={{ fontWeight: 'bold' }}>Day</span>: {customAddNotes.day}
        </p>

        <Select
          mb={'md'}
          searchable
          label="Reason"
          data={dataReason.map((user) => ({
            value: user.c_code.toString(),
            label: user.c_name,
          }))}
          onChange={(e) => {
            setCustomAddNotes({ ...customAddNotes, reason: e! })
          }}
        />
        {customAddNotes.reason != '' && (
          <Select
            mb={'md'}
            label="Time Type"
            data={dataTimeType.map((item) => {
              return { value: item.c_code.toString(), label: item.c_name }
            })}
            onChange={(e) => {
              setCustomAddNotes({ ...customAddNotes, type: e! })
            }}
          />
        )}
        {customAddNotes.type != '' && (
          <Textarea
            mb={'md'}
            label="Note"
            onChange={(e) => {
              setCustomAddNotes({ ...customAddNotes, note: e.target.value })
            }}
          />
        )}
        <Button
          onClick={() => {
            setDisableBtn(true)
            if (
              customAddNotes.type === '' ||
              customAddNotes.reason === '' ||
              customAddNotes.note === '' ||
              customAddNotes.day === 0 ||
              customAddNotes.user.id === 0
            ) {
              notifications.show({
                title: 'Error',
                message: 'Input data required',
                color: 'red',
              })
              setDisableBtn(false)
            } else {
              updateInfoNote(
                customAddNotes.user,
                customAddNotes.day,
                customAddNotes.type,
                customAddNotes.reason,
                customAddNotes.note,
              )
            }
          }}
          disabled={disableBtn}
        >
          Save
        </Button>
        {customAddNotes.notes.map((item, index) => {
          return (
            <Box
              key={index}
              display="flex"
              className="text-muted"
              style={{
                marginTop: '10px',
                border: '1px solid #ccc',
                borderRadius: '5px',
                marginBottom: '10px',
                padding: '10px',
                justifyContent: 'space-around',
              }}
            >
              <Box w={'90%'}>
                <TextInput
                  readOnly
                  variant="unstyled"
                  type="text"
                  size="xs"
                  label={`${item.reasonName} - ${item.timeTypeName}`}
                  w={'100%'}
                  value={item.note}
                />
              </Box>
              <Box
                className={classes.optionIcon}
                style={{ alignItems: 'center' }}
              >
                <IconTrash
                  className={classes.deleteIcon}
                  onClick={async () => {
                    await handleDelete(item.id)
                    // handleUpdateCacheMonth()
                    // close2()
                  }}
                  width={20}
                  height={20}
                />
              </Box>
            </Box>
          )
        })}
      </Drawer>
      <Box display={'flex'}>
        <Box style={{ display: 'flex', flexFlow: 'column' }} w={'30%'}>
          <Box w="100%" display={'flex'}>
            <Select
              w="50%"
              value={date.month}
              size="xs"
              label="Month"
              data={Array.from({ length: 12 }, (_, index) => {
                return {
                  value: (1 + index).toString(),
                  label: (1 + index).toString(),
                  disabled:
                    1 + index > parseInt(moment(Date.now()).format('MM')),
                }
              })}
              onChange={(e) => {
                setDate({ ...date, month: e! })
              }}
            ></Select>
            <Select
              w="50%"
              value={date.year}
              size="xs"
              ml={'sm'}
              label="Year"
              data={Array.from({ length: 10 }, (_, index) => {
                return {
                  value: (
                    parseInt(moment(Date.now()).format('YYYY')) -
                    3 +
                    index
                  ).toString(),
                  label: (
                    parseInt(moment(Date.now()).format('YYYY')) -
                    3 +
                    index
                  ).toString(),
                  disabled:
                    parseInt(moment(Date.now()).format('YYYY')) - 3 + index >
                    parseInt(moment(Date.now()).format('YYYY')),
                }
              })}
              onChange={(e) => {
                setDate({ ...date, year: e! })
              }}
            ></Select>
          </Box>
          <Box display={'flex'} style={{ alignItems: 'end' }}>
            <TextInput
              type="number"
              size="xs"
              label="Working days"
              w={'20%'}
              value={workingDays}
              onChange={(e) => {
                setWorkingDays(parseFloat(e.target.value))
              }}
            />
            <Tooltip label="Save working days">
              <Button
                size="xs"
                ml={'sm'}
                onClick={() => handleUpdateWorkingDays()}
              >
                Save
              </Button>
            </Tooltip>
          </Box>
        </Box>
        <Box
          w="70%"
          pl={200}
          style={{
            display: 'flex',
            alignItems: 'end',
            justifyContent: 'space-evenly',
          }}
        >
          <Box style={{ display: 'flex', alignItems: 'center' }}>
            <IconCheck
              size={20}
              style={{
                backgroundColor: 'green',
                color: 'white',
                borderRadius: '5px',
                padding: '2px',
                fontWeight: 700,
              }}
            />
            <Text ml={'sm'} fz="14px">
              Work over 7 hours
            </Text>
          </Box>
          <Box style={{ display: 'flex', alignItems: 'center' }}>
            <IconCheck
              size={20}
              style={{
                backgroundColor: 'orange',
                color: 'white',
                borderRadius: '5px',
                padding: '2px',
                fontWeight: 700,
              }}
            />
            <Text ml={'sm'} fz="14px">
              Work over 3.5 hours
            </Text>
          </Box>
          <Box style={{ display: 'flex', alignItems: 'center' }}>
            <IconExclamationMark
              size={20}
              style={{
                backgroundColor: 'orange',
                color: 'white',
                borderRadius: '5px',
                padding: '2px',
                fontWeight: 700,
              }}
            />
            <Text ml={'sm'} fz="14px">
              Checked in
            </Text>
          </Box>
          <Box style={{ display: 'flex', alignItems: 'center' }}>
            <IconX
              size={20}
              style={{
                backgroundColor: '#ff4646',
                color: 'white',
                borderRadius: '5px',
                padding: '2px',
                fontWeight: 700,
              }}
            />
            <Text ml={'sm'} fz="14px">
              Off
            </Text>
          </Box>
        </Box>
      </Box>
      <Box>
        <Table
          striped
          highlightOnHover
          withTableBorder
          withColumnBorders
          mt={'md'}
        >
          <Table.Thead>
            <Table.Tr bg={'#228be66b'}>
              <Table.Th>Day</Table.Th>
              <Table.Th></Table.Th>
              <Table.Th></Table.Th>
              {daysInMonth.map((d) => {
                return (
                  <Menu width={200} shadow="md" key={d}>
                    <Menu.Target>
                      <Table.Th
                        key={d}
                        ta={'center'}
                        style={{ cursor: 'pointer' }}
                      >
                        <span>{d}</span>
                      </Table.Th>
                    </Menu.Target>

                    <Menu.Dropdown>
                      <Menu.Item
                        onClick={() =>
                          updateMultipleUser(
                            data.map((u) => u.user.id),
                            d,
                            'half',
                          )
                        }
                      >
                        + Add half a day's work
                      </Menu.Item>
                      <Menu.Item
                        onClick={() =>
                          updateMultipleUser(
                            data.map((u) => u.user.id),
                            d,
                            'one',
                          )
                        }
                      >
                        + Add 1 day of work
                      </Menu.Item>
                      <Menu.Item>
                        <Text
                          size="sm"
                          onClick={() => {
                            open1()
                            setCustomAddData({ ...customAddData, day: d })
                          }}
                        >
                          + Add custom worklog
                        </Text>
                      </Menu.Item>
                    </Menu.Dropdown>
                  </Menu>
                )
              })}
            </Table.Tr>
            <Table.Tr bg={'#228be66b'}>
              <Table.Th></Table.Th>
              <Table.Th ta={'center'}>Total</Table.Th>
              <Table.Th ta={'center'}>Off</Table.Th>
              {daysInMonth.map((d) => {
                return (
                  <Table.Th
                    key={d}
                    ta={'center'}
                    bg={
                      getDayName(`${date.year}-${date.month}-${d}`) === 'Su' ||
                      getDayName(`${date.year}-${date.month}-${d}`) === 'Sa'
                        ? 'rgb(251 255 196 / 78%)'
                        : ''
                    }
                  >
                    {getDayName(`${date.year}-${date.month}-${d}`)}
                  </Table.Th>
                )
              })}
            </Table.Tr>
          </Table.Thead>
          <Table.Tbody>
            {data.map((user) => {
              let totalDays =
                user.history.filter((h) => h.total / 60 / 60 >= 7).length +
                user.history.filter(
                  (h) => h.total / 60 / 60 < 7 && h.total / 60 / 60 >= 3.5,
                ).length /
                  2
              return (
                <Table.Tr key={user.user.id} className={classes.tableTr}>
                  <Table.Td>
                    <Tooltip
                      // position={'auto'}
                      multiline
                      // opened
                      // offset={{ mainAxis: 5, crossAxis: 0 }}
                      label={showTooltipAllNote(user)}
                    >
                      <div>{user.user.name}</div>
                    </Tooltip>
                  </Table.Td>
                  <Table.Td ta={'center'}>{totalDays}</Table.Td>
                  <Table.Td ta={'center'}>{workingDays - totalDays}</Table.Td>
                  {daysInMonth.map((d) => {
                    var total =
                      user.history.find((h) => h.day === d)?.total ?? 0
                    var notes = user.history.find((h) => h.day === d)?.notes
                    return (
                      <Table.Td
                        pos={'relative'}
                        key={d}
                        ta={'center'}
                        bg={
                          getDayName(`${date.year}-${date.month}-${d}`) ===
                            'Su' ||
                          getDayName(`${date.year}-${date.month}-${d}`) === 'Sa'
                            ? 'rgb(251 255 196 / 78%)'
                            : ''
                        }
                      >
                        <Box
                          pos={'absolute'}
                          top={-3}
                          right={-3}
                          display={notes && notes.length > 0 ? 'block' : 'none'}
                        >
                          <IconPointFilled
                            width={15}
                            height={15}
                            style={{ color: '#2767e1' }}
                          />
                        </Box>
                        {total / 60 / 60 < 7 &&
                        user.history.find(
                          (h) => h.day === d && h.values && h.values.length > 0,
                        ) ? (
                          total / 60 / 60 >= 3.5 ? (
                            <Tooltip
                              multiline
                              label={showTooltip(user, total, d)}
                            >
                              <IconCheck
                                size={20}
                                style={{
                                  backgroundColor: 'orange',
                                  color: 'white',
                                  borderRadius: '5px',
                                  padding: '2px',
                                  fontWeight: 700,
                                }}
                                onClick={() => {
                                  handleOpenNote(user, d)
                                }}
                              />
                            </Tooltip>
                          ) : (
                            <Tooltip
                              multiline
                              label={showTooltip(user, total, d)}
                            >
                              <IconExclamationMark
                                size={20}
                                style={{
                                  backgroundColor: 'orange',
                                  color: 'white',
                                  borderRadius: '5px',
                                  padding: '2px',
                                  fontWeight: 700,
                                }}
                                onClick={() => {
                                  handleOpenNote(user, d)
                                }}
                              />
                            </Tooltip>
                          )
                        ) : total >= 7 ? (
                          <>
                            <Tooltip
                              multiline
                              label={showTooltip(user, total, d)}
                            >
                              <IconCheck
                                size={20}
                                style={{
                                  backgroundColor: 'green',
                                  color: 'white',
                                  borderRadius: '5px',
                                  padding: '2px',
                                }}
                                onClick={() => {
                                  handleOpenNote(user, d)
                                }}
                              />
                            </Tooltip>
                          </>
                        ) : (
                          <>
                            {user.history.find(
                              (h) =>
                                h.day === d && h.notes && h.notes.length > 0,
                            ) ? (
                              <Tooltip
                                multiline
                                label={showTooltipNote(user, d)}
                              >
                                <IconX
                                  size={20}
                                  style={{
                                    backgroundColor: '#ff4646',
                                    color: 'white',
                                    borderRadius: '5px',
                                    padding: '2px',
                                  }}
                                  id={`indexBySN${user.user.id}_${d}`}
                                  onClick={() => {
                                    handleOpenNote(user, d)
                                  }}
                                />
                              </Tooltip>
                            ) : (
                              <IconX
                                size={20}
                                style={{
                                  backgroundColor: '#ff4646',
                                  color: 'white',
                                  borderRadius: '5px',
                                  padding: '2px',
                                }}
                                id={`indexBySN${user.user.id}_${d}`}
                                onClick={() => {
                                  handleOpenNote(user, d)
                                }}
                              />
                            )}
                          </>
                        )}
                      </Table.Td>
                    )
                  })}
                </Table.Tr>
              )
            })}
          </Table.Tbody>
        </Table>
      </Box>
    </div>
  )
}

export default Timekeeping
