import { json, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node";
import { useLoaderData, useActionData, Form, useNavigation } from "@remix-run/react";
import { useState, useEffect } from "react";

interface UpdateInfo {
  update_available: boolean;
  current_version: string;
  latest_version?: string;
  release_date?: string;
  changelog?: string;
  is_prerelease: boolean;
  download_size?: number;
  message?: string;
}

interface UpdateProgress {
  status: string;
  current_version: string;
  available_version?: string;
  download_progress: number;
  error_message?: string;
  last_check?: string;
}

export async function loader({ request }: LoaderFunctionArgs) {
  try {
    // Fetch current update status and progress
    const [updateRes, progressRes] = await Promise.all([
      fetch("http://localhost:8000/api/updates/check"),
      fetch("http://localhost:8000/api/updates/progress"),
    ]);

    const updateInfo = await updateRes.json();
    const progressInfo = await progressRes.json();

    return json({ updateInfo, progressInfo });
  } catch (error) {
    console.error("Error loading update info:", error);
    return json({
      updateInfo: null,
      progressInfo: null,
      error: "Failed to load update information",
    });
  }
}

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const action = formData.get("_action");

  try {
    if (action === "check_updates") {
      const response = await fetch("http://localhost:8000/api/updates/check", {
        method: "GET",
      });
      const data = await response.json();
      return json({ success: true, message: "Update check complete", data });
    }

    if (action === "download_update") {
      const response = await fetch("http://localhost:8000/api/updates/download", {
        method: "POST",
      });
      const data = await response.json();
      return json({ success: true, message: "Download started", data });
    }

    if (action === "install_update") {
      const response = await fetch("http://localhost:8000/api/updates/install", {
        method: "POST",
      });
      const data = await response.json();
      return json({ success: true, message: "Installation started", data });
    }

    return json({ success: false, message: "Unknown action" });
  } catch (error: any) {
    return json({ success: false, message: error.message || "Action failed" });
  }
}

export default function Updates() {
  const { updateInfo, progressInfo, error } = useLoaderData<typeof loader>();
  const actionData = useActionData<typeof action>();
  const navigation = useNavigation();
  const isSubmitting = navigation.state === "submitting";

  const [progress, setProgress] = useState<UpdateProgress | null>(progressInfo);

  // Poll for progress updates when downloading or installing
  useEffect(() => {
    if (!progress || (progress.status !== "downloading" && progress.status !== "installing")) {
      return;
    }

    const interval = setInterval(async () => {
      try {
        const response = await fetch("http://localhost:8000/api/updates/progress");
        const data = await response.json();
        setProgress(data);
      } catch (error) {
        console.error("Error polling progress:", error);
      }
    }, 1000);

    return () => clearInterval(interval);
  }, [progress?.status]);

  const getStatusBadge = (status: string) => {
    const badges: Record<string, { text: string; color: string }> = {
      idle: { text: "Idle", color: "var(--color-text-muted)" },
      checking: { text: "Checking...", color: "var(--color-primary)" },
      available: { text: "Update Available", color: "var(--color-accent)" },
      downloading: { text: "Downloading", color: "var(--color-primary)" },
      installing: { text: "Installing", color: "var(--color-warning)" },
      complete: { text: "Complete", color: "var(--color-success)" },
      failed: { text: "Failed", color: "var(--color-danger)" },
    };

    const badge = badges[status] || badges.idle;

    return (
      <span
        className="badge"
        style={{
          backgroundColor: `${badge.color}20`,
          color: badge.color,
          border: `1px solid ${badge.color}40`,
        }}
      >
        {badge.text}
      </span>
    );
  };

  const formatBytes = (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 Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
  };

  const formatDate = (dateString: string) => {
    const date = new Date(dateString);
    return date.toLocaleDateString("en-US", {
      year: "numeric",
      month: "long",
      day: "numeric",
    });
  };

  if (error) {
    return (
      <div className="container">
        <h1>⚠️ Error</h1>
        <div className="card">
          <p style={{ color: "var(--color-danger)" }}>{error}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="container">
      <div style={{ marginBottom: "var(--space-6)" }}>
        <h1 style={{ marginBottom: "var(--space-2)" }}>
          <span style={{ color: "var(--color-primary)" }}>🔄</span> System Updates
        </h1>
        <p className="text-muted">
          Manage system updates from GitHub releases
        </p>
      </div>

      {/* Action Messages */}
      {actionData && (
        <div
          className="card"
          style={{
            marginBottom: "var(--space-6)",
            backgroundColor: actionData.success
              ? "var(--color-success-bg)"
              : "var(--color-danger-bg)",
            borderColor: actionData.success
              ? "var(--color-success)"
              : "var(--color-danger)",
          }}
        >
          <p style={{ margin: 0 }}>{actionData.message}</p>
        </div>
      )}

      {/* Current Version */}
      <div className="card" style={{ marginBottom: "var(--space-6)" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "var(--space-4)" }}>
          <div>
            <h2 className="card-title" style={{ marginBottom: "var(--space-2)" }}>
              Current Version
            </h2>
            <div style={{ fontSize: "1.5rem", fontWeight: 700, color: "var(--color-primary)" }}>
              v{progressInfo?.current_version || updateInfo?.current_version || "Unknown"}
            </div>
          </div>
          {progress && getStatusBadge(progress.status)}
        </div>

        {progressInfo?.last_check && (
          <p className="text-muted" style={{ fontSize: "0.875rem", marginTop: "var(--space-2)" }}>
            Last checked: {new Date(progressInfo.last_check).toLocaleString()}
          </p>
        )}

        <Form method="post" style={{ marginTop: "var(--space-4)" }}>
          <input type="hidden" name="_action" value="check_updates" />
          <button
            type="submit"
            className="btn btn-secondary"
            disabled={isSubmitting || progress?.status === "checking"}
          >
            {isSubmitting || progress?.status === "checking" ? (
              <>
                <span className="spinner"></span>
                <span>Checking...</span>
              </>
            ) : (
              <>
                <span>🔍</span>
                <span>Check for Updates</span>
              </>
            )}
          </button>
        </Form>
      </div>

      {/* Update Available */}
      {updateInfo?.update_available && (
        <div className="card" style={{ marginBottom: "var(--space-6)", borderColor: "var(--color-accent)" }}>
          <h2 className="card-title" style={{ marginBottom: "var(--space-4)" }}>
            <span style={{ color: "var(--color-accent)" }}>✨</span> Update Available
          </h2>

          <div style={{ marginBottom: "var(--space-4)" }}>
            <div style={{ display: "flex", gap: "var(--space-4)", marginBottom: "var(--space-3)" }}>
              <div>
                <div className="label" style={{ fontSize: "0.75rem" }}>New Version</div>
                <div style={{ fontSize: "1.25rem", fontWeight: 700, color: "var(--color-accent)" }}>
                  v{updateInfo.latest_version}
                </div>
              </div>
              {updateInfo.download_size && (
                <div>
                  <div className="label" style={{ fontSize: "0.75rem" }}>Download Size</div>
                  <div style={{ fontSize: "1.25rem", fontWeight: 600 }}>
                    {formatBytes(updateInfo.download_size)}
                  </div>
                </div>
              )}
            </div>

            {updateInfo.release_date && (
              <p className="text-muted" style={{ fontSize: "0.875rem" }}>
                Released: {formatDate(updateInfo.release_date)}
              </p>
            )}

            {updateInfo.is_prerelease && (
              <div
                className="badge"
                style={{
                  backgroundColor: "var(--color-warning-bg)",
                  color: "var(--color-warning)",
                  marginTop: "var(--space-2)",
                }}
              >
                Pre-release
              </div>
            )}
          </div>

          {/* Changelog */}
          {updateInfo.changelog && (
            <div style={{ marginBottom: "var(--space-4)" }}>
              <div className="label" style={{ marginBottom: "var(--space-2)" }}>Release Notes</div>
              <div
                style={{
                  padding: "var(--space-3)",
                  background: "var(--color-bg)",
                  border: "1px solid var(--color-border)",
                  borderRadius: "var(--radius)",
                  maxHeight: "300px",
                  overflowY: "auto",
                  fontSize: "0.875rem",
                  lineHeight: 1.6,
                  whiteSpace: "pre-wrap",
                }}
              >
                {updateInfo.changelog}
              </div>
            </div>
          )}

          {/* Update Actions */}
          <div style={{ display: "flex", gap: "var(--space-2)", flexWrap: "wrap" }}>
            {progress?.status === "available" && (
              <Form method="post">
                <input type="hidden" name="_action" value="download_update" />
                <button type="submit" className="btn btn-primary" disabled={isSubmitting}>
                  {isSubmitting ? (
                    <>
                      <span className="spinner"></span>
                      <span>Starting...</span>
                    </>
                  ) : (
                    <>
                      <span>⬇️</span>
                      <span>Download Update</span>
                    </>
                  )}
                </button>
              </Form>
            )}

            {progress?.status === "downloading" && (
              <div style={{ flex: 1 }}>
                <div style={{ marginBottom: "var(--space-2)" }}>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: "0.875rem" }}>
                    <span>Downloading...</span>
                    <span>{Math.round(progress.download_progress)}%</span>
                  </div>
                  <div
                    style={{
                      width: "100%",
                      height: "8px",
                      background: "var(--color-border)",
                      borderRadius: "var(--radius)",
                      overflow: "hidden",
                      marginTop: "var(--space-2)",
                    }}
                  >
                    <div
                      style={{
                        width: `${progress.download_progress}%`,
                        height: "100%",
                        background: "linear-gradient(90deg, var(--color-primary), var(--color-accent))",
                        transition: "width 0.3s ease",
                      }}
                    />
                  </div>
                </div>
              </div>
            )}

            {(progress?.status === "idle" || progress?.download_progress === 100) &&
              updateInfo.update_available && (
                <Form method="post">
                  <input type="hidden" name="_action" value="install_update" />
                  <button type="submit" className="btn btn-accent" disabled={isSubmitting}>
                    {isSubmitting ? (
                      <>
                        <span className="spinner"></span>
                        <span>Installing...</span>
                      </>
                    ) : (
                      <>
                        <span>⚡</span>
                        <span>Install Update</span>
                      </>
                    )}
                  </button>
                </Form>
              )}

            {progress?.status === "installing" && (
              <div className="btn btn-accent" style={{ cursor: "default" }}>
                <span className="spinner"></span>
                <span>Installing Update...</span>
              </div>
            )}

            {progress?.status === "complete" && (
              <div style={{ flex: 1 }}>
                <div
                  className="card"
                  style={{
                    backgroundColor: "var(--color-success-bg)",
                    borderColor: "var(--color-success)",
                    padding: "var(--space-3)",
                  }}
                >
                  <p style={{ margin: 0 }}>
                    ✅ Update installed successfully! Please restart the service for changes to take effect.
                  </p>
                </div>
              </div>
            )}
          </div>

          {progress?.error_message && (
            <div
              className="card"
              style={{
                marginTop: "var(--space-4)",
                backgroundColor: "var(--color-danger-bg)",
                borderColor: "var(--color-danger)",
                padding: "var(--space-3)",
              }}
            >
              <p style={{ margin: 0, color: "var(--color-danger)" }}>
                ❌ {progress.error_message}
              </p>
            </div>
          )}
        </div>
      )}

      {/* No Update Available */}
      {updateInfo && !updateInfo.update_available && updateInfo.message && (
        <div className="card">
          <p style={{ margin: 0, textAlign: "center", color: "var(--color-text-muted)" }}>
            ✅ {updateInfo.message}
          </p>
        </div>
      )}
    </div>
  );
}
