import { useEffect, useState } from 'react'
import type { Product, CompleteDrone, KitBuild, Drone, Category, Currency } from '../types'
import { storeImage, resolveImage } from '../utils/imageCache'

const CATEGORIES: Category[] = [
  'frame', 'flight-controller', 'esc', 'motor', 'camera',
  'vtx', 'props', 'battery', 'charger', 'radio', 'receiver',
  'goggles', 'complete-drone', 'accessory',
]

const CURRENCIES: Currency[] = ['USD', 'EUR', 'GBP', 'SEK']

type ItemType = 'product' | 'complete-drone' | 'kit'

const inputStyle: React.CSSProperties = {
  background: 'var(--color-bg2)',
  color: 'var(--color-fg)',
  borderColor: 'var(--color-bg3)',
}

interface PartRow {
  tempId: string
  name: string
  brand: string
  category: Category
  amount: string
  currency: Currency
  asOf: string
  url: string
  image: string
}

interface Props {
  isDroneSection: boolean
  initialItem?: Product | Drone
  onSubmit: (item: Product | CompleteDrone | KitBuild) => void
  onClose: () => void
}

function today() { return new Date().toISOString().slice(0, 10) }

function emptyPart(): PartRow {
  return { tempId: crypto.randomUUID(), name: '', brand: '', category: 'frame', amount: '', currency: 'SEK', asOf: today(), url: '', image: '' }
}

function partFromProduct(p: Product): PartRow {
  return {
    tempId: crypto.randomUUID(),
    name: p.name,
    brand: p.brand ?? '',
    category: p.category,
    amount: String(p.price.amount),
    currency: p.price.currency,
    asOf: p.price.asOf,
    url: p.url ?? '',
    image: p.image ?? '',
  }
}

function initType(item: Product | Drone | undefined, isDroneSection: boolean): ItemType {
  if (!item) return isDroneSection ? 'complete-drone' : 'product'
  if ('buildType' in item) return item.buildType === 'kit' ? 'kit' : 'complete-drone'
  return 'product'
}

function fileToBase64(file: File): Promise<string> {
  return new Promise(resolve => {
    const reader = new FileReader()
    reader.onload = () => resolve(reader.result as string)
    reader.readAsDataURL(file)
  })
}

async function readImageFromClipboard(): Promise<string | null> {
  try {
    const items = await navigator.clipboard.read()
    for (const item of items) {
      const type = item.types.find(t => t.startsWith('image/'))
      if (type) {
        const blob = await item.getType(type)
        return fileToBase64(new File([blob], 'image', { type }))
      }
    }
  } catch {}
  return null
}

export function AddItemDialog({ isDroneSection, initialItem, onSubmit, onClose }: Props) {
  const editing = !!initialItem

  const [type, setType]         = useState<ItemType>(() => initType(initialItem, isDroneSection))
  const [name, setName]         = useState(() => initialItem?.name ?? '')
  const [brand, setBrand]       = useState(() => (initialItem as CompleteDrone | Product)?.brand ?? '')
  const [category, setCategory] = useState<Category>(() => (initialItem as Product)?.category ?? 'radio')
  const [amount, setAmount]     = useState(() => {
    if (!initialItem) return ''
    if ('buildType' in initialItem && initialItem.buildType === 'complete') return String(initialItem.price.amount)
    if (!('buildType' in initialItem)) return String(initialItem.price.amount)
    return ''
  })
  const [currency, setCurrency] = useState<Currency>(() => {
    if (!initialItem) return 'SEK'
    if ('buildType' in initialItem && initialItem.buildType === 'complete') return initialItem.price.currency
    if (!('buildType' in initialItem)) return initialItem.price.currency
    return 'SEK'
  })
  const [asOf, setAsOf]   = useState(() => {
    if (!initialItem) return today()
    if ('buildType' in initialItem && initialItem.buildType === 'complete') return initialItem.price.asOf
    if (!('buildType' in initialItem)) return initialItem.price.asOf
    return today()
  })
  const [url, setUrl]     = useState(() => (initialItem as Product | CompleteDrone | KitBuild)?.url ?? '')
  const [image, setImage] = useState('')
  const [note, setNote]   = useState(() => initialItem?.note ?? '')
  const [parts, setParts] = useState<PartRow[]>(() => {
    if (initialItem && 'buildType' in initialItem && initialItem.buildType === 'kit') {
      return initialItem.parts.length > 0 ? initialItem.parts.map(partFromProduct) : [emptyPart()]
    }
    return [emptyPart()]
  })

  // Resolve img: keys from cache when opening in edit mode
  useEffect(() => {
    if (!initialItem) return
    resolveImage(initialItem.image).then(v => setImage(v ?? ''))
    if ('buildType' in initialItem && initialItem.buildType === 'kit') {
      Promise.all(initialItem.parts.map(async p => ({
        ...p,
        image: (p.image ? await resolveImage(p.image) ?? p.image : ''),
      }))).then(resolved => setParts(resolved.map(p => ({
        tempId: crypto.randomUUID(),
        name: p.name,
        brand: p.brand ?? '',
        category: p.category,
        amount: String(p.price.amount),
        currency: p.price.currency,
        asOf: p.price.asOf,
        url: p.url ?? '',
        image: p.image ?? '',
      }))))
    }
  }, [])

  // Global paste → sets main item image (Ctrl+V anywhere in the dialog)
  useEffect(() => {
    async function onPaste(e: ClipboardEvent) {
      const item = Array.from(e.clipboardData?.items ?? []).find(i => i.type.startsWith('image/'))
      if (!item) return
      const file = item.getAsFile()
      if (!file) return
      setImage(await fileToBase64(file))
    }
    document.addEventListener('paste', onPaste)
    return () => document.removeEventListener('paste', onPaste)
  }, [])

  function updatePart(tempId: string, patch: Partial<PartRow>) {
    setParts(prev => prev.map(p => p.tempId === tempId ? { ...p, ...patch } : p))
  }

  async function pastePart(tempId: string) {
    const result = await readImageFromClipboard()
    if (result) updatePart(tempId, { image: result })
  }

  async function handleImageFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (!file) return
    setImage(await fileToBase64(file))
  }

  async function handlePartImageFile(tempId: string, e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0]
    if (!file) return
    updatePart(tempId, { image: await fileToBase64(file) })
  }

  async function submit(e: React.FormEvent) {
    e.preventDefault()
    const id = initialItem?.id ?? crypto.randomUUID()
    const storedImage = image ? await storeImage(image) : undefined
    const common = { image: storedImage, note: note || undefined, url: url || undefined }

    if (type === 'kit') {
      const builtParts = await Promise.all(parts.filter(p => p.name).map(async p => ({
        id: crypto.randomUUID(),
        name: p.name,
        brand: p.brand || undefined,
        category: p.category,
        price: { amount: parseFloat(p.amount) || 0, currency: p.currency, asOf: p.asOf },
        url: p.url || undefined,
        image: p.image ? await storeImage(p.image) : undefined,
      })))
      onSubmit({ id, buildType: 'kit', name, ...common, parts: builtParts })
    } else if (type === 'complete-drone') {
      onSubmit({ id, buildType: 'complete', name, brand: brand || undefined, price: { amount: parseFloat(amount) || 0, currency, asOf }, ...common })
    } else {
      onSubmit({ id, name, brand: brand || undefined, category, price: { amount: parseFloat(amount) || 0, currency, asOf }, ...common })
    }
    onClose()
  }

  const labelCls = 'block text-xs mb-1'
  const inputCls = 'w-full rounded border px-2 py-1.5 text-sm outline-none'
  const fieldCls = 'flex flex-col'

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center p-4"
      style={{ background: 'rgba(0,0,0,0.6)' }}
      onClick={e => e.target === e.currentTarget && onClose()}
    >
      <div
        className="w-full max-w-lg rounded-lg border p-0"
        style={{ background: 'var(--color-bg1)', borderColor: 'var(--color-bg3)', color: 'var(--color-fg)', maxHeight: '90vh', overflowY: 'auto' }}
      >
        <form onSubmit={submit}>
          <div className="flex items-center justify-between border-b px-4 py-3" style={{ borderColor: 'var(--color-bg3)' }}>
            <h2 className="font-medium">{editing ? 'Edit item' : 'Add item'}</h2>
            <button type="button" onClick={onClose} style={{ color: 'var(--color-grey)' }}>✕</button>
          </div>

          <div className="flex flex-col gap-4 p-4">
            {isDroneSection && (
              <div className={fieldCls}>
                <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Type</label>
                <select value={type} onChange={e => setType(e.target.value as ItemType)} className={inputCls} style={inputStyle}>
                  <option value="complete-drone">Complete drone</option>
                  <option value="kit">Kit build (parts list)</option>
                </select>
              </div>
            )}

            <div className={fieldCls}>
              <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Name *</label>
              <input required value={name} onChange={e => setName(e.target.value)} className={inputCls} style={inputStyle} placeholder="e.g. BetaFPV Cetus X" />
            </div>

            {type !== 'kit' && (
              <div className={fieldCls}>
                <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Brand</label>
                <input value={brand} onChange={e => setBrand(e.target.value)} className={inputCls} style={inputStyle} placeholder="e.g. BetaFPV" />
              </div>
            )}

            {type === 'product' && (
              <div className={fieldCls}>
                <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Category</label>
                <select value={category} onChange={e => setCategory(e.target.value as Category)} className={inputCls} style={inputStyle}>
                  {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
                </select>
              </div>
            )}

            {type !== 'kit' && (
              <div className="grid grid-cols-3 gap-2">
                <div className={fieldCls}>
                  <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Amount</label>
                  <input required value={amount} onChange={e => setAmount(e.target.value)} type="number" min="0" step="0.01" className={inputCls} style={inputStyle} placeholder="0.00" />
                </div>
                <div className={fieldCls}>
                  <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Currency</label>
                  <select value={currency} onChange={e => setCurrency(e.target.value as Currency)} className={inputCls} style={inputStyle}>
                    {CURRENCIES.map(c => <option key={c} value={c}>{c}</option>)}
                  </select>
                </div>
                <div className={fieldCls}>
                  <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Price as of</label>
                  <input value={asOf} onChange={e => setAsOf(e.target.value)} type="date" className={inputCls} style={inputStyle} />
                </div>
              </div>
            )}

            {/* Main item image */}
            <div className={fieldCls}>
              <label className={labelCls} style={{ color: 'var(--color-grey)' }}>
                Image
                <span className="ml-2 font-normal" style={{ color: 'var(--color-grey-dim)' }}>— Ctrl+V anywhere to paste</span>
              </label>
              <div className="flex items-center gap-2">
                <input type="file" accept="image/*" onChange={handleImageFile} className="text-sm" style={{ color: 'var(--color-grey)' }} />
                {image && (
                  <button type="button" onClick={() => setImage('')} className="text-xs" style={{ color: 'var(--color-grey)' }}>
                    ✕ clear
                  </button>
                )}
              </div>
              {image && <img src={image} alt="preview" className="mt-2 h-20 w-20 rounded object-cover" />}
            </div>

            {type !== 'kit' && (
              <div className={fieldCls}>
                <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Store URL</label>
                <input value={url} onChange={e => setUrl(e.target.value)} className={inputCls} style={inputStyle} placeholder="https://..." />
              </div>
            )}

            {type === 'kit' && (
              <>
                <div className={fieldCls}>
                  <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Build guide URL</label>
                  <input value={url} onChange={e => setUrl(e.target.value)} className={inputCls} style={inputStyle} placeholder="https://..." />
                </div>

                <div className="flex flex-col gap-2">
                  <div className="flex items-center justify-between">
                    <span className="text-xs" style={{ color: 'var(--color-grey)' }}>Parts</span>
                    <button type="button" onClick={() => setParts(p => [...p, emptyPart()])} className="text-xs" style={{ color: 'var(--color-cyan)' }}>
                      + Add part
                    </button>
                  </div>

                  {parts.map((part, i) => (
                    <div key={part.tempId} className="flex flex-col gap-2 rounded border p-2" style={{ borderColor: 'var(--color-bg3)' }}>
                      <div className="flex items-center justify-between">
                        <span className="text-xs" style={{ color: 'var(--color-grey)' }}>Part {i + 1}</span>
                        {parts.length > 1 && (
                          <button type="button" onClick={() => setParts(p => p.filter(r => r.tempId !== part.tempId))} className="text-xs" style={{ color: 'var(--color-grey)' }}>✕</button>
                        )}
                      </div>
                      <div className="grid grid-cols-2 gap-2">
                        <input value={part.name}  onChange={e => updatePart(part.tempId, { name: e.target.value })}  placeholder="Name"  className={inputCls} style={inputStyle} />
                        <input value={part.brand} onChange={e => updatePart(part.tempId, { brand: e.target.value })} placeholder="Brand" className={inputCls} style={inputStyle} />
                      </div>
                      <div className="grid grid-cols-3 gap-2">
                        <select value={part.category} onChange={e => updatePart(part.tempId, { category: e.target.value as Category })} className={inputCls} style={inputStyle}>
                          {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
                        </select>
                        <input value={part.amount} onChange={e => updatePart(part.tempId, { amount: e.target.value })} type="number" min="0" step="0.01" placeholder="Price" className={inputCls} style={inputStyle} />
                        <select value={part.currency} onChange={e => updatePart(part.tempId, { currency: e.target.value as Currency })} className={inputCls} style={inputStyle}>
                          {CURRENCIES.map(c => <option key={c} value={c}>{c}</option>)}
                        </select>
                      </div>
                      <input value={part.url} onChange={e => updatePart(part.tempId, { url: e.target.value })} placeholder="Store URL (optional)" className={inputCls} style={inputStyle} />

                      {/* Part image */}
                      <div className="flex items-center gap-2">
                        {part.image
                          ? <img src={part.image} alt="part" className="h-10 w-10 rounded object-cover" />
                          : <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded text-xs" style={{ background: 'var(--color-bg3)', color: 'var(--color-grey)' }}>img</div>
                        }
                        <input
                          type="file"
                          accept="image/*"
                          onChange={e => handlePartImageFile(part.tempId, e)}
                          className="text-xs"
                          style={{ color: 'var(--color-grey)' }}
                        />
                        <button
                          type="button"
                          onClick={() => pastePart(part.tempId)}
                          className="shrink-0 rounded px-2 py-1 text-xs"
                          style={{ background: 'var(--color-bg2)', color: 'var(--color-grey)' }}
                          title="Paste image from clipboard"
                        >
                          Paste
                        </button>
                        {part.image && (
                          <button type="button" onClick={() => updatePart(part.tempId, { image: '' })} className="text-xs" style={{ color: 'var(--color-grey)' }}>✕</button>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </>
            )}

            <div className={fieldCls}>
              <label className={labelCls} style={{ color: 'var(--color-grey)' }}>Note</label>
              <input value={note} onChange={e => setNote(e.target.value)} className={inputCls} style={inputStyle} placeholder="e.g. best beginner choice" />
            </div>
          </div>

          <div className="flex justify-end gap-2 border-t px-4 py-3" style={{ borderColor: 'var(--color-bg3)' }}>
            <button type="button" onClick={onClose} className="rounded px-3 py-1.5 text-sm" style={{ background: 'var(--color-bg2)', color: 'var(--color-grey)' }}>
              Cancel
            </button>
            <button type="submit" className="rounded px-3 py-1.5 text-sm font-medium" style={{ background: 'var(--color-yellow)', color: 'var(--color-black)' }}>
              {editing ? 'Save' : 'Add'}
            </button>
          </div>
        </form>
      </div>
    </div>
  )
}
