import { useState, useEffect } from "react";
import api from "../../api/client";

function computeStepsAndNotes(stepsStr) {
  if (!stepsStr || !stepsStr.trim()) return { steps: 0, totalNotes: 0 };
  const tokens = stepsStr.trim().split(",");
  const bellSet = new Set();
  for (const token of tokens) {
    for (const part of token.split("+")) {
      const n = parseInt(part.trim(), 10);
      if (!isNaN(n) && n >= 1 && n <= 16) bellSet.add(n);
    }
  }
  return { steps: tokens.length, totalNotes: bellSet.size || 1 };
}

export default function SelectBuiltMelodyModal({ open, melodyId, currentMelody, onClose, onSuccess }) {
  const [melodies, setMelodies] = useState([]);
  const [loading, setLoading] = useState(false);
  const [assigning, setAssigning] = useState(null); // id of the one being assigned
  const [error, setError] = useState("");

  useEffect(() => {
    if (open) loadMelodies();
  }, [open]);

  const loadMelodies = async () => {
    setLoading(true);
    setError("");
    try {
      const data = await api.get("/builder/melodies");
      // Only show those with a built binary
      setMelodies((data.melodies || []).filter((m) => m.binary_path));
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const handleSelect = async (builtMelody) => {
    setAssigning(builtMelody.id);
    setError("");
    try {
      // 1. Fetch the .bsm file from the builder endpoint
      const token = localStorage.getItem("access_token");
      const res = await fetch(`/api${builtMelody.binary_url}`, {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error(`Failed to download binary: ${res.statusText}`);
      const blob = await res.blob();
      const file = new File([blob], `${builtMelody.name}.bsm`, { type: "application/octet-stream" });

      // 2. Upload to Firebase Storage via the existing melody upload endpoint
      await api.upload(`/melodies/${melodyId}/upload/binary`, file);

      // 3. Mark this built melody as assigned to this Firestore melody
      await api.post(`/builder/melodies/${builtMelody.id}/assign?firestore_melody_id=${melodyId}`);

      // 4. Update the melody's information with archetype_csv, steps, and totalNotes
      const csv = builtMelody.steps || "";
      const { steps, totalNotes } = computeStepsAndNotes(csv);
      if (currentMelody && csv) {
        const existingInfo = currentMelody.information || {};
        await api.put(`/melodies/${melodyId}`, {
          information: {
            ...existingInfo,
            archetype_csv: csv,
            steps,
            totalNotes,
          },
          default_settings: currentMelody.default_settings,
          type: currentMelody.type,
          url: currentMelody.url,
          uid: currentMelody.uid,
          pid: currentMelody.pid,
        });
      }

      onSuccess({ name: builtMelody.name, pid: builtMelody.pid, steps, totalNotes, archetype_csv: csv });
    } catch (err) {
      setError(err.message);
    } finally {
      setAssigning(null);
    }
  };

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 flex items-center justify-center z-50"
      style={{ backgroundColor: "rgba(0,0,0,0.6)" }}
      onClick={(e) => e.target === e.currentTarget && onClose()}
    >
      <div
        className="w-full max-w-2xl rounded-lg border shadow-xl"
        style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
      >
        <div className="flex items-center justify-between px-6 py-4 border-b" style={{ borderColor: "var(--border-primary)" }}>
          <h2 className="text-lg font-semibold" style={{ color: "var(--text-heading)" }}>Select Built Melody</h2>
          <button onClick={onClose} className="text-xl leading-none" style={{ color: "var(--text-muted)" }}>&times;</button>
        </div>

        <div className="p-6">
          {error && (
            <div className="text-sm rounded-md p-3 mb-4 border" style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
              {error}
            </div>
          )}

          {loading ? (
            <div className="text-center py-8" style={{ color: "var(--text-muted)" }}>Loading...</div>
          ) : melodies.length === 0 ? (
            <div className="text-center py-8 text-sm" style={{ color: "var(--text-muted)" }}>
              No built binaries found. Go to <strong>Melody Builder</strong> to create one first.
            </div>
          ) : (
            <div className="space-y-2 max-h-96 overflow-y-auto">
              {melodies.map((m) => (
                <div
                  key={m.id}
                  className="flex items-center justify-between rounded-lg px-4 py-3 border transition-colors"
                  style={{ borderColor: "var(--border-primary)", backgroundColor: "var(--bg-primary)" }}
                >
                  <div>
                    <p className="text-sm font-medium" style={{ color: "var(--text-heading)" }}>{m.name}</p>
                    <p className="text-xs mt-0.5 font-mono" style={{ color: "var(--text-muted)" }}>
                      PID: {m.pid || "—"} &nbsp;·&nbsp; {m.steps?.split(",").length || 0} steps
                    </p>
                  </div>
                  <button
                    onClick={() => handleSelect(m)}
                    disabled={Boolean(assigning)}
                    className="px-3 py-1.5 text-xs rounded-md disabled:opacity-50 transition-colors font-medium"
                    style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}
                  >
                    {assigning === m.id ? "Uploading..." : "Select & Upload"}
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>

        <div className="flex justify-end px-6 py-4 border-t" style={{ borderColor: "var(--border-primary)" }}>
          <button onClick={onClose} className="px-4 py-2 text-sm rounded-md transition-colors" style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-primary)" }}>
            Cancel
          </button>
        </div>
      </div>
    </div>
  );
}
