import { useState, useEffect, useRef } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { useDockerStatus, useCloneToDocker } from "@/hooks/use-docker";
import { toast } from "sonner";
import {
  Loader2,
  CheckCircle2,
  XCircle,
  Container,
  Copy,
  ChevronDown,
  ChevronRight,
} from "lucide-react";
import type { CloneMode, CloneProgress } from "@/types";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  connectionId: string;
  database: string;
  onConnect?: (connectionId: string) => void;
}

type Step = "config" | "progress" | "done";

function ProcessLog({
  entries,
  open: logOpen,
  onToggle,
  endRef,
}: {
  entries: CloneProgress[];
  open: boolean;
  onToggle: () => void;
  endRef: React.RefObject<HTMLDivElement | null>;
}) {
  if (entries.length === 0) return null;

  return (
    <div>
      <button
        type="button"
        className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
        onClick={onToggle}
      >
        {logOpen ? (
          <ChevronDown className="h-3 w-3" />
        ) : (
          <ChevronRight className="h-3 w-3" />
        )}
        Process Log ({entries.length})
      </button>
      {logOpen && (
        <div className="mt-1.5 rounded-md bg-muted p-3 text-xs font-mono max-h-40 overflow-y-auto">
          {entries.map((entry, i) => (
            <div key={i} className="flex gap-2 leading-5">
              <span className="text-muted-foreground shrink-0 w-8 text-right">
                {entry.percent}%
              </span>
              <span>{entry.message}</span>
              {entry.detail && (
                <span className="text-muted-foreground truncate">
                  — {entry.detail}
                </span>
              )}
            </div>
          ))}
          <div ref={endRef} />
        </div>
      )}
    </div>
  );
}

export function CloneDatabaseDialog({
  open,
  onOpenChange,
  connectionId,
  database,
  onConnect,
}: Props) {
  const [step, setStep] = useState<Step>("config");
  const [containerName, setContainerName] = useState("");
  const [pgVersion, setPgVersion] = useState("16");
  const [portMode, setPortMode] = useState<"auto" | "manual">("auto");
  const [manualPort, setManualPort] = useState(5433);
  const [cloneMode, setCloneMode] = useState<CloneMode>("schema_only");
  const [sampleRows, setSampleRows] = useState(1000);

  const [logEntries, setLogEntries] = useState<CloneProgress[]>([]);
  const [logOpen, setLogOpen] = useState(false);
  const logEndRef = useRef<HTMLDivElement>(null);

  const { data: dockerStatus } = useDockerStatus();
  const { clone, result, error, isCloning, progress, reset } =
    useCloneToDocker();

  // Reset state when dialog opens
  useEffect(() => {
    if (open) {
      setStep("config");
      setContainerName(
        `tusk-${database.replace(/[^a-zA-Z0-9_-]/g, "-")}-${Date.now().toString(36)}`
      );
      setPgVersion("16");
      setPortMode("auto");
      setManualPort(5433);
      setCloneMode("schema_only");
      setSampleRows(1000);
      setLogEntries([]);
      setLogOpen(false);
      reset();
    }
  }, [open, database, reset]);

  // Accumulate progress events into log
  useEffect(() => {
    if (progress) {
      setLogEntries((prev) => {
        const last = prev[prev.length - 1];
        if (last && last.stage === progress.stage && last.message === progress.message) {
          return prev;
        }
        return [...prev, progress];
      });
      if (progress.stage === "done" || progress.stage === "error") {
        setStep("done");
      }
    }
  }, [progress]);

  // Auto-scroll log to bottom
  useEffect(() => {
    if (logOpen && logEndRef.current) {
      logEndRef.current.scrollIntoView({ behavior: "smooth" });
    }
  }, [logEntries, logOpen]);

  const handleClone = () => {
    if (!containerName.trim()) {
      toast.error("Container name is required");
      return;
    }

    setStep("progress");

    const cloneId = crypto.randomUUID();
    clone({
      params: {
        source_connection_id: connectionId,
        source_database: database,
        container_name: containerName.trim(),
        pg_version: pgVersion,
        host_port: portMode === "manual" ? manualPort : null,
        clone_mode: cloneMode,
        sample_rows: cloneMode === "sample_data" ? sampleRows : null,
        postgres_password: null,
      },
      cloneId,
    });
  };

  const handleConnect = () => {
    if (result?.connection_id && onConnect) {
      onConnect(result.connection_id);
    }
    onOpenChange(false);
  };

  const dockerReady =
    dockerStatus?.installed && dockerStatus?.daemon_running;

  const logSection = (
    <ProcessLog
      entries={logEntries}
      open={logOpen}
      onToggle={() => setLogOpen(!logOpen)}
      endRef={logEndRef}
    />
  );

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[520px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Container className="h-5 w-5" />
            Clone to Docker
          </DialogTitle>
        </DialogHeader>

        {step === "config" && (
          <>
            <div className="flex items-center gap-2 rounded-md border px-3 py-2 text-sm">
              {dockerStatus === undefined ? (
                <>
                  <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                  <span className="text-muted-foreground">
                    Checking Docker...
                  </span>
                </>
              ) : dockerReady ? (
                <>
                  <CheckCircle2 className="h-4 w-4 text-green-500" />
                  <span>Docker {dockerStatus.version}</span>
                </>
              ) : (
                <>
                  <XCircle className="h-4 w-4 text-destructive" />
                  <span className="text-destructive">
                    {dockerStatus?.error || "Docker not available"}
                  </span>
                </>
              )}
            </div>

            <div className="grid gap-3 py-2">
              <div className="grid grid-cols-4 items-center gap-3">
                <label className="text-right text-sm text-muted-foreground">
                  Database
                </label>
                <div className="col-span-3">
                  <Badge variant="secondary">{database}</Badge>
                </div>
              </div>

              <div className="grid grid-cols-4 items-center gap-3">
                <label className="text-right text-sm text-muted-foreground">
                  Container
                </label>
                <Input
                  className="col-span-3"
                  value={containerName}
                  onChange={(e) => setContainerName(e.target.value)}
                  placeholder="tusk-mydb-clone"
                />
              </div>

              <div className="grid grid-cols-4 items-center gap-3">
                <label className="text-right text-sm text-muted-foreground">
                  PG Version
                </label>
                <Select value={pgVersion} onValueChange={setPgVersion}>
                  <SelectTrigger className="col-span-3">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="17">PostgreSQL 17</SelectItem>
                    <SelectItem value="16">PostgreSQL 16</SelectItem>
                    <SelectItem value="15">PostgreSQL 15</SelectItem>
                    <SelectItem value="14">PostgreSQL 14</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="grid grid-cols-4 items-center gap-3">
                <label className="text-right text-sm text-muted-foreground">
                  Port
                </label>
                <div className="col-span-3 flex items-center gap-2">
                  <Select
                    value={portMode}
                    onValueChange={(v) =>
                      setPortMode(v as "auto" | "manual")
                    }
                  >
                    <SelectTrigger className="w-24">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="auto">Auto</SelectItem>
                      <SelectItem value="manual">Manual</SelectItem>
                    </SelectContent>
                  </Select>
                  {portMode === "manual" && (
                    <Input
                      type="number"
                      className="flex-1"
                      value={manualPort}
                      onChange={(e) =>
                        setManualPort(parseInt(e.target.value) || 5433)
                      }
                      min={1024}
                      max={65535}
                    />
                  )}
                </div>
              </div>

              <div className="grid grid-cols-4 items-center gap-3">
                <label className="text-right text-sm text-muted-foreground">
                  Clone Mode
                </label>
                <Select
                  value={cloneMode}
                  onValueChange={(v) => setCloneMode(v as CloneMode)}
                >
                  <SelectTrigger className="col-span-3">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="schema_only">
                      Schema Only
                    </SelectItem>
                    <SelectItem value="full_clone">Full Clone</SelectItem>
                    <SelectItem value="sample_data">
                      Sample Data
                    </SelectItem>
                  </SelectContent>
                </Select>
              </div>

              {cloneMode === "sample_data" && (
                <div className="grid grid-cols-4 items-center gap-3">
                  <label className="text-right text-sm text-muted-foreground">
                    Sample Rows
                  </label>
                  <Input
                    className="col-span-3"
                    type="number"
                    value={sampleRows}
                    onChange={(e) =>
                      setSampleRows(parseInt(e.target.value) || 1000)
                    }
                    min={1}
                    max={100000}
                  />
                </div>
              )}
            </div>

            <DialogFooter>
              <Button
                variant="outline"
                onClick={() => onOpenChange(false)}
              >
                Cancel
              </Button>
              <Button onClick={handleClone} disabled={!dockerReady}>
                Clone
              </Button>
            </DialogFooter>
          </>
        )}

        {step === "progress" && (
          <div className="py-4 space-y-4">
            <div className="space-y-2">
              <div className="flex items-center justify-between text-sm">
                <span>{progress?.message || "Starting..."}</span>
                <span className="text-muted-foreground">
                  {progress?.percent ?? 0}%
                </span>
              </div>
              <div className="h-2 rounded-full bg-secondary overflow-hidden">
                <div
                  className="h-full rounded-full bg-primary transition-all duration-300"
                  style={{ width: `${progress?.percent ?? 0}%` }}
                />
              </div>
            </div>

            {isCloning && (
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <Loader2 className="h-4 w-4 animate-spin" />
                {progress?.stage || "Initializing..."}
              </div>
            )}

            {logSection}
          </div>
        )}

        {step === "done" && (
          <div className="py-4 space-y-4">
            {error ? (
              <div className="flex items-start gap-3 rounded-md border border-destructive/50 bg-destructive/10 p-4">
                <XCircle className="h-5 w-5 text-destructive shrink-0 mt-0.5" />
                <div className="space-y-1">
                  <p className="text-sm font-medium text-destructive">
                    Clone Failed
                  </p>
                  <p className="text-xs text-muted-foreground">{error}</p>
                </div>
              </div>
            ) : (
              <div className="space-y-3">
                <div className="flex items-start gap-3 rounded-md border border-green-500/50 bg-green-500/10 p-4">
                  <CheckCircle2 className="h-5 w-5 text-green-500 shrink-0 mt-0.5" />
                  <div className="space-y-1">
                    <p className="text-sm font-medium">
                      Clone Completed
                    </p>
                    <p className="text-xs text-muted-foreground">
                      Database cloned to Docker container successfully.
                    </p>
                  </div>
                </div>

                {result && (
                  <div className="rounded-md border p-3 space-y-2 text-sm">
                    <div className="flex items-center justify-between">
                      <span className="text-muted-foreground">
                        Container
                      </span>
                      <span className="font-mono">
                        {result.container.name}
                      </span>
                    </div>
                    <div className="flex items-center justify-between">
                      <span className="text-muted-foreground">Port</span>
                      <span className="font-mono">
                        {result.container.host_port}
                      </span>
                    </div>
                    <div className="flex items-center justify-between gap-2">
                      <span className="text-muted-foreground">URL</span>
                      <div className="flex items-center gap-1">
                        <span className="font-mono text-xs truncate max-w-[250px]">
                          {result.connection_url}
                        </span>
                        <Button
                          variant="ghost"
                          size="sm"
                          className="h-6 w-6 p-0"
                          onClick={() => {
                            navigator.clipboard.writeText(
                              result.connection_url
                            );
                            toast.success("URL copied");
                          }}
                        >
                          <Copy className="h-3 w-3" />
                        </Button>
                      </div>
                    </div>
                  </div>
                )}
              </div>
            )}

            {logSection}

            <DialogFooter>
              {error ? (
                <>
                  <Button
                    variant="outline"
                    onClick={() => onOpenChange(false)}
                  >
                    Close
                  </Button>
                  <Button
                    onClick={() => setStep("config")}
                  >
                    Retry
                  </Button>
                </>
              ) : (
                <>
                  <Button
                    variant="outline"
                    onClick={() => onOpenChange(false)}
                  >
                    Close
                  </Button>
                  {onConnect && result && (
                    <Button onClick={handleConnect}>Connect</Button>
                  )}
                </>
              )}
            </DialogFooter>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
