import { useState, useEffect, useRef, useCallback } from "react";
import { api } from "../services/api";
import { useWebSocket } from "../hooks/useWebSocket";
import {
  Hammer,
  Package,
  Cpu,
  Play,
  Archive,
  Upload,
  ChevronDown,
  ChevronUp,
  AlertTriangle,
} from "lucide-react";

type BuildStatus = "idle" | "building" | "success" | "failed";

interface BuildSectionState {
  status: BuildStatus;
  output: string[];
  collapsed: boolean;
}

function StatusBadge({ status }: { status: BuildStatus }) {
  const styles: Record<BuildStatus, React.CSSProperties> = {
    idle: {
      backgroundColor: "var(--forge-surface-raised)",
      color: "var(--forge-text-secondary)",
    },
    building: {
      backgroundColor: "var(--forge-warning-bg)",
      color: "var(--forge-warning)",
    },
    success: {
      backgroundColor: "var(--forge-success-bg)",
      color: "var(--forge-success)",
    },
    failed: {
      backgroundColor: "var(--forge-danger-bg)",
      color: "var(--forge-danger)",
    },
  };

  return (
    <span
      style={{
        ...styles[status],
        borderRadius: "9999px",
        padding: "0.125rem 0.625rem",
        fontSize: "var(--text-xs)",
        fontWeight: 600,
        fontFamily: "var(--font-mono)",
        textTransform: "uppercase" as const,
        letterSpacing: "0.03em",
      }}
    >
      {status}
    </span>
  );
}

function BuildOutput({
  lines,
  collapsed,
  onToggle,
}: {
  lines: string[];
  collapsed: boolean;
  onToggle: () => void;
}) {
  const scrollRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!collapsed && scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [lines, collapsed]);

  return (
    <div style={{ marginTop: "0.75rem" }}>
      <button
        onClick={onToggle}
        style={{
          display: "flex",
          alignItems: "center",
          gap: "0.375rem",
          fontSize: "var(--text-xs)",
          color: "var(--forge-text-secondary)",
          background: "none",
          border: "none",
          cursor: "pointer",
          padding: "0.25rem 0",
          fontFamily: "var(--font-sans)",
        }}
      >
        {collapsed ? <ChevronDown size={14} /> : <ChevronUp size={14} />}
        <span>Output ({lines.length} lines)</span>
      </button>
      {!collapsed && (
        <div
          ref={scrollRef}
          style={{
            marginTop: "0.5rem",
            maxHeight: "16rem",
            overflowY: "auto",
            borderRadius: "0.5rem",
            padding: "0.875rem 1rem",
            backgroundColor: "var(--forge-log-bg)",
            fontFamily: "var(--font-mono)",
            fontSize: "var(--text-xs)",
            lineHeight: "1.6",
          }}
        >
          {lines.length === 0 ? (
            <span style={{ color: "var(--forge-text-secondary)", fontStyle: "italic" }}>
              No output yet
            </span>
          ) : (
            lines.map((line, i) => (
              <div key={i} style={{ color: "var(--forge-log-text)" }}>
                {line}
              </div>
            ))
          )}
        </div>
      )}
    </div>
  );
}

function ActionButton({
  label,
  onClick,
  disabled,
  variant = "default",
  icon,
}: {
  label: string;
  onClick: () => void;
  disabled?: boolean;
  variant?: "default" | "primary" | "warning";
  icon?: React.ReactNode;
}) {
  const variantStyles: Record<string, React.CSSProperties> = {
    default: {
      backgroundColor: "var(--forge-surface-raised)",
      border: "1px solid var(--forge-border)",
      color: "var(--forge-text)",
    },
    primary: {
      backgroundColor: "var(--forge-accent)",
      border: "none",
      color: "var(--forge-accent-text)",
    },
    warning: {
      backgroundColor: "var(--forge-warning-bg)",
      border: "1px solid var(--forge-warning-border)",
      color: "var(--forge-warning)",
    },
  };

  return (
    <button
      onClick={onClick}
      disabled={disabled}
      style={{
        ...variantStyles[variant],
        borderRadius: "0.375rem",
        padding: "0.5rem 1rem",
        fontSize: "var(--text-sm)",
        fontWeight: 600,
        fontFamily: "var(--font-sans)",
        cursor: disabled ? "not-allowed" : "pointer",
        opacity: disabled ? 0.5 : 1,
        display: "inline-flex",
        alignItems: "center",
        gap: "0.375rem",
        transition: "opacity 0.15s ease",
      }}
    >
      {icon}
      {label}
    </button>
  );
}

export function Build() {
  const { subscribe } = useWebSocket();

  const [module, setModule] = useState<BuildSectionState>({
    status: "idle",
    output: [],
    collapsed: true,
  });
  const [haks, setHaks] = useState<BuildSectionState>({
    status: "idle",
    output: [],
    collapsed: true,
  });
  const [nwnx, setNwnx] = useState<BuildSectionState>({
    status: "idle",
    output: [],
    collapsed: true,
  });
  const [nwnxTarget, setNwnxTarget] = useState("");

  useEffect(() => {
    const unsubs = [
      subscribe("build:start", (event) => {
        const data = event.data as Record<string, string>;
        const section = data?.section;
        const setter =
          section === "haks" ? setHaks : section === "nwnx" ? setNwnx : setModule;
        setter((prev) => ({ ...prev, status: "building", output: [], collapsed: false }));
      }),
      subscribe("build:complete", (event) => {
        const data = event.data as Record<string, string>;
        const section = data?.section;
        const setter =
          section === "haks" ? setHaks : section === "nwnx" ? setNwnx : setModule;
        setter((prev) => ({ ...prev, status: "success" }));
      }),
      subscribe("build:failed", (event) => {
        const data = event.data as Record<string, string>;
        const section = data?.section;
        const setter =
          section === "haks" ? setHaks : section === "nwnx" ? setNwnx : setModule;
        setter((prev) => ({ ...prev, status: "failed" }));
      }),
      subscribe("build:output", (event) => {
        const data = event.data as { text?: string; section?: string };
        if (!data?.text) return;
        const section = data.section;
        const setter =
          section === "haks" ? setHaks : section === "nwnx" ? setNwnx : setModule;
        setter((prev) => ({
          ...prev,
          output: [...prev.output, ...data.text!.split("\n").filter(Boolean)],
        }));
      }),
    ];
    return () => unsubs.forEach((u) => u());
  }, [subscribe]);

  const handleAction = useCallback(
    async (action: () => Promise<unknown>, section: "module" | "haks" | "nwnx") => {
      const setter =
        section === "haks" ? setHaks : section === "nwnx" ? setNwnx : setModule;
      setter((prev) => ({ ...prev, status: "building", output: [], collapsed: false }));
      try {
        await action();
      } catch {
        setter((prev) => ({ ...prev, status: "failed" }));
      }
    },
    [],
  );

  const isBuilding =
    module.status === "building" || haks.status === "building" || nwnx.status === "building";

  const cardStyle: React.CSSProperties = {
    backgroundColor: "var(--forge-surface)",
    border: "1px solid var(--forge-border)",
    borderRadius: "0.75rem",
    padding: "1.25rem",
    marginBottom: "1rem",
  };

  const sectionHeaderStyle: React.CSSProperties = {
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    marginBottom: "1rem",
  };

  const sectionTitleStyle: React.CSSProperties = {
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    textTransform: "uppercase",
    fontSize: "var(--text-xs)",
    fontWeight: 600,
    letterSpacing: "0.05em",
    color: "var(--forge-text-secondary)",
    fontFamily: "var(--font-heading)",
  };

  const buttonRowStyle: React.CSSProperties = {
    display: "flex",
    flexWrap: "wrap",
    gap: "0.5rem",
    alignItems: "center",
  };

  return (
    <div
      style={{
        height: "100%",
        overflowY: "auto",
        padding: "1.5rem",
        color: "var(--forge-text)",
      }}
    >
      <div style={{ marginBottom: "1.5rem" }}>
        <h2
          style={{
            fontFamily: "var(--font-heading)",
            fontSize: "var(--text-xl)",
            fontWeight: 700,
            color: "var(--forge-text)",
            margin: 0,
          }}
        >
          Build Pipeline
        </h2>
        <p
          style={{
            fontFamily: "var(--font-sans)",
            fontSize: "var(--text-sm)",
            color: "var(--forge-text-secondary)",
            margin: "0.375rem 0 0 0",
          }}
        >
          Compile, pack, and deploy module resources
        </p>
      </div>

      {/* Module Section */}
      <section style={cardStyle}>
        <div style={sectionHeaderStyle}>
          <div style={sectionTitleStyle}>
            <Hammer size={14} />
            <span>Module</span>
          </div>
          <StatusBadge status={module.status} />
        </div>
        <div style={buttonRowStyle}>
          <ActionButton
            label="Compile"
            variant="primary"
            icon={<Play size={14} />}
            disabled={isBuilding}
            onClick={() => handleAction(() => api.build.compileModule(), "module")}
          />
          <ActionButton
            label="Pack Module"
            icon={<Archive size={14} />}
            disabled={isBuilding}
            onClick={() => handleAction(() => api.build.packModule(), "module")}
          />
          <ActionButton
            label="Deploy to Server"
            variant="warning"
            icon={<Upload size={14} />}
            disabled={isBuilding}
            onClick={() => handleAction(() => api.build.deploy(), "module")}
          />
        </div>
        <BuildOutput
          lines={module.output}
          collapsed={module.collapsed}
          onToggle={() => setModule((prev) => ({ ...prev, collapsed: !prev.collapsed }))}
        />
      </section>

      {/* Haks Section */}
      <section style={cardStyle}>
        <div style={sectionHeaderStyle}>
          <div style={sectionTitleStyle}>
            <Package size={14} />
            <span>Haks</span>
          </div>
          <StatusBadge status={haks.status} />
        </div>
        <div style={buttonRowStyle}>
          <ActionButton
            label="Build Haks"
            variant="primary"
            icon={<Play size={14} />}
            disabled={isBuilding}
            onClick={() => handleAction(() => api.build.buildHaks(), "haks")}
          />
        </div>
        <BuildOutput
          lines={haks.output}
          collapsed={haks.collapsed}
          onToggle={() => setHaks((prev) => ({ ...prev, collapsed: !prev.collapsed }))}
        />
      </section>

      {/* NWNX Section */}
      <section style={cardStyle}>
        <div style={sectionHeaderStyle}>
          <div style={sectionTitleStyle}>
            <Cpu size={14} />
            <span>NWNX</span>
            <span
              style={{
                fontWeight: 400,
                textTransform: "none",
                opacity: 0.6,
                letterSpacing: "normal",
              }}
            >
              (Advanced)
            </span>
          </div>
          <StatusBadge status={nwnx.status} />
        </div>
        <div style={{ ...buttonRowStyle, marginBottom: "0.75rem" }}>
          <ActionButton
            label="Build All"
            variant="primary"
            icon={<Play size={14} />}
            disabled={isBuilding}
            onClick={() => handleAction(() => api.build.buildNwnx(), "nwnx")}
          />
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
          <input
            type="text"
            value={nwnxTarget}
            onChange={(e) => setNwnxTarget(e.target.value)}
            placeholder="Target (e.g. Item, Creature)"
            style={{
              backgroundColor: "var(--forge-bg)",
              border: "1px solid var(--forge-border)",
              borderRadius: "0.375rem",
              padding: "0.5rem 0.75rem",
              fontSize: "var(--text-sm)",
              color: "var(--forge-text)",
              fontFamily: "var(--font-sans)",
              outline: "none",
              flex: "0 1 16rem",
            }}
          />
          <ActionButton
            label="Build Target"
            disabled={isBuilding || !nwnxTarget.trim()}
            onClick={() =>
              handleAction(() => api.build.buildNwnx(nwnxTarget.trim()), "nwnx")
            }
          />
        </div>
        <p
          style={{
            marginTop: "0.75rem",
            marginBottom: 0,
            fontSize: "var(--text-xs)",
            color: "var(--forge-warning)",
            display: "flex",
            alignItems: "center",
            gap: "0.375rem",
          }}
        >
          <AlertTriangle size={12} />
          Requires server restart to pick up changes
        </p>
        <BuildOutput
          lines={nwnx.output}
          collapsed={nwnx.collapsed}
          onToggle={() => setNwnx((prev) => ({ ...prev, collapsed: !prev.collapsed }))}
        />
      </section>
    </div>
  );
}
