import { createFileRoute } from '@tanstack/react-router'
import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { queryOptions } from '@tanstack/react-query'
import { api } from '@/lib/api-client'
import { useAuthStore } from '@/stores/auth.store'
import { useThemeStore } from '@/stores/theme.store'
import { themes } from '@/lib/themes'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
import { Sun, Moon, Monitor } from 'lucide-react'
import { toast } from 'sonner'
import { AvatarUpload } from '@/components/shared/avatar-upload'

interface Profile {
  id: string
  email: string
  firstName: string
  lastName: string
  role: string
  employeeNumber: string | null
  hasPin: boolean
  createdAt: string
}

export const Route = createFileRoute('/_authenticated/profile')({
  component: ProfilePage,
})

function profileOptions() {
  return queryOptions({
    queryKey: ['auth', 'me'],
    queryFn: () => api.get<Profile>('/v1/auth/me'),
  })
}

function ProfilePage() {
  const { tab } = Route.useSearch() as { tab?: string }

  const queryClient = useQueryClient()
  const setAuth = useAuthStore((s) => s.setAuth)
  const storeUser = useAuthStore((s) => s.user)
  const storeToken = useAuthStore((s) => s.token)

  const { data: profile } = useQuery(profileOptions())

  return (
    <div className="space-y-6 max-w-2xl">
      <h1 className="text-2xl font-bold">Profile</h1>

      <Tabs defaultValue={tab === 'security' || tab === 'appearance' ? tab : 'account'}>
        <TabsList>
          <TabsTrigger value="account">Account</TabsTrigger>
          <TabsTrigger value="security">Security</TabsTrigger>
          <TabsTrigger value="appearance">Appearance</TabsTrigger>
        </TabsList>

        <TabsContent value="account">
          <AccountTab profile={profile} queryClient={queryClient} setAuth={setAuth} storeUser={storeUser} storeToken={storeToken} />
        </TabsContent>

        <TabsContent value="security">
          <SecurityTab profile={profile} queryClient={queryClient} />
        </TabsContent>

        <TabsContent value="appearance">
          <AppearanceTab />
        </TabsContent>
      </Tabs>
    </div>
  )
}

function AccountTab({ profile, queryClient, setAuth, storeUser, storeToken }: {
  profile: Profile | undefined
  queryClient: ReturnType<typeof useQueryClient>
  setAuth: (token: string, user: any) => void
  storeUser: any
  storeToken: string | null
}) {
  const [firstName, setFirstName] = useState(profile?.firstName ?? '')
  const [lastName, setLastName] = useState(profile?.lastName ?? '')
  const [nameLoaded, setNameLoaded] = useState(false)

  if (profile && !nameLoaded) {
    setFirstName(profile.firstName)
    setLastName(profile.lastName)
    setNameLoaded(true)
  }

  const updateProfileMutation = useMutation({
    mutationFn: (data: Record<string, unknown>) => api.patch<Profile>('/v1/auth/me', data),
    onSuccess: (updated) => {
      queryClient.invalidateQueries({ queryKey: ['auth', 'me'] })
      if (storeToken && storeUser) {
        setAuth(storeToken, { ...storeUser, firstName: updated.firstName, lastName: updated.lastName })
      }
      toast.success('Profile updated')
    },
    onError: (err) => toast.error(err.message),
  })

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-lg">Account</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {profile?.id && (
          <div className="flex items-center gap-4">
            <AvatarUpload entityType="user" entityId={profile.id} size="lg" />
            <div>
              <p className="font-medium">{profile.firstName} {profile.lastName}</p>
              <p className="text-sm text-muted-foreground">{profile.email}</p>
              {profile.employeeNumber && (
                <p className="text-xs text-muted-foreground">Employee #{profile.employeeNumber}</p>
              )}
            </div>
          </div>
        )}
        <div className="space-y-2">
          <Label>Email</Label>
          <Input value={profile?.email ?? ''} disabled className="opacity-60" />
        </div>
        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-2">
            <Label>First Name</Label>
            <Input value={firstName} onChange={(e) => setFirstName(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label>Last Name</Label>
            <Input value={lastName} onChange={(e) => setLastName(e.target.value)} />
          </div>
        </div>
        <Button
          onClick={() => updateProfileMutation.mutate({ firstName, lastName })}
          disabled={updateProfileMutation.isPending}
        >
          {updateProfileMutation.isPending ? 'Saving...' : 'Save'}
        </Button>
      </CardContent>
    </Card>
  )
}

function SecurityTab({ profile, queryClient }: {
  profile: Profile | undefined
  queryClient: ReturnType<typeof useQueryClient>
}) {
  const [currentPassword, setCurrentPassword] = useState('')
  const [newPassword, setNewPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')
  const [pin, setPin] = useState('')
  const [confirmPin, setConfirmPin] = useState('')

  const changePasswordMutation = useMutation({
    mutationFn: () => api.post('/v1/auth/change-password', { currentPassword, newPassword }),
    onSuccess: () => {
      setCurrentPassword('')
      setNewPassword('')
      setConfirmPassword('')
      toast.success('Password changed')
    },
    onError: (err) => toast.error(err.message),
  })

  const setPinMutation = useMutation({
    mutationFn: () => api.post('/v1/auth/set-pin', { pin }),
    onSuccess: () => {
      setPin('')
      setConfirmPin('')
      queryClient.invalidateQueries({ queryKey: ['auth', 'me'] })
      toast.success('PIN set')
    },
    onError: (err) => toast.error(err.message),
  })

  const removePinMutation = useMutation({
    mutationFn: () => api.del('/v1/auth/pin'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['auth', 'me'] })
      toast.success('PIN removed')
    },
    onError: (err) => toast.error(err.message),
  })

  function handlePasswordChange() {
    if (newPassword.length < 12) {
      toast.error('Password must be at least 12 characters')
      return
    }
    if (newPassword !== confirmPassword) {
      toast.error('Passwords do not match')
      return
    }
    changePasswordMutation.mutate()
  }

  function handleSetPin() {
    if (pin.length < 4 || pin.length > 6) {
      toast.error('PIN must be 4-6 digits')
      return
    }
    if (!/^\d+$/.test(pin)) {
      toast.error('PIN must be digits only')
      return
    }
    if (pin !== confirmPin) {
      toast.error('PINs do not match')
      return
    }
    setPinMutation.mutate()
  }

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Change Password</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label>Current Password</Label>
            <Input type="password" value={currentPassword} onChange={(e) => setCurrentPassword(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label>New Password</Label>
            <Input type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label>Confirm New Password</Label>
            <Input type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} />
          </div>
          <Button onClick={handlePasswordChange} disabled={changePasswordMutation.isPending}>
            {changePasswordMutation.isPending ? 'Changing...' : 'Change Password'}
          </Button>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-lg">POS PIN</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          {profile?.employeeNumber && (
            <p className="text-sm text-muted-foreground">
              Your employee number is <span className="font-mono font-medium text-foreground">{profile.employeeNumber}</span>.
              To unlock the POS, enter your employee number followed by your PIN.
            </p>
          )}
          {profile?.hasPin ? (
            <>
              <p className="text-sm text-muted-foreground">You have a PIN set. You can change or remove it below.</p>
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label>New PIN (4-6 digits)</Label>
                  <Input type="password" inputMode="numeric" maxLength={6} value={pin} onChange={(e) => setPin(e.target.value)} placeholder="****" />
                </div>
                <div className="space-y-2">
                  <Label>Confirm PIN</Label>
                  <Input type="password" inputMode="numeric" maxLength={6} value={confirmPin} onChange={(e) => setConfirmPin(e.target.value)} placeholder="****" />
                </div>
              </div>
              <div className="flex gap-2">
                <Button onClick={handleSetPin} disabled={setPinMutation.isPending}>
                  {setPinMutation.isPending ? 'Saving...' : 'Change PIN'}
                </Button>
                <Button variant="outline" onClick={() => removePinMutation.mutate()} disabled={removePinMutation.isPending}>
                  {removePinMutation.isPending ? 'Removing...' : 'Remove PIN'}
                </Button>
              </div>
            </>
          ) : (
            <>
              <p className="text-sm text-muted-foreground">Set a PIN to unlock the Point of Sale terminal.</p>
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label>PIN (4-6 digits)</Label>
                  <Input type="password" inputMode="numeric" maxLength={6} value={pin} onChange={(e) => setPin(e.target.value)} placeholder="****" />
                </div>
                <div className="space-y-2">
                  <Label>Confirm PIN</Label>
                  <Input type="password" inputMode="numeric" maxLength={6} value={confirmPin} onChange={(e) => setConfirmPin(e.target.value)} placeholder="****" />
                </div>
              </div>
              <Button onClick={handleSetPin} disabled={setPinMutation.isPending}>
                {setPinMutation.isPending ? 'Saving...' : 'Set PIN'}
              </Button>
            </>
          )}
        </CardContent>
      </Card>
    </div>
  )
}

function AppearanceTab() {
  const { mode, colorTheme, setMode, setColorTheme } = useThemeStore()

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-lg">Appearance</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="space-y-2">
          <Label>Mode</Label>
          <div className="flex gap-2">
            {[
              { value: 'light' as const, icon: Sun, label: 'Light' },
              { value: 'dark' as const, icon: Moon, label: 'Dark' },
              { value: 'system' as const, icon: Monitor, label: 'System' },
            ].map((m) => (
              <Button
                key={m.value}
                variant={mode === m.value ? 'default' : 'secondary'}
                size="sm"
                onClick={() => setMode(m.value)}
              >
                <m.icon className="mr-2 h-4 w-4" />
                {m.label}
              </Button>
            ))}
          </div>
        </div>

        <Separator />

        <div className="space-y-2">
          <Label>Color Theme</Label>
          <div className="flex gap-2 flex-wrap">
            {themes.map((t) => (
              <Button
                key={t.name}
                variant={colorTheme === t.name ? 'default' : 'secondary'}
                size="sm"
                onClick={() => setColorTheme(t.name)}
              >
                <span
                  className="mr-2 h-3 w-3 rounded-full border inline-block"
                  style={{ backgroundColor: `hsl(${t.light.primary})` }}
                />
                {t.label}
              </Button>
            ))}
          </div>
        </div>
      </CardContent>
    </Card>
  )
}
