import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { useNostr } from '@/providers/NostrProvider'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { ScanLine, X } from 'lucide-react'
import QrScanner from 'qr-scanner'

function QrScannerModal({
  onScan,
  onClose
}: {
  onScan: (result: string) => void
  onClose: () => void
}) {
  const { t } = useTranslation()
  const videoRef = useRef<HTMLVideoElement>(null)
  const scannerRef = useRef<QrScanner | null>(null)
  const [error, setError] = useState<string | null>(null)

  const handleScan = useCallback(
    (result: QrScanner.ScanResult) => {
      onScan(result.data)
      onClose()
    },
    [onScan, onClose]
  )

  useEffect(() => {
    if (!videoRef.current) return

    const scanner = new QrScanner(videoRef.current, handleScan, {
      preferredCamera: 'environment',
      highlightScanRegion: true,
      highlightCodeOutline: true
    })

    scannerRef.current = scanner

    scanner.start().catch(() => {
      setError(t('Failed to access camera'))
    })

    return () => {
      scanner.destroy()
    }
  }, [handleScan, t])

  return (
    <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center">
      <div className="relative w-full max-w-sm mx-4">
        <Button
          variant="ghost"
          size="icon"
          className="absolute -top-12 right-0 text-white hover:bg-white/20"
          onClick={onClose}
        >
          <X className="h-6 w-6" />
        </Button>
        <div className="rounded-lg overflow-hidden bg-black">
          {error ? (
            <div className="p-8 text-center text-destructive">{error}</div>
          ) : (
            <video ref={videoRef} className="w-full" />
          )}
        </div>
        <p className="text-center text-white/70 text-sm mt-4">
          {t('Point camera at QR code')}
        </p>
      </div>
    </div>
  )
}

export default function PrivateKeyLogin({
  back,
  onLoginSuccess
}: {
  back: () => void
  onLoginSuccess: () => void
}) {
  return (
    <Tabs defaultValue="nsec">
      <TabsList>
        <TabsTrigger value="nsec">nsec</TabsTrigger>
        <TabsTrigger value="ncryptsec">ncryptsec</TabsTrigger>
      </TabsList>
      <TabsContent value="nsec">
        <NsecLogin back={back} onLoginSuccess={onLoginSuccess} />
      </TabsContent>
      <TabsContent value="ncryptsec">
        <NcryptsecLogin back={back} onLoginSuccess={onLoginSuccess} />
      </TabsContent>
    </Tabs>
  )
}

function NsecLogin({ back, onLoginSuccess }: { back: () => void; onLoginSuccess: () => void }) {
  const { t } = useTranslation()
  const { nsecLogin } = useNostr()
  const [nsecOrHex, setNsecOrHex] = useState('')
  const [errMsg, setErrMsg] = useState<string | null>(null)
  const [password, setPassword] = useState('')
  const [showScanner, setShowScanner] = useState(false)

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNsecOrHex(e.target.value)
    setErrMsg(null)
  }

  const handleScan = (result: string) => {
    setNsecOrHex(result)
    setErrMsg(null)
  }

  const handleLogin = () => {
    if (nsecOrHex === '') return

    nsecLogin(nsecOrHex, password)
      .then(() => onLoginSuccess())
      .catch((err) => {
        setErrMsg(err.message)
      })
  }

  return (
    <>
      {showScanner && (
        <QrScannerModal onScan={handleScan} onClose={() => setShowScanner(false)} />
      )}
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault()
          handleLogin()
        }}
      >
        <div className="text-orange-400">
          {t(
            'Using private key login is insecure. It is recommended to use a browser extension for login, such as alby, nostr-keyx or nos2x. If you must use a private key, please set a password for encryption at minimum.'
          )}
        </div>
        <div className="grid gap-2">
          <Label htmlFor="nsec-input">nsec or hex</Label>
          <div className="flex gap-2">
            <Input
              id="nsec-input"
              type="password"
              placeholder="nsec1.. or hex"
              value={nsecOrHex}
              onChange={handleInputChange}
              className={errMsg ? 'border-destructive' : ''}
            />
            <Button
              type="button"
              variant="outline"
              size="icon"
              onClick={() => setShowScanner(true)}
              title={t('Scan QR code')}
            >
              <ScanLine className="h-4 w-4" />
            </Button>
          </div>
          {errMsg && <div className="text-xs text-destructive">{errMsg}</div>}
        </div>
        <div className="grid gap-2">
          <Label htmlFor="password-input">{t('password')}</Label>
          <Input
            id="password-input"
            type="password"
            placeholder={t('optional: encrypt nsec')}
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        </div>
        <div className="flex gap-2">
          <Button className="w-fit px-8" variant="secondary" type="button" onClick={back}>
            {t('Back')}
          </Button>
          <Button className="flex-1" type="submit">
            {t('Login')}
          </Button>
        </div>
      </form>
    </>
  )
}

function NcryptsecLogin({
  back,
  onLoginSuccess
}: {
  back: () => void
  onLoginSuccess: () => void
}) {
  const { t } = useTranslation()
  const { ncryptsecLogin } = useNostr()
  const [ncryptsec, setNcryptsec] = useState('')
  const [errMsg, setErrMsg] = useState<string | null>(null)
  const [showScanner, setShowScanner] = useState(false)

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNcryptsec(e.target.value)
    setErrMsg(null)
  }

  const handleScan = (result: string) => {
    setNcryptsec(result)
    setErrMsg(null)
  }

  const handleLogin = () => {
    if (ncryptsec === '') return

    ncryptsecLogin(ncryptsec)
      .then(() => onLoginSuccess())
      .catch((err) => {
        setErrMsg(err.message)
      })
  }

  return (
    <>
      {showScanner && (
        <QrScannerModal onScan={handleScan} onClose={() => setShowScanner(false)} />
      )}
      <form
        className="space-y-4"
        onSubmit={(e) => {
          e.preventDefault()
          handleLogin()
        }}
      >
        <div className="grid gap-2">
          <Label htmlFor="ncryptsec-input">ncryptsec</Label>
          <div className="flex gap-2">
            <Input
              id="ncryptsec-input"
              type="password"
              placeholder="ncryptsec1.."
              value={ncryptsec}
              onChange={handleInputChange}
              className={errMsg ? 'border-destructive' : ''}
            />
            <Button
              type="button"
              variant="outline"
              size="icon"
              onClick={() => setShowScanner(true)}
              title={t('Scan QR code')}
            >
              <ScanLine className="h-4 w-4" />
            </Button>
          </div>
          {errMsg && <div className="text-xs text-destructive">{errMsg}</div>}
        </div>
        <div className="flex gap-2">
          <Button className="w-fit px-8" variant="secondary" type="button" onClick={back}>
            {t('Back')}
          </Button>
          <Button className="flex-1" type="submit">
            {t('Login')}
          </Button>
        </div>
      </form>
    </>
  )
}
