"use client"

import { useState, useRef } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Progress } from "@/components/ui/progress"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Upload, Loader2, AlertCircle } from "lucide-react"
import type { DetectionData, DetectionType } from "@/types"

import { videoService } from "@/services/api"
const API_URL = process.env.NEXT_PUBLIC_API_URL
const WS_URL = API_URL?.replace(/^https:\/\//, "wss://").replace(/^http:\/\//, "ws://")

const DETECTION_TYPES = [
  { value: "pothole-detection", label: "Pothole Detection" },
  { value: "sign-board-detection", label: "Signboard Detection" },
  { value: "pot-sign-detection", label: "Pothole & Signboard Detection" },
] as const

const DETECTION_METHODS = [
  { value: "yolo", label: "YOLO" },
  { value: "yolo_vl", label: "YOLO with VL" },
  { value: "sam3", label: "SAM 3" },
  { value: "yoloe", label: "YOLOE" },
  { value: "yoloe_trained_vl", label: "YOLOE Trained" },
] as const

type UploadSectionProps = {
  onDetectionComplete: (data: DetectionData, videoId: string, file: File) => void
  onDetectionTypeChange: (type: DetectionType) => void
}

export function UploadSection({ onDetectionComplete, onDetectionTypeChange }: UploadSectionProps) {
  const [file, setFile] = useState<File | null>(null)
  const [jsonFile, setJsonFile] = useState<File | null>(null)
  const [speed, setSpeed] = useState(30)
  const [detectionType, setDetectionType] = useState<DetectionType>("pothole-detection")
  const [selectMethod, setSelectMethod] = useState("yolo_vl")
  const [uploading, setUploading] = useState(false)
  const [progress, setProgress] = useState(0)
  const [statusMessage, setStatusMessage] = useState("")
  const [error, setError] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const jsonFileInputRef = useRef<HTMLInputElement>(null)
  const wsRef = useRef<WebSocket | null>(null)

  const handleDetectionTypeChange = (value: DetectionType) => {
    setDetectionType(value)
    onDetectionTypeChange(value)
  }

  const connectWebSocket = (videoId: string) => {
    console.log("[Upload] Connecting WebSocket for video:", videoId)

    const ws = new WebSocket(`${WS_URL}/ws/${videoId}`)
    wsRef.current = ws

    ws.onopen = () => {
      console.log("[Upload] WebSocket connected")
      setError(null)
    }

    ws.onmessage = (event) => {
      const data = JSON.parse(event.data)
      console.log("[Upload] WebSocket message:", data)

      if (data.type === "progress" || data.progress !== undefined) {
        const progressValue = data.progress || 0
        setProgress(progressValue)

        let message = data.message || "Processing..."

        // Handle both pothole and signboard progress messages
        if (data.unique_potholes !== undefined) {
          message += ` | Unique: ${data.unique_potholes} | Total: ${data.total_detections || 0}`
        } else if (data.unique_signboards !== undefined) {
          message += ` | Unique: ${data.unique_signboards} | Total: ${data.total_detections || 0}`
        }

        setStatusMessage(message)
      }

      if (data.type === "complete" || data.status === "completed") {
        setStatusMessage("Processing completed! Loading results...")
        ws.close()
        setTimeout(() => loadResults(videoId), 500)
      }

      if (data.type === "error") {
        setError("Error: " + data.message)
        setStatusMessage("")
        setUploading(false)
        ws.close()
      }
    }

    ws.onerror = (error) => {
      console.error("[Upload] WebSocket error:", error)
      setStatusMessage("Connection error. Retrying...")
    }

    ws.onclose = () => {
      console.log("[Upload] WebSocket closed")
    }
  }

  const loadResults = async (videoId: string) => {
    try {
      console.log("[Upload] Loading results for:", videoId)
      const detectionData: DetectionData = await videoService.getVideoResults(videoId);
      console.log("[Upload] Results loaded:", detectionData)

      setUploading(false)
      setProgress(100)
      setStatusMessage("✓ Complete!")
      setError(null)

      // Pass detection data, video_id, and the original file
      if (file) {
        onDetectionComplete(detectionData, videoId, file)
      }
    } catch (error) {
      console.error("[Upload] Failed to load results:", error)
      setError("Failed to load results. Please try again.")
      setStatusMessage("")
      setUploading(false)
    }
  }

  const handleUpload = async () => {
    if (!file) {
      setError("Please select a video file")
      return
    }

    const formData = new FormData()
    formData.append("file", file)
    formData.append("detection_type", detectionType)
    formData.append("speed_kmh", speed.toString())
    formData.append("detection_mode", selectMethod)

    // Add JSON file if provided
    if (jsonFile) {
      formData.append("json_file", jsonFile)
    }

    setUploading(true)
    setProgress(0)
    setStatusMessage("Uploading...")
    setError(null)

    try {
      const result = await videoService.uploadVideo(formData);
      const videoId = result.video_id

      console.log("[Upload] Video uploaded successfully, ID:", videoId)
      console.log("[Upload] Response:", result)
      setStatusMessage("Uploaded! Starting processing...")
      setProgress(10)

      // Connect WebSocket for progress updates
      connectWebSocket(videoId)
    } catch (error) {
      console.error("[Upload] Upload error:", error)

      let errorMessage = "Upload failed"

      if (error instanceof TypeError && error.message === "Failed to fetch") {
        errorMessage = "Cannot connect to server. Please check if backend is running."
      } else if (error instanceof Error) {
        errorMessage = error.message
      }

      setError(errorMessage)
      setStatusMessage("")
      setUploading(false)
      setProgress(0)
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>Upload Video</CardTitle>
        <CardDescription>
          Select video file, detection type, vehicle speed, and method for analysis
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
          <div className="space-y-2">
            <Label htmlFor="video-file">Video File</Label>
            <div className="flex gap-2">
              <Input
                ref={fileInputRef}
                id="video-file"
                type="file"
                accept="video/*"
                onChange={(e) => {
                  setFile(e.target.files?.[0] || null)
                  setError(null)
                }}
                disabled={uploading}
                className="flex-1"
              />
            </div>
            {file && (
              <p className="text-sm text-muted-foreground">
                Selected: {file.name} ({(file.size / 1024 / 1024).toFixed(2)} MB)
              </p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="json-file">GPS JSON File</Label>
            <div className="flex gap-2">
              <Input
                ref={jsonFileInputRef}
                id="json-file"
                type="file"
                accept=".json,application/json"
                onChange={(e) => {
                  setJsonFile(e.target.files?.[0] || null)
                  setError(null)
                }}
                disabled={uploading}
                className="flex-1"
              />
            </div>
            {jsonFile && (
              <p className="text-sm text-muted-foreground">
                Selected: {jsonFile.name} ({(jsonFile.size / 1024).toFixed(2)} KB)
              </p>
            )}
          </div>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div className="space-y-2">
            <Label htmlFor="detection-type">Detection Type</Label>
            <Select
              value={detectionType}
              onValueChange={handleDetectionTypeChange}
              disabled={uploading}
            >
              <SelectTrigger id="detection-type">
                <SelectValue placeholder="Select detection type" />
              </SelectTrigger>
              <SelectContent>
                {DETECTION_TYPES.map((type) => (
                  <SelectItem key={type.value} value={type.value}>
                    <span>{type.label}</span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <Label htmlFor="speed">Vehicle Speed (km/h)</Label>
            <Input
              id="speed"
              type="number"
              min={1}
              max={200}
              value={speed}
              onChange={(e) => setSpeed(Number(e.target.value))}
              disabled={uploading}
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="select-method">Select Method</Label>
            <Select
              value={selectMethod}
              onValueChange={setSelectMethod}
              disabled={uploading}
            >
              <SelectTrigger id="select-method">
                <SelectValue placeholder="Select method" />
              </SelectTrigger>
              <SelectContent>
                {DETECTION_METHODS.map((method) => (
                  <SelectItem key={method.value} value={method.value}>
                    <span>{method.label}</span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        {error && (
          <div className="flex items-start gap-2 p-3 rounded-lg bg-destructive/10 text-destructive">
            <AlertCircle className="h-5 w-5 mt-0.5 shrink-0" />
            <p className="text-sm whitespace-pre-line">{error}</p>
          </div>
        )}

        <Button
          onClick={handleUpload}
          disabled={!file || uploading}
          className="w-full"
          size="lg"
        >
          {uploading ? (
            <>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              Processing...
            </>
          ) : (
            <>
              <Upload className="mr-2 h-4 w-4" />
              Upload & Process
            </>
          )}
        </Button>

        {uploading && (
          <div className="space-y-3">
            <Progress value={progress} className="h-3" />
            <div className="flex items-center justify-between text-sm">
              <span className="text-muted-foreground">{statusMessage}</span>
              <span className="font-semibold">{progress}%</span>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  )
}