import { useRef, useState } from 'react'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { queryOptions } from '@tanstack/react-query'
import { api } from '@/lib/api-client'
import { useAuthStore } from '@/stores/auth.store'
import { Button } from '@/components/ui/button'
import { Camera, User } from 'lucide-react'
import { toast } from 'sonner'

interface FileRecord {
  id: string
  path: string
  url: string
  filename: string
}

function entityFilesOptions(entityType: string, entityId: string) {
  return queryOptions({
    queryKey: ['files', entityType, entityId],
    queryFn: () => api.get<{ data: FileRecord[] }>('/v1/files', { entityType, entityId }),
    enabled: !!entityId,
  })
}

interface AvatarUploadProps {
  entityType: 'user' | 'member' | 'company'
  entityId: string
  size?: 'sm' | 'md' | 'lg'
  category?: string
  placeholderIcon?: React.ComponentType<{ className?: string }>
}

const sizeClasses = {
  sm: 'h-8 w-8',
  md: 'h-16 w-16',
  lg: 'h-24 w-24',
}

const iconSizes = {
  sm: 'h-4 w-4',
  md: 'h-8 w-8',
  lg: 'h-12 w-12',
}

export function AvatarUpload({ entityType, entityId, size = 'lg', category = 'profile', placeholderIcon: PlaceholderIcon }: AvatarUploadProps) {
  const queryClient = useQueryClient()
  const token = useAuthStore((s) => s.token)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [uploading, setUploading] = useState(false)
  const IconComponent = PlaceholderIcon ?? User

  const { data: filesData } = useQuery(entityFilesOptions(entityType, entityId))

  // Find image by category
  const profileFile = filesData?.data?.find((f) => f.path.includes(`/${category}-`))
  const imageUrl = profileFile ? `/v1/files/serve/${profileFile.path}` : null

  async function handleUpload(file: File) {
    setUploading(true)
    try {
      const formData = new FormData()
      formData.append('file', file)
      formData.append('entityType', entityType)
      formData.append('entityId', entityId)
      formData.append('category', category)

      // Delete existing profile image first
      if (profileFile) {
        await api.del(`/v1/files/${profileFile.id}`)
      }

      const res = await fetch('/v1/files', {
        method: 'POST',
        headers: { Authorization: `Bearer ${token}` },
        body: formData,
      })

      if (!res.ok) {
        const err = await res.json()
        throw new Error(err.error?.message ?? 'Upload failed')
      }

      queryClient.invalidateQueries({ queryKey: ['files', entityType, entityId] })
      toast.success('Profile picture updated')
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Upload failed')
    } finally {
      setUploading(false)
    }
  }

  function handleFileSelect(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (file) handleUpload(file)
    // Reset input so same file can be re-selected
    e.target.value = ''
  }

  return (
    <div className="relative inline-block">
      <div
        className={`${sizeClasses[size]} rounded-full bg-muted flex items-center justify-center overflow-hidden border-2 border-border`}
      >
        {imageUrl ? (
          <img
            src={imageUrl}
            alt="Profile"
            className="h-full w-full object-cover"
          />
        ) : (
          <IconComponent className={`${iconSizes[size]} text-muted-foreground`} />
        )}
      </div>
      <Button
        variant="secondary"
        size="sm"
        className="absolute -bottom-1 -right-1 h-7 w-7 rounded-full p-0"
        onClick={() => fileInputRef.current?.click()}
        disabled={uploading}
      >
        <Camera className="h-3.5 w-3.5" />
      </Button>
      <input
        ref={fileInputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp"
        className="hidden"
        onChange={handleFileSelect}
      />
    </div>
  )
}

/** Display-only avatar (no upload button) */
export function Avatar({ entityType, entityId, size = 'sm' }: AvatarUploadProps) {
  const { data: filesData } = useQuery(entityFilesOptions(entityType, entityId))
  const profileFile = filesData?.data?.find((f) => f.path.includes('/profile-'))
  const imageUrl = profileFile ? `/v1/files/serve/${profileFile.path}` : null

  return (
    <div className={`${sizeClasses[size]} rounded-full bg-muted flex items-center justify-center overflow-hidden`}>
      {imageUrl ? (
        <img src={imageUrl} alt="Profile" className="h-full w-full object-cover" />
      ) : (
        <User className={`${iconSizes[size]} text-muted-foreground`} />
      )}
    </div>
  )
}
