import { useRef, useState, useEffect } 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 { Button } from '@/components/ui/button'
import { FileText, Plus, Trash2 } from 'lucide-react'
import { toast } from 'sonner'

function AuthImage({ path, alt, className, onClick }: { path: string; alt: string; className?: string; onClick?: () => void }) {
  const token = useAuthStore((s) => s.token)
  const [src, setSrc] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    let blobUrl: string | null = null
    async function load() {
      try {
        const res = await fetch(`/v1/files/serve/${path}`, {
          headers: token ? { Authorization: `Bearer ${token}` } : {},
        })
        if (!res.ok || cancelled) return
        const blob = await res.blob()
        if (!cancelled) {
          blobUrl = URL.createObjectURL(blob)
          setSrc(blobUrl)
        }
      } catch { /* ignore */ }
    }
    load()
    return () => {
      cancelled = true
      if (blobUrl) URL.revokeObjectURL(blobUrl)
    }
  }, [path, token])

  if (!src) return <div className={`${className} bg-muted animate-pulse`} />
  return <img src={src} alt={alt} className={className} onClick={onClick} />
}

async function openSignedFile(fileId: string) {
  try {
    const res = await api.get<{ url: string }>(`/v1/files/signed-url/${fileId}`)
    window.open(res.url, '_blank')
  } catch {
    toast.error('Failed to open file')
  }
}

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

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

const PHOTO_CATEGORIES = [
  { key: 'intake', label: 'Intake Photos', description: 'Condition at intake' },
  { key: 'in_progress', label: 'Work in Progress', description: 'During repair' },
  { key: 'completed', label: 'Completed', description: 'Final result' },
  { key: 'document', label: 'Documents', description: 'Signed approvals, quotes, receipts' },
] as const

interface TicketPhotosProps {
  ticketId: string
  currentStatus: string
}

export function TicketPhotos({ ticketId, currentStatus }: TicketPhotosProps) {
  const queryClient = useQueryClient()
  const token = useAuthStore((s) => s.token)
  const { data: filesData } = useQuery(ticketFilesOptions(ticketId))

  const files = filesData?.data ?? []

  // Determine which category to highlight based on current status
  const activeCategory =
    ['in_progress', 'pending_parts'].includes(currentStatus) ? 'in_progress'
    : ['ready', 'picked_up', 'delivered'].includes(currentStatus) ? 'completed'
    : 'intake'

  return (
    <div className="space-y-4">
      {PHOTO_CATEGORIES.map((cat) => (
        <PhotoSection
          key={cat.key}
          ticketId={ticketId}
          category={cat.key}
          label={cat.label}
          description={cat.description}
          photos={files.filter((f) => f.category === cat.key)}
          isActive={activeCategory === cat.key}
          token={token}
          onUpdate={() => queryClient.invalidateQueries({ queryKey: ['files', 'repair_ticket', ticketId] })}
        />
      ))}
    </div>
  )
}

function PhotoSection({
  ticketId,
  category,
  label,
  description,
  photos,
  isActive,
  token,
  onUpdate,
}: {
  ticketId: string
  category: string
  label: string
  description: string
  photos: FileRecord[]
  isActive: boolean
  token: string | null
  onUpdate: () => void
}) {
  const fileInputRef = useRef<HTMLInputElement>(null)

  const deleteMutation = useMutation({
    mutationFn: (fileId: string) => api.del(`/v1/files/${fileId}`),
    onSuccess: () => {
      onUpdate()
      toast.success('Photo removed')
    },
    onError: (err) => toast.error(err.message),
  })

  async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const files = Array.from(e.target.files ?? [])
    for (const file of files) {
      const formData = new FormData()
      formData.append('file', file)
      formData.append('entityType', 'repair_ticket')
      formData.append('entityId', ticketId)
      formData.append('category', category)

      try {
        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')
        }
      } catch (err) {
        toast.error(err instanceof Error ? err.message : 'Upload failed')
      }
    }
    onUpdate()
    toast.success(`${files.length} photo(s) uploaded`)
    e.target.value = ''
  }

  return (
    <div className={`rounded-md border p-3 ${isActive ? 'border-primary/50 bg-primary/5' : ''}`}>
      <div className="flex items-center justify-between mb-2">
        <div>
          <h4 className="text-sm font-semibold">{label}</h4>
          <p className="text-xs text-muted-foreground">{description}</p>
        </div>
        <Button variant="ghost" size="sm" onClick={() => fileInputRef.current?.click()}>
          <Plus className="mr-1 h-3 w-3" />Add
        </Button>
      </div>

      {photos.length === 0 ? (
        <p className="text-xs text-muted-foreground py-2">No photos</p>
      ) : (
        <div className="flex flex-wrap gap-2">
          {photos.map((photo) => {
            const isPdf = photo.filename?.endsWith('.pdf') || photo.path?.endsWith('.pdf')
            return (
              <div key={photo.id} className="relative group">
                {isPdf ? (
                  <button
                    type="button"
                    onClick={() => openSignedFile(photo.id)}
                    className="h-20 w-20 rounded-md border flex flex-col items-center justify-center bg-muted hover:bg-muted/80 transition-colors cursor-pointer"
                  >
                    <FileText className="h-6 w-6 text-muted-foreground" />
                    <span className="text-[9px] text-muted-foreground mt-1 px-1 truncate max-w-full">{photo.filename}</span>
                  </button>
                ) : (
                  <button type="button" onClick={() => openSignedFile(photo.id)}>
                    <AuthImage
                      path={photo.path}
                      alt={photo.filename}
                      className="h-20 w-20 object-cover rounded-md border cursor-pointer hover:opacity-80 transition-opacity"
                    />
                  </button>
                )}
                <button
                  type="button"
                  className="absolute -top-1.5 -right-1.5 h-5 w-5 rounded-full bg-destructive text-destructive-foreground flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
                  onClick={() => deleteMutation.mutate(photo.id)}
                >
                  <Trash2 className="h-3 w-3" />
                </button>
              </div>
            )
          })}
        </div>
      )}

      <input
        ref={fileInputRef}
        type="file"
        accept={category === 'document' ? 'image/jpeg,image/png,image/webp,application/pdf' : 'image/jpeg,image/png,image/webp'}
        multiple
        className="hidden"
        onChange={handleUpload}
      />
    </div>
  )
}
