import React, { useState, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";

import { Separator } from "@/components/ui/separator";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import {
  Upload,
  X,
  CheckCircle,
  AlertCircle,
  FileText,
  Trash2,
  ArrowUpDown,
  Copy,
} from "lucide-react";
import { useSystemNotifications } from "@/hooks/useSystemNotifications";
import { useAgentGraph } from "@/context/AgentGraphContext";
import { api } from "@/lib/api";

type ConcatenationMethod = "newlines" | "timestamps" | "custom" | "none";

interface FileUpload {
  file: File;
  id: string;
  preview?: string;
}

export function UploadView() {
  const [uploadProgress, setUploadProgress] = useState(0);
  const [isUploading, setIsUploading] = useState(false);
  const [selectedFiles, setSelectedFiles] = useState<FileUpload[]>([]);
  const [uploadComplete, setUploadComplete] = useState(false);
  const [concatenationMethod, setConcatenationMethod] =
    useState<ConcatenationMethod>("newlines");
  const [customSeparator, setCustomSeparator] = useState("\n---\n");
  const [finalFilename, setFinalFilename] = useState("");
  const [isDragging, setIsDragging] = useState(false);

  const { notifySuccess, notifyError } = useSystemNotifications();
  const { actions } = useAgentGraph();

  const handleFileSelect = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const files = e.target.files;
      if (files) {
        addFiles(Array.from(files));
      }
    },
    []
  );

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  }, []);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    
    const files = Array.from(e.dataTransfer.files);
    if (files.length > 0) {
      addFiles(files);
    }
  }, []);

  const addFiles = (files: File[]) => {
    const newFiles = files.map((file) => ({
      file,
      id: Math.random().toString(36).substr(2, 9),
      preview: file.size < 50000 ? "Loading..." : undefined, // Only preview small files
    }));

    setSelectedFiles((prev) => [...prev, ...newFiles]);
    setUploadComplete(false);

    // Generate filename suggestion
    if (files.length === 1 && selectedFiles.length === 0) {
      setFinalFilename(files[0]?.name || "trace");
    } else {
      setFinalFilename(`combined_trace_${Date.now()}.${getOutputExtension()}`);
    }
  };

  const removeFile = (id: string) => {
    setSelectedFiles((prev) => prev.filter((f) => f.id !== id));
  };

  const moveFile = (id: string, direction: "up" | "down") => {
    setSelectedFiles((prev) => {
      const index = prev.findIndex((f) => f.id === id);
      if (index === -1) return prev;

      const newFiles = [...prev];
      const targetIndex = direction === "up" ? index - 1 : index + 1;

      if (
        targetIndex >= 0 &&
        targetIndex < newFiles.length &&
        newFiles[index] &&
        newFiles[targetIndex]
      ) {
        [newFiles[index], newFiles[targetIndex]] = [
          newFiles[targetIndex],
          newFiles[index],
        ];
      }

      return newFiles;
    });
  };

  const getOutputExtension = () => {
    const hasJson = selectedFiles.some((f) => f.file.name.endsWith(".json"));
    return hasJson ? "json" : "txt";
  };

  const concatenateFiles = async (): Promise<string> => {
    if (selectedFiles.length === 1) {
      return (await selectedFiles[0]?.file.text()) || "";
    }

    const fileContents = await Promise.all(
      selectedFiles.map(async (fileUpload) => {
        const content = await fileUpload.file.text();
        return {
          filename: fileUpload.file.name,
          content: content.trim(),
        };
      })
    );

    switch (concatenationMethod) {
      case "none":
        return fileContents.map((f) => f.content).join("");

      case "newlines":
        return fileContents.map((f) => f.content).join("\n\n");

      case "timestamps":
        return fileContents
          .map(
            (f) =>
              `=== File: ${f.filename} (${new Date().toISOString()}) ===\n${
                f.content
              }`
          )
          .join("\n\n");

      case "custom":
        return fileContents.map((f) => f.content).join(customSeparator);

      default:
        return fileContents.map((f) => f.content).join("\n\n");
    }
  };

  const handleUpload = async () => {
    if (selectedFiles.length === 0) return;

    setIsUploading(true);
    setUploadProgress(0);

    try {
      let fileToUpload: File;

      if (selectedFiles.length === 1 && selectedFiles[0]) {
        fileToUpload = selectedFiles[0].file;
      } else {
        // Concatenate multiple files
        const combinedContent = await concatenateFiles();
        const blob = new Blob([combinedContent], { type: "text/plain" });
        fileToUpload = new File([blob], finalFilename, { type: blob.type });
      }

      const trace = await api.traces.upload(fileToUpload, (progress) => {
        setUploadProgress(progress);
      });

      notifySuccess(
        "Upload Successful",
        `${fileToUpload.name} has been uploaded successfully.`
      );

      // Refresh traces list
      const traces = await api.traces.list();
      actions.setTraces(traces);

      // Select the uploaded trace
      actions.setSelectedTrace(trace);

      // Mark upload as complete
      setUploadComplete(true);
      setUploadProgress(100);
    } catch (error) {
      notifyError(
        "Upload Failed",
        error instanceof Error ? error.message : "Failed to upload file"
      );
    } finally {
      setIsUploading(false);
    }
  };

  const handleReset = () => {
    setSelectedFiles([]);
    setUploadProgress(0);
    setUploadComplete(false);
    setFinalFilename("");
  };

  const handleViewTrace = () => {
    actions.setActiveView("traces");
  };

  const getFileIcon = (fileName: string) => {
    const extension = fileName.toLowerCase().split(".").pop();
    switch (extension) {
      case "json":
        return "📄";
      case "txt":
        return "📝";
      case "log":
        return "📋";
      default:
        return "📄";
    }
  };

  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return "0 Bytes";
    const k = 1024;
    const sizes = ["Bytes", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };

  return (
    <div className="p-6 space-y-6 max-w-7xl mx-auto">
      {/* Upload Instructions */}
      <div 
        className={`border border-dashed rounded-lg p-8 text-center space-y-4 transition-colors ${
          isDragging
            ? "border-primary bg-primary/5 border-2"
            : "border-gray-300 hover:border-primary/50"
        }`}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
      >
        <div className="space-y-2">
          <Upload className="h-12 w-12 text-muted-foreground mx-auto" />
          <h3 className="text-lg font-semibold">
            Drop files here or click to upload
          </h3>
          <p className="text-muted-foreground max-w-md mx-auto">
            Select trace files (JSON, TXT, JSONL) to upload. You can select
            multiple files at once.
          </p>
        </div>
        <Button size="lg" variant="outline" asChild>
          <label className="cursor-pointer">
            <input
              type="file"
              className="hidden"
              accept=".json,.txt,.log"
              multiple
              onChange={handleFileSelect}
            />
            Browse Files
          </label>
        </Button>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
        {/* Left Column - Upload Functionality */}
        <div className="space-y-6">
          {/* Selected Files */}
          {selectedFiles.length > 0 && (
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <h4 className="font-medium">
                  Selected Files ({selectedFiles.length})
                </h4>
                <Button variant="ghost" size="sm" onClick={handleReset}>
                  <X className="h-4 w-4 mr-1" />
                  Clear All
                </Button>
              </div>

              <div className="space-y-2 max-h-60 overflow-y-auto">
                {selectedFiles.map((fileUpload, index) => (
                  <div
                    key={fileUpload.id}
                    className="flex items-center gap-3 p-3 border rounded-lg bg-muted/20"
                  >
                    <div className="text-2xl">
                      {getFileIcon(fileUpload.file.name)}
                    </div>
                    <div className="flex-1 min-w-0">
                      <p
                        className="font-medium text-sm truncate"
                        title={fileUpload.file.name}
                      >
                        {fileUpload.file.name}
                      </p>
                      <div className="flex items-center gap-2 text-xs text-muted-foreground">
                        <span>{formatFileSize(fileUpload.file.size)}</span>
                        <span>•</span>
                        <span>{fileUpload.file.type || "Unknown type"}</span>
                      </div>
                    </div>
                    <div className="flex items-center gap-1">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => moveFile(fileUpload.id, "up")}
                        disabled={index === 0}
                      >
                        <ArrowUpDown className="h-3 w-3" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => removeFile(fileUpload.id)}
                      >
                        <Trash2 className="h-3 w-3" />
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* Multiple Files Configuration */}
          {selectedFiles.length > 1 && (
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <Copy className="h-5 w-5" />
                  File Concatenation
                </CardTitle>
                <CardDescription>
                  Configure how multiple files should be combined
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="space-y-2">
                  <Label htmlFor="concatenation-method">
                    Concatenation Method
                  </Label>
                  <Select
                    value={concatenationMethod}
                    onValueChange={(value: ConcatenationMethod) =>
                      setConcatenationMethod(value)
                    }
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="newlines">
                        Separate with blank lines
                      </SelectItem>
                      <SelectItem value="timestamps">
                        Add timestamps and filenames
                      </SelectItem>
                      <SelectItem value="custom">Custom separator</SelectItem>
                      <SelectItem value="none">
                        No separation (direct concatenation)
                      </SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                {concatenationMethod === "custom" && (
                  <div className="space-y-2">
                    <Label htmlFor="custom-separator">Custom Separator</Label>
                    <Textarea
                      id="custom-separator"
                      value={customSeparator}
                      onChange={(e) => setCustomSeparator(e.target.value)}
                      placeholder="Enter custom separator..."
                      rows={2}
                    />
                  </div>
                )}

                <div className="space-y-2">
                  <Label htmlFor="final-filename">Final Filename</Label>
                  <input
                    id="final-filename"
                    type="text"
                    value={finalFilename}
                    onChange={(e) => setFinalFilename(e.target.value)}
                    className="w-full px-3 py-2 border rounded-lg text-sm"
                    placeholder="Enter filename for combined file..."
                  />
                </div>
              </CardContent>
            </Card>
          )}

          {/* Upload Progress & Actions */}
          {selectedFiles.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <FileText className="h-5 w-5" />
                  {uploadComplete ? "Upload Complete" : "Ready to Upload"}
                </CardTitle>
                <CardDescription>
                  {selectedFiles.length === 1 && selectedFiles[0]
                    ? `Upload ${selectedFiles[0].file.name}`
                    : `Combine and upload ${selectedFiles.length} files`}
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                {/* Upload Progress */}
                {isUploading && (
                  <div className="space-y-3">
                    <div className="flex items-center justify-between text-sm">
                      <span className="text-muted-foreground">
                        Uploading...
                      </span>
                      <span className="font-medium">
                        {Math.round(uploadProgress)}%
                      </span>
                    </div>
                    <Progress value={uploadProgress} className="h-3" />
                  </div>
                )}

                {/* Success State */}
                {uploadComplete && (
                  <div className="p-4 bg-green-50 border border-green-200 rounded-lg">
                    <div className="flex items-center gap-2 text-green-800 mb-2">
                      <CheckCircle className="h-5 w-5" />
                      <span className="font-medium">Upload Successful!</span>
                    </div>
                    <p className="text-sm text-green-700 mb-4">
                      Your trace file has been uploaded and is ready for
                      analysis.
                    </p>
                    <div className="flex gap-2">
                      <Button onClick={handleViewTrace} size="sm">
                        View in Traces
                      </Button>
                      <Button onClick={handleReset} variant="outline" size="sm">
                        Upload Another
                      </Button>
                    </div>
                  </div>
                )}

                {/* Upload Actions */}
                {!uploadComplete && (
                  <div className="flex gap-3">
                    <Button
                      variant="outline"
                      onClick={handleReset}
                      disabled={isUploading}
                      className="flex-1"
                    >
                      Reset
                    </Button>
                    <Button
                      onClick={handleUpload}
                      disabled={isUploading}
                      className="flex-1"
                      size="lg"
                    >
                      {isUploading
                        ? "Uploading..."
                        : selectedFiles.length > 1
                        ? "Combine & Upload"
                        : "Upload File"}
                    </Button>
                  </div>
                )}
              </CardContent>
            </Card>
          )}

          {/* Minimum Viable Trace Example */}
          <Card>
            <CardHeader>
              <CardTitle className="text-lg">
                Minimum Viable Trace Example
              </CardTitle>
              <CardDescription>
                AgentGraph can process even basic conversation logs with just
                agent identification and input/output pairs
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="bg-slate-50 border rounded-lg p-4">
                <pre className="text-xs text-slate-700 whitespace-pre-wrap">
                  {`{
  "agent_name": "assistant",
  "input": "user message", 
  "output": "agent response"
}`}
                </pre>
              </div>
              <p className="text-xs text-muted-foreground mt-3">
                <span className="font-medium">Note:</span> Analysis capabilities
                scale significantly with additional structured metadata.
              </p>
            </CardContent>
          </Card>

          {/* File Guidelines */}
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Upload className="h-5 w-5" />
                File Guidelines
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="space-y-4 text-sm">
                <div>
                  <h4 className="font-medium mb-2">Supported File Types</h4>
                  <ul className="space-y-1 text-muted-foreground">
                    <li>• JSON files (.json) - Structured trace data</li>
                    <li>• Text files (.txt) - Plain text traces</li>
                    <li>• Log files (.log) - Application logs</li>
                  </ul>
                </div>
                <Separator />
                <div>
                  <h4 className="font-medium mb-2">File Requirements</h4>
                  <ul className="space-y-1 text-muted-foreground">
                    <li>• Maximum file size: 50MB per file</li>
                    <li>• UTF-8 encoding recommended</li>
                    <li>• Well-formed JSON for .json files</li>
                    <li>
                      • Multiple files will be concatenated based on your
                      settings
                    </li>
                  </ul>
                </div>
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Right Column - AgentGraph Trace Requirements */}
        <div className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <AlertCircle className="h-5 w-5" />
                AgentGraph Trace Requirements
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="space-y-6 text-sm">
                {/* Essential Requirements */}
                <div>
                  <h4 className="font-semibold text-green-700 mb-3">
                    Essential (Absolute Minimum):
                  </h4>
                  <ul className="space-y-2 text-muted-foreground">
                    <li>
                      •{" "}
                      <span className="font-medium">Agent Identification</span>{" "}
                      - Clear agent names/types to distinguish different actors
                    </li>
                    <li>
                      •{" "}
                      <span className="font-medium">Input/Output Messages</span>{" "}
                      - Core conversation content (user inputs and agent
                      responses)
                    </li>
                  </ul>
                </div>

                <Separator />

                {/* Highly Recommended */}
                <div>
                  <h4 className="font-semibold text-blue-700 mb-3">
                    Highly Recommended:
                  </h4>
                  <ul className="space-y-2 text-muted-foreground">
                    <li>
                      • <span className="font-medium">System Prompts</span> -
                      Agent instructions and personas (improves entity
                      classification)
                    </li>
                    <li>
                      •{" "}
                      <span className="font-medium">
                        Hierarchical Structure
                      </span>{" "}
                      - Parent-child relationships between spans/steps for
                      execution flow analysis
                    </li>
                    <li>
                      • <span className="font-medium">Tool Usage Details</span>{" "}
                      - Function calls with parameters and return values
                      (critical for multi-step agents)
                    </li>
                    <li>
                      • <span className="font-medium">Error Information</span> -
                      Exception details and failure modes for anomaly detection
                    </li>
                  </ul>
                </div>

                <Separator />

                {/* Optional */}
                <div>
                  <h4 className="font-semibold text-purple-700 mb-3">
                    Optional (Enhanced Analysis):
                  </h4>
                  <ul className="space-y-2 text-muted-foreground">
                    <li>
                      •{" "}
                      <span className="font-medium">
                        Intermediate Reasoning
                      </span>{" "}
                      - Chain-of-thought processes (enhances causal analysis)
                    </li>
                    <li>
                      •{" "}
                      <span className="font-medium">
                        Unique Trace Identifier
                      </span>{" "}
                      - Consistent ID to track complete agent workflows (e.g.,
                      trace_id, session_id)
                    </li>
                    <li>
                      • <span className="font-medium">Timestamps</span> -
                      Start/end times for temporal analysis and performance
                      optimization
                    </li>
                    <li>
                      • <span className="font-medium">Basic Status</span> -
                      Success/failure indication for each step
                    </li>
                    <li>
                      • <span className="font-medium">Model Information</span> -
                      LLM model names, versions, parameters (enables
                      model-specific insights)
                    </li>
                    <li>
                      • <span className="font-medium">Token Usage</span> -
                      Input/output token counts (for cost analysis)
                    </li>
                    <li>
                      • <span className="font-medium">Execution Context</span> -
                      Environment details, API endpoints, service versions
                    </li>
                  </ul>
                </div>

                <Separator />

                {/* Multi-Agent Specific */}
                <div>
                  <h4 className="font-semibold text-orange-700 mb-3">
                    Multi-Agent Specific (Optional):
                  </h4>
                  <ul className="space-y-2 text-muted-foreground">
                    <li>
                      • <span className="font-medium">Task Decomposition</span>{" "}
                      - How tasks are split among agents (Normally in the Agent
                      Setting yaml file in CrewAI)
                    </li>
                    <li>
                      • <span className="font-medium">Dependency Tracking</span>{" "}
                      - Inter-agent dependencies (Access level of each agent)
                    </li>
                    <li>
                      •{" "}
                      <span className="font-medium">Orchestration Events</span>{" "}
                      - Workflow coordination and handoffs (Sometimes defined in
                      the parameters or code)
                    </li>
                  </ul>
                </div>
              </div>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}
