import { Button, Divider, TextField, Tooltip } from '@mui/material'
import JSZip from 'jszip'
import { useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import { useAppSelector } from '../../hooks'
import { appPrivateRoutes, appPublicRoutes } from '../../routes'
import { Meta, ProfileMetadata } from '../../types'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
  faAdd,
  faFilter,
  faFilterCircleXmark,
  faSearch
} from '@fortawesome/free-solid-svg-icons'
import { Select } from '../../components/Select'
import { DisplaySigit } from '../../components/DisplaySigit'

import { Container } from '../../components/Container'
import styles from './style.module.scss'

// Unsupported Filter options are commented
const FILTERS = [
  'Show all',
  // 'Drafts',
  'In-progress',
  'Completed'
  // 'Archived'
] as const
type Filter = (typeof FILTERS)[number]

const SORT_BY = [
  {
    label: 'Newest',
    value: 'desc'
  },
  { label: 'Oldest', value: 'asc' }
] as const
type Sort = (typeof SORT_BY)[number]['value']

export const HomePage = () => {
  const navigate = useNavigate()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [sigits, setSigits] = useState<Meta[]>([])
  const [profiles, setProfiles] = useState<{ [key: string]: ProfileMetadata }>(
    {}
  )
  const usersAppData = useAppSelector((state) => state.userAppData)

  useEffect(() => {
    if (usersAppData) {
      setSigits(Object.values(usersAppData.sigits))
    }
  }, [usersAppData])

  const handleUploadClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click()
    }
  }

  const handleFileChange = async (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = event.target.files?.[0]
    if (file) {
      // Check if the file extension is .sigit.zip
      const fileName = file.name
      const fileExtension = fileName.slice(-10) // ".sigit.zip" has 10 characters
      if (fileExtension === '.sigit.zip') {
        const zip = await JSZip.loadAsync(file).catch((err) => {
          console.log('err in loading zip file :>> ', err)
          toast.error(err.message || 'An error occurred in loading zip file.')
          return null
        })

        if (!zip) return

        // navigate to sign page if zip contains keys.json
        if ('keys.json' in zip.files) {
          return navigate(appPrivateRoutes.sign, {
            state: { uploadedZip: file }
          })
        }

        // navigate to verify page if zip contains meta.json
        if ('meta.json' in zip.files) {
          return navigate(appPublicRoutes.verify, {
            state: { uploadedZip: file }
          })
        }

        toast.error('Invalid zip file')
        return
      }

      // navigate to create page
      navigate(appPrivateRoutes.create, { state: { uploadedFile: file } })
    }
  }

  const [filter, setFilter] = useState<Filter>('Show all')
  const [isFilterVisible, setIsFilterVisible] = useState(true)
  const [sort, setSort] = useState<Sort>('asc')

  return (
    <Container className={styles.container}>
      <div className={styles.header}>
        {isFilterVisible && (
          <>
            <Select
              name={'filter-select'}
              setValue={setFilter}
              options={FILTERS.map((f) => {
                return {
                  label: f,
                  value: f
                }
              })}
            />
            <Select
              name={'sort-select'}
              setValue={setSort}
              options={SORT_BY.map((s) => {
                return { ...s }
              })}
            />
          </>
        )}
        <div className={styles.actionButtons}>
          <div className={styles.search}>
            <TextField
              placeholder="Search"
              size="small"
              sx={{
                fontSize: '16px',
                height: '34px',
                borderTopLeftRadius: 'var(----mui-shape-borderRadius)',
                borderBottomLeftRadius: 'var(----mui-shape-borderRadius)',
                '& .MuiInputBase-root': {
                  borderTopRightRadius: 0,
                  borderBottomRightRadius: 0
                },
                '& .MuiInputBase-input': {
                  padding: '5.5px 14px'
                },
                '& .MuiOutlinedInput-notchedOutline': {
                  display: 'none'
                }
              }}
            />
            <Button
              sx={{
                minWidth: '44px',
                padding: '10px 12px',
                borderTopLeftRadius: 0,
                borderBottomLeftRadius: 0
              }}
              variant={'contained'}
            >
              <FontAwesomeIcon icon={faSearch} />
            </Button>
          </div>
          <Divider orientation="vertical" variant="middle" flexItem />
          <Tooltip title="Toggle Filter" arrow>
            <Button
              sx={{
                minWidth: '44px',
                padding: '10px 12px'
              }}
              variant={'contained'}
              onClick={() => setIsFilterVisible((v) => !v)}
            >
              {isFilterVisible ? (
                <FontAwesomeIcon icon={faFilterCircleXmark} />
              ) : (
                <FontAwesomeIcon icon={faFilter} />
              )}
            </Button>
          </Tooltip>
          <Tooltip title="Upload" arrow>
            <Button
              sx={{
                minWidth: '44px',
                padding: '10px 12px'
              }}
              component={'label'}
              htmlFor="fileUpload"
              variant={'contained'}
              onClick={handleUploadClick}
            >
              <FontAwesomeIcon icon={faAdd} />
            </Button>
          </Tooltip>
          <input
            id="fileUpload"
            type="file"
            hidden
            ref={fileInputRef}
            onChange={handleFileChange}
          />
        </div>
      </div>
      <div className={styles.dropzone}>
        <div>Click or drag files to upload!</div>
      </div>
      <div className={styles.submissions}>
        {sigits.map((sigit, index) => (
          <DisplaySigit
            key={`sigit-${index}`}
            meta={sigit}
            profiles={profiles}
            setProfiles={setProfiles}
          />
        ))}
      </div>
    </Container>
  )
}
