import { useState } from 'react'
import { format } from 'date-fns'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
  guessDateFromPath,
  type DateGuess,
} from '../../lib/guessDateFromPath'
import type { Photo } from '../../types/photo'

interface BulkTakenAtEditorProps {
  disabled: boolean
  selectedCount: number
  collectPhotos: () => Photo[]
  onApplyUniform: (iso: string) => void
  onApplyMap: (map: Record<string, string>) => void
}

/** Bulk Date Taken sub-panel used by RightSidebar in multi-select mode.
 *  Two modes share one UI:
 *    1. Apply-one: user types a datetime, clicks Apply, every selected
 *       photo is rewritten to that date.
 *    2. Guess-from-path: we run `guessDateFromPath` against each selected
 *       photo's filepath, show a preview of the hits + misses, and let
 *       the user commit the per-photo map in one round-trip. */
export function BulkTakenAtEditor({
  disabled,
  selectedCount,
  collectPhotos,
  onApplyUniform,
  onApplyMap,
}: BulkTakenAtEditorProps) {
  const [uniformDraft, setUniformDraft] = useState('')
  const [preview, setPreview] = useState<
    | {
        hits: { photo: Photo; guess: DateGuess }[]
        misses: Photo[]
      }
    | null
  >(null)

  const handleGuess = () => {
    const photos = collectPhotos()
    const hits: { photo: Photo; guess: DateGuess }[] = []
    const misses: Photo[] = []
    for (const p of photos) {
      const g = guessDateFromPath(p.filepath)
      if (g) hits.push({ photo: p, guess: g })
      else misses.push(p)
    }
    setPreview({ hits, misses })
  }

  const handleApplyPreview = () => {
    if (!preview) return
    const map: Record<string, string> = {}
    for (const { photo, guess } of preview.hits) {
      map[photo.id] = guess.date.toISOString()
    }
    if (Object.keys(map).length === 0) return
    onApplyMap(map)
    setPreview(null)
  }

  const handleApplyUniform = () => {
    if (!uniformDraft) return
    const parsed = new Date(uniformDraft)
    if (Number.isNaN(parsed.getTime())) return
    onApplyUniform(parsed.toISOString())
  }

  return (
    <div className="space-y-2">
      {/* Apply-one row */}
      <div className="flex items-center gap-1.5">
        <Input
          type="datetime-local"
          value={uniformDraft}
          onChange={(e) => setUniformDraft(e.target.value)}
          disabled={disabled}
          className="h-7 flex-1 text-xs"
        />
        <Button
          size="sm"
          onClick={handleApplyUniform}
          disabled={disabled || !uniformDraft}
          className="bg-primary/20 text-primary hover:bg-primary/30"
          title={`Apply this date to all ${selectedCount} selected`}
        >
          Apply
        </Button>
      </div>

      {/* Guess-from-path preview */}
      {preview === null ? (
        <Button
          variant="outline"
          size="sm"
          onClick={handleGuess}
          disabled={disabled}
          className="w-full border-dashed border-primary/50 bg-transparent text-primary hover:bg-primary/10"
          title="Scan each photo's folder + filename for a date pattern"
        >
          Guess from folder paths
        </Button>
      ) : (
        <div className="rounded border border-border bg-bg p-2 text-[11px]">
          <div className="mb-1.5 text-text-muted">
            {preview.hits.length} will update ·{' '}
            {preview.misses.length} skipped
          </div>
          {preview.hits.length > 0 && (
            <ul className="mb-1.5 max-h-24 space-y-0.5 overflow-y-auto font-mono text-[10px] text-text">
              {preview.hits.slice(0, 5).map(({ photo, guess }) => (
                <li key={photo.id} className="truncate" title={photo.filepath}>
                  <span className="text-text-muted">{photo.filename}</span>
                  {' → '}
                  <span className="text-primary">
                    {format(guess.date, 'yyyy-MM-dd')}
                  </span>
                </li>
              ))}
              {preview.hits.length > 5 && (
                <li className="text-text-muted">
                  …and {preview.hits.length - 5} more
                </li>
              )}
            </ul>
          )}
          <div className="flex gap-1.5">
            <Button
              size="sm"
              onClick={handleApplyPreview}
              disabled={disabled || preview.hits.length === 0}
              className="flex-1 bg-primary/20 text-primary hover:bg-primary/30"
            >
              Apply {preview.hits.length}
            </Button>
            <Button
              variant="secondary"
              size="sm"
              onClick={() => setPreview(null)}
              disabled={disabled}
              className="text-text-muted"
            >
              Cancel
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}
