"use client";

import { useState, useMemo, useCallback } from "react";
import dynamic from "next/dynamic";
import { useTheme } from "@/app/lib/theme";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Switch } from "./ui/switch";
import { X, Copy, Pencil, Check } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/app/lib/utils";

const MonacoEditor = dynamic(
  () => import("@monaco-editor/react").then((m) => m.default),
  { ssr: false },
);

type Props = {
  open: boolean;
  onClose: () => void;
  columnName: string;
  columnType?: string;
  value: unknown;
  tableName: string;
  rowId?: string;
  onEdit?: (column: string, newValue: string, rowId: string) => void;
};

export default function CellDetailSheet({
  open,
  onClose,
  columnName,
  columnType,
  value,
  tableName,
  rowId,
  onEdit,
}: Props) {
  const { resolved: themeMode } = useTheme();
  const [editing, setEditing] = useState(false);
  const [editValue, setEditValue] = useState("");

  const formatted = useMemo(() => {
    if (value === null) return "NULL";
    if (value === undefined) return "";
    if (typeof value === "object") {
      try {
        return JSON.stringify(value, null, 2);
      } catch {
        return String(value);
      }
    }
    return String(value);
  }, [value]);

  const isBool = useMemo(() => {
    const dt = (columnType ?? "").toLowerCase();
    return dt === "bool" || dt === "boolean" || typeof value === "boolean";
  }, [value, columnType]);

  const isJson = useMemo(() => {
    const dt = (columnType ?? "").toLowerCase();
    if (dt === "jsonb" || dt === "json") return true;
    if (typeof value === "object" && value !== null) return true;
    if (typeof value === "string") {
      try {
        JSON.parse(value);
        return value.trim().startsWith("{") || value.trim().startsWith("[");
      } catch {
        return false;
      }
    }
    return false;
  }, [value, columnType]);

  const useMonaco = isJson && !isBool;
  const language = isJson ? "json" : "plaintext";

  const startEdit = useCallback(() => {
    setEditValue(formatted);
    setEditing(true);
  }, [formatted]);

  const handleSave = useCallback(() => {
    if (onEdit && rowId) {
      onEdit(columnName, editValue, rowId);
    }
    setEditing(false);
  }, [onEdit, rowId, columnName, editValue]);

  const copyValue = useCallback(() => {
    navigator.clipboard.writeText(formatted);
    toast.success("Copied to clipboard");
  }, [formatted]);

  if (!open) return null;

  return (
    <div className="fixed inset-y-0 right-0 z-50 w-full sm:w-[480px] sm:max-w-[85vw] border-l border-border bg-card shadow-xl animate-slide-in-right flex flex-col">
      <div className="flex items-center justify-between border-b border-border px-4 py-3">
        <div className="min-w-0">
          <p className="text-caption uppercase tracking-wider text-muted-foreground">
            {tableName}
          </p>
          <h3 className="text-sm font-medium text-foreground font-mono truncate">
            {columnName}
          </h3>
          {columnType && (
            <p className="text-caption text-muted-foreground font-mono">
              {columnType}
            </p>
          )}
        </div>
        <div className="flex items-center gap-1">
          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7"
            onClick={copyValue}
          >
            <Copy className="h-3.5 w-3.5" />
          </Button>
          {onEdit && rowId && !editing && (
            <Button
              variant="ghost"
              size="icon"
              className="h-7 w-7"
              onClick={startEdit}
            >
              <Pencil className="h-3.5 w-3.5" />
            </Button>
          )}
          {editing && (
            <Button
              variant="ghost"
              size="icon"
              className="h-7 w-7 text-success"
              onClick={handleSave}
            >
              <Check className="h-3.5 w-3.5" />
            </Button>
          )}
          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7"
            onClick={onClose}
          >
            <X className="h-3.5 w-3.5" />
          </Button>
        </div>
      </div>

      <div className="flex-1 min-h-0">
        {isBool ? (
          <div className="p-4 h-full flex flex-col gap-3">
            <label className="text-body-sm text-muted-foreground font-medium">
              {columnName}
            </label>
            <div className="flex items-center gap-3">
              <Switch
                checked={
                  editing
                    ? editValue === "true"
                    : value === true || value === "true"
                }
                onCheckedChange={(checked) => {
                  if (!editing) {
                    setEditValue(checked ? "true" : "false");
                    setEditing(true);
                  } else {
                    setEditValue(checked ? "true" : "false");
                  }
                }}
                disabled={!onEdit || !rowId}
              />
              <span
                className={cn(
                  "text-sm font-mono",
                  (
                    editing
                      ? editValue === "true"
                      : value === true || value === "true"
                  )
                    ? "text-success"
                    : "text-muted-foreground",
                )}
              >
                {editing ? editValue : formatted}
              </span>
            </div>
            {editing && (
              <p className="text-caption text-muted-foreground">
                Toggle to change value, then save
              </p>
            )}
          </div>
        ) : editing ? (
          useMonaco ? (
            <MonacoEditor
              height="100%"
              language={language}
              theme={themeMode === "dark" ? "vs-dark" : "light"}
              value={editValue}
              onChange={(v) => setEditValue(v ?? "")}
              options={{
                minimap: { enabled: false },
                fontSize: 12,
                lineNumbers: "on",
                scrollBeyondLastLine: false,
                wordWrap: "on",
                automaticLayout: true,
                tabSize: 2,
                padding: { top: 8 },
                fontFamily: "var(--font-geist-mono), 'Fira Code', monospace",
              }}
            />
          ) : (
            <div className="p-4 h-full flex flex-col gap-2">
              <label className="text-body-sm text-muted-foreground font-medium">
                {columnName}
              </label>
              {formatted.length > 200 ? (
                <textarea
                  value={editValue}
                  onChange={(e) => setEditValue(e.target.value)}
                  className="flex-1 w-full rounded border border-input bg-background px-3 py-2 font-mono text-body-sm text-foreground outline-none focus:ring-1 focus:ring-ring resize-none"
                  autoFocus
                />
              ) : (
                <Input
                  value={editValue}
                  onChange={(e) => setEditValue(e.target.value)}
                  className="font-mono text-body-sm"
                  autoFocus
                  onKeyDown={(e) => {
                    if (e.key === "Enter") handleSave();
                  }}
                />
              )}
              <p className="text-caption text-muted-foreground">
                Press Enter to save, Escape to cancel
              </p>
            </div>
          )
        ) : useMonaco ? (
          <div className="h-full overflow-auto">
            <MonacoEditor
              height="100%"
              language={language}
              theme={themeMode === "dark" ? "vs-dark" : "light"}
              value={formatted}
              options={{
                readOnly: true,
                minimap: { enabled: false },
                fontSize: 12,
                lineNumbers: "on",
                scrollBeyondLastLine: false,
                wordWrap: "on",
                automaticLayout: true,
                tabSize: 2,
                padding: { top: 8 },
                fontFamily: "var(--font-geist-mono), 'Fira Code', monospace",
              }}
            />
          </div>
        ) : (
          <div className="p-4 h-full flex flex-col gap-2">
            <label className="text-body-sm text-muted-foreground font-medium">
              {columnName}
            </label>
            <div className="flex-1 rounded border border-border bg-muted/50 p-3 font-mono text-body-sm text-foreground overflow-auto whitespace-pre-wrap break-words">
              {formatted}
            </div>
          </div>
        )}
      </div>

      <div className="border-t border-border px-4 py-2 text-caption text-muted-foreground">
        {typeof value === "object" && value !== null ? "JSON" : typeof value} ·{" "}
        {formatted.length} chars
        {editing && " · Editing"}
      </div>
    </div>
  );
}
