import { useState, useEffect } from 'react'
import { useQuery } from '@tanstack/react-query'
import { queryOptions } from '@tanstack/react-query'
import { repairNoteListOptions } from '@/api/repairs'
import { api } from '@/lib/api-client'
import { useAuthStore } from '@/stores/auth.store'
import { generateAndUploadPdf } from './generate-pdf'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
import { FileText, Download, Check, Eye } from 'lucide-react'
import { toast } from 'sonner'
import type { RepairTicket, RepairLineItem } from '@/types/repair'

interface FileRecord {
  id: string
  path: string
  filename: string
  category: 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,
  })
}

interface PdfModalProps {
  ticket: RepairTicket
  lineItems: RepairLineItem[]
  ticketId: string
}

export function PdfModal({ ticket, lineItems, ticketId }: PdfModalProps) {
  const [open, setOpen] = useState(false)
  const [generating, setGenerating] = useState(false)
  const token = useAuthStore((s) => s.token)

  // Fetch notes and photos
  const { data: notesData } = useQuery(repairNoteListOptions(ticketId))
  const { data: filesData } = useQuery(ticketFilesOptions(ticketId))

  const allNotes = notesData?.data ?? []
  const customerNotes = allNotes.filter((n) => n.visibility === 'customer')
  const allPhotos = (filesData?.data ?? []).filter((f) => f.category !== 'document')

  // Selection state
  const [selectedNoteIds, setSelectedNoteIds] = useState<Set<string>>(new Set())
  const [selectedPhotoIds, setSelectedPhotoIds] = useState<Set<string>>(new Set())
  const [includeLineItems, setIncludeLineItems] = useState(true)

  // Default: select all customer-visible notes and completed photos
  useEffect(() => {
    if (open) {
      setSelectedNoteIds(new Set(customerNotes.map((n) => n.id)))
      const completedPhotos = allPhotos.filter((p) => p.category === 'completed')
      setSelectedPhotoIds(new Set(completedPhotos.length > 0 ? completedPhotos.map((p) => p.id) : []))
      setIncludeLineItems(true)
    }
  }, [open, notesData, filesData])

  function toggleNote(id: string) {
    setSelectedNoteIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) { next.delete(id) } else { next.add(id) }
      return next
    })
  }

  function togglePhoto(id: string) {
    setSelectedPhotoIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) { next.delete(id) } else { next.add(id) }
      return next
    })
  }

  function selectAllNotes() {
    setSelectedNoteIds(new Set(customerNotes.map((n) => n.id)))
  }

  function selectNone() {
    setSelectedNoteIds(new Set())
  }

  async function handleGenerate() {
    setGenerating(true)
    try {
      const selectedNotes = allNotes.filter((n) => selectedNoteIds.has(n.id))
      await generateAndUploadPdf(
        {
          ticket,
          lineItems: includeLineItems ? lineItems : [],
          notes: selectedNotes,
          includeNotes: selectedNotes.length > 0,
        },
        ticketId,
        token,
      )
      toast.success('PDF generated and saved to documents')
      setOpen(false)
    } catch {
      toast.error('Failed to generate PDF')
    } finally {
      setGenerating(false)
    }
  }

  function formatDate(dateStr: string) {
    return new Date(dateStr).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button variant="outline" size="sm">
          <FileText className="mr-2 h-4 w-4" />PDF
        </Button>
      </DialogTrigger>
      <DialogContent className="max-w-lg max-h-[80vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>Generate PDF — Ticket #{ticket.ticketNumber}</DialogTitle>
        </DialogHeader>

        <div className="space-y-5">
          {/* Line Items toggle */}
          <div>
            <button
              type="button"
              onClick={() => setIncludeLineItems(!includeLineItems)}
              className={`flex items-center gap-2 w-full text-left px-3 py-2 rounded-md border text-sm transition-colors ${
                includeLineItems ? 'border-primary bg-primary/5' : 'border-border'
              }`}
            >
              <div className={`h-4 w-4 rounded border flex items-center justify-center ${includeLineItems ? 'bg-primary border-primary' : 'border-muted-foreground/40'}`}>
                {includeLineItems && <Check className="h-3 w-3 text-primary-foreground" />}
              </div>
              <span className="font-medium">Include Line Items</span>
              <span className="text-muted-foreground ml-auto">{lineItems.length} items</span>
            </button>
          </div>

          {/* Notes selection */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-sm font-medium">Customer Notes</Label>
              <div className="flex gap-1">
                <button type="button" onClick={selectAllNotes} className="text-xs text-primary hover:underline">All</button>
                <span className="text-xs text-muted-foreground">|</span>
                <button type="button" onClick={selectNone} className="text-xs text-primary hover:underline">None</button>
              </div>
            </div>
            {customerNotes.length === 0 ? (
              <p className="text-xs text-muted-foreground py-2">No customer-visible notes</p>
            ) : (
              <div className="space-y-1.5 max-h-40 overflow-y-auto">
                {customerNotes.map((note) => (
                  <button
                    key={note.id}
                    type="button"
                    onClick={() => toggleNote(note.id)}
                    className={`flex items-start gap-2 w-full text-left px-3 py-2 rounded-md border text-sm transition-colors ${
                      selectedNoteIds.has(note.id) ? 'border-primary bg-primary/5' : 'border-border'
                    }`}
                  >
                    <div className={`h-4 w-4 rounded border flex-shrink-0 mt-0.5 flex items-center justify-center ${selectedNoteIds.has(note.id) ? 'bg-primary border-primary' : 'border-muted-foreground/40'}`}>
                      {selectedNoteIds.has(note.id) && <Check className="h-3 w-3 text-primary-foreground" />}
                    </div>
                    <div className="min-w-0">
                      <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
                        <span>{note.authorName}</span>
                        <span>{formatDate(note.createdAt)}</span>
                        <Badge variant="secondary" className="text-[9px] px-1 py-0 gap-0.5">
                          <Eye className="h-2 w-2" />Customer
                        </Badge>
                      </div>
                      <p className="text-xs mt-0.5 line-clamp-2">{note.content}</p>
                    </div>
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* Photos selection */}
          {allPhotos.length > 0 && (
            <div className="space-y-2">
              <Label className="text-sm font-medium">Photos ({selectedPhotoIds.size} selected)</Label>
              <div className="grid grid-cols-5 gap-2 max-h-40 overflow-y-auto">
                {allPhotos.map((photo) => (
                  <button
                    key={photo.id}
                    type="button"
                    onClick={() => togglePhoto(photo.id)}
                    className={`relative rounded-md border-2 overflow-hidden transition-colors ${
                      selectedPhotoIds.has(photo.id) ? 'border-primary' : 'border-transparent'
                    }`}
                  >
                    <AuthThumbnail path={photo.path} />
                    {selectedPhotoIds.has(photo.id) && (
                      <div className="absolute top-0.5 right-0.5 h-4 w-4 rounded-full bg-primary flex items-center justify-center">
                        <Check className="h-2.5 w-2.5 text-primary-foreground" />
                      </div>
                    )}
                    <div className="absolute bottom-0 left-0 right-0 bg-black/50 text-[8px] text-white px-1 py-0.5 text-center">
                      {photo.category}
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Summary */}
          <div className="text-xs text-muted-foreground border-t pt-3">
            PDF will include: ticket details, {includeLineItems ? `${lineItems.length} line items` : 'no line items'}, {selectedNoteIds.size} notes{selectedPhotoIds.size > 0 ? `, ${selectedPhotoIds.size} photos` : ''}
          </div>

          {/* Generate button */}
          <div className="flex gap-2">
            <Button onClick={handleGenerate} disabled={generating} className="flex-1">
              <Download className="mr-2 h-4 w-4" />
              {generating ? 'Generating...' : 'Generate & Download PDF'}
            </Button>
            <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  )
}

function AuthThumbnail({ path }: { path: string }) {
  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="h-14 w-full bg-muted animate-pulse rounded" />
  return <img src={src} alt="" className="h-14 w-full object-cover" />
}
