import React, { useState, useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Save,
  FileText,
  RotateCcw,
  AlertCircle,
  CheckCircle,
  Search,
  Hash,
} from "lucide-react";
import { Trace } from "@/types";

interface TraceEditorProps {
  trace: Trace;
  onBack?: () => void;
}

interface LineNumberMapping {
  [lineNumber: number]: number; // line number to character position mapping
}

export function TraceEditor({ trace, onBack: _onBack }: TraceEditorProps) {
  const [content, setContent] = useState("");
  const [originalContent, setOriginalContent] = useState("");
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [saveSuccess, setSaveSuccess] = useState(false);
  const [validationError, setValidationError] = useState<string | null>(null);
  const [lineMapping, setLineMapping] = useState<LineNumberMapping>({});
  const [gotoLineNumber, setGotoLineNumber] = useState("");
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  // JSON validation function
  const validateJSON = (
    content: string
  ): { isValid: boolean; error?: string } => {
    if (!content.trim()) {
      return { isValid: false, error: "Content cannot be empty" };
    }

    try {
      JSON.parse(content);
      return { isValid: true };
    } catch (e) {
      if (e instanceof SyntaxError) {
        return {
          isValid: false,
          error: `Invalid JSON: ${e.message}`,
        };
      }
      return {
        isValid: false,
        error: "Invalid JSON format",
      };
    }
  };

  // Validate content on change
  useEffect(() => {
    if (content !== originalContent) {
      const validation = validateJSON(content);
      setValidationError(validation.isValid ? null : validation.error || null);
    } else {
      setValidationError(null);
    }
  }, [content, originalContent]);

  // Create line number mapping (similar to TraceLineNumberProcessor)
  const createLineMapping = (content: string): LineNumberMapping => {
    const lines = content.split("\n");
    const mapping: LineNumberMapping = {};
    let currentCharPos = 0;

    for (let i = 0; i < lines.length; i++) {
      const lineNumber = i + 1;
      const line = lines[i];
      mapping[lineNumber] = currentCharPos;
      currentCharPos += (line?.length || 0) + 1; // +1 for newline character
    }

    return mapping;
  };

  // Get line mapping for external use (e.g., ContentReference integration)
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const getLineMapping = (): LineNumberMapping => {
    return lineMapping;
  };

  // Load trace content with line numbers for ContentReference compatibility
  useEffect(() => {
    const loadTraceContent = async () => {
      try {
        setIsLoading(true);
        setError(null);

        const response = await fetch(
          `/api/traces/${trace.trace_id}/content-numbered`
        );
        if (!response.ok) {
          throw new Error(
            `Failed to load trace content: ${response.statusText}`
          );
        }

        const data = await response.json();
        const traceContent = data.content || "";
        setContent(traceContent);
        setOriginalContent(traceContent);

        // Create line number mapping
        const mapping = createLineMapping(traceContent);
        setLineMapping(mapping);
      } catch (err) {
        setError(
          err instanceof Error ? err.message : "Failed to load trace content"
        );
      } finally {
        setIsLoading(false);
      }
    };

    loadTraceContent();
  }, [trace.trace_id]);

  // Calculate statistics
  const characterCount = content.length;
  const lineCount = content.split("\n").length;
  const wordCount =
    content.trim() === "" ? 0 : content.trim().split(/\s+/).length;
  const hasChanges = content !== originalContent;
  const canSave = hasChanges && !validationError;

  // Handle save
  const handleSave = async () => {
    // Prevent saving if there are validation errors
    if (validationError) {
      setError("Cannot save: " + validationError);
      return;
    }

    try {
      setIsSaving(true);
      setError(null);
      setSaveSuccess(false);

      const response = await fetch(`/api/traces/${trace.trace_id}/content`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ content }),
      });

      if (!response.ok) {
        throw new Error(`Failed to save trace: ${response.statusText}`);
      }

      setOriginalContent(content);
      setSaveSuccess(true);

      // Update line mapping for the new content
      const mapping = createLineMapping(content);
      setLineMapping(mapping);

      // Auto-hide success message after 3 seconds
      setTimeout(() => setSaveSuccess(false), 3000);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to save trace");
    } finally {
      setIsSaving(false);
    }
  };

  // Handle reset
  const handleReset = () => {
    if (window.confirm("Are you sure you want to discard all changes?")) {
      setContent(originalContent);
      // Reset line mapping
      const mapping = createLineMapping(originalContent);
      setLineMapping(mapping);
    }
  };

  // Handle goto line
  const handleGotoLine = () => {
    const lineNumber = parseInt(gotoLineNumber);
    if (
      lineNumber &&
      lineNumber > 0 &&
      lineNumber <= lineCount &&
      textareaRef.current
    ) {
      const lines = content.split("\n");
      let position = 0;
      for (let i = 0; i < lineNumber - 1; i++) {
        position += (lines[i]?.length || 0) + 1; // +1 for newline
      }

      textareaRef.current.focus();
      textareaRef.current.setSelectionRange(position, position);
      textareaRef.current.scrollTop = (lineNumber - 1) * 20; // Approximate line height
    }
  };

  // Handle content change
  const handleContentChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setContent(e.target.value);
  };

  // Handle scroll synchronization between line numbers and textarea
  const handleScroll = (e: React.UIEvent<HTMLTextAreaElement>) => {
    const lineNumbersElement = document.getElementById("line-numbers");
    if (lineNumbersElement && e.currentTarget) {
      const scrollTop = e.currentTarget.scrollTop;
      lineNumbersElement.style.transform = `translateY(-${scrollTop}px)`;
    }
  };

  // Generate line numbers based on content
  const generateLineNumbers = () => {
    const lines = content.split("\n");
    return lines.map((_, index) => `${index + 1}`).join("\n");
  };

  // Expose line mapping functionality for future ContentReference integration
  React.useEffect(() => {
    if (Object.keys(lineMapping).length > 0) {
      console.debug(
        "Line mapping updated:",
        Object.keys(lineMapping).length,
        "lines"
      );
    }
  }, [lineMapping]);

  return (
    <div className="p-6 space-y-6">
      <style>{`
        #line-numbers {
          scrollbar-width: none;
          -ms-overflow-style: none;
        }
        #line-numbers::-webkit-scrollbar {
          display: none;
        }
      `}</style>

      {/* Action Buttons */}
      <div className="flex items-center justify-end gap-2">
        {hasChanges && (
          <Button variant="outline" onClick={handleReset}>
            <RotateCcw className="h-4 w-4 mr-2" />
            Reset
          </Button>
        )}
        <Button
          onClick={handleSave}
          disabled={!canSave || isSaving}
          className="bg-primary hover:bg-primary/90"
        >
          {isSaving ? (
            <>
              <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin mr-2" />
              Saving...
            </>
          ) : (
            <>
              <Save className="h-4 w-4 mr-2" />
              Save Changes
            </>
          )}
        </Button>
      </div>

      {/* Status Messages */}
      {error && (
        <div className="bg-destructive/10 border border-destructive/20 rounded-lg p-3">
          <div className="flex items-center gap-2 text-destructive">
            <AlertCircle className="h-4 w-4" />
            <span className="text-sm font-medium">{error}</span>
          </div>
        </div>
      )}

      {validationError && (
        <div className="bg-yellow-50 border border-yellow-200 rounded-lg p-3">
          <div className="flex items-center gap-2 text-yellow-800">
            <AlertCircle className="h-4 w-4" />
            <span className="text-sm font-medium">
              Validation Error: {validationError}
            </span>
          </div>
        </div>
      )}

      {saveSuccess && (
        <div className="bg-green-50 border border-green-200 rounded-lg p-3">
          <div className="flex items-center gap-2 text-green-800">
            <CheckCircle className="h-4 w-4" />
            <div>
              <span className="text-sm font-medium">
                Trace content saved successfully!
              </span>
              <p className="text-xs text-green-700 mt-1">
                Note: Trace statistics may need to be regenerated to reflect
                your changes.
              </p>
            </div>
          </div>
        </div>
      )}

      {/* File Info & Statistics */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <FileText className="h-5 w-5" />
            File Information
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div>
              <div className="text-sm text-muted-foreground mb-1">
                Characters
              </div>
              <div className="text-lg font-medium">
                {characterCount.toLocaleString()}
              </div>
            </div>
            <div>
              <div className="text-sm text-muted-foreground mb-1">Lines</div>
              <div className="text-lg font-medium">
                {lineCount.toLocaleString()}
              </div>
            </div>
            <div>
              <div className="text-sm text-muted-foreground mb-1">Words</div>
              <div className="text-lg font-medium">
                {wordCount.toLocaleString()}
              </div>
            </div>
            <div>
              <div className="text-sm text-muted-foreground mb-1">Status</div>
              <div className="flex items-center gap-2">
                {hasChanges ? (
                  <Badge variant="secondary">Modified</Badge>
                ) : (
                  <Badge variant="outline">Saved</Badge>
                )}
              </div>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Editor Controls */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Search className="h-5 w-5" />
            Editor Controls
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center gap-4">
            <div className="flex items-center gap-2">
              <Label htmlFor="goto-line">
                <Hash className="h-4 w-4" />
              </Label>
              <Input
                id="goto-line"
                type="number"
                placeholder="Line number"
                value={gotoLineNumber}
                onChange={(e) => setGotoLineNumber(e.target.value)}
                className="w-32"
                min="1"
                max={lineCount}
              />
              <Button
                variant="outline"
                size="sm"
                onClick={handleGotoLine}
                disabled={!gotoLineNumber || isLoading}
              >
                Go to Line
              </Button>
            </div>
            <div className="text-sm text-muted-foreground">
              Language: plaintext
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Simple Text Editor */}
      <Card className="flex-1">
        <CardHeader>
          <CardTitle>Content Editor</CardTitle>
        </CardHeader>
        <CardContent className="p-0">
          {isLoading ? (
            <div className="space-y-4 p-6">
              <div className="h-8 w-full bg-muted animate-pulse rounded" />
              <div className="h-6 w-3/4 bg-muted animate-pulse rounded" />
              <div className="h-6 w-1/2 bg-muted animate-pulse rounded" />
            </div>
          ) : (
            <div className="p-4">
              <div
                className="flex border rounded-lg overflow-hidden relative"
                style={{ border: "1px solid hsl(var(--border))" }}
              >
                {/* Line Numbers Container */}
                <div
                  className="bg-muted/30 relative overflow-hidden"
                  style={{
                    minWidth: "60px",
                    maxWidth: "60px",
                    height: "600px",
                    borderRight: "1px solid hsl(var(--border))",
                  }}
                >
                  <div
                    id="line-numbers"
                    className="text-muted-foreground text-right select-none"
                    style={{
                      fontFamily:
                        "'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace",
                      fontSize: "14px",
                      lineHeight: "20px",
                      padding: "16px 8px 16px 16px",
                      whiteSpace: "pre",
                      willChange: "transform",
                    }}
                  >
                    {generateLineNumbers()}
                  </div>
                </div>

                {/* Text Editor */}
                <textarea
                  ref={textareaRef}
                  value={content}
                  onChange={handleContentChange}
                  onScroll={handleScroll}
                  className="flex-1 h-[600px] resize-none focus:outline-none bg-transparent border-none"
                  style={{
                    fontFamily:
                      "'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace",
                    fontSize: "14px",
                    lineHeight: "20px",
                    backgroundColor: "hsl(var(--background))",
                    color: "hsl(var(--foreground))",
                    padding: "16px",
                    margin: 0,
                    outline: "none",
                  }}
                  spellCheck={false}
                  autoComplete="off"
                  autoCorrect="off"
                  autoCapitalize="off"
                  wrap="soft"
                />
              </div>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
