"use client";

import { useState, useMemo, useEffect } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";

interface PibiMeasureSelectorProps {
  dealId: string;
  portfolioId: string;
  proposedMeasures: string[];
  canEdit: boolean;
}

export function PibiMeasureSelector({
  dealId,
  portfolioId,
  proposedMeasures,
  canEdit,
}: PibiMeasureSelectorProps) {
  const queryClient = useQueryClient();

  const { data, isLoading } = useQuery<{
    pibiMeasures: string[];
    approvedMeasures: string[];
    instructedMeasures: string[];
  }>({
    queryKey: ["pibiMeasures", portfolioId, dealId],
    queryFn: async () => {
      const res = await fetch(
        `/api/portfolio/${portfolioId}/pibi-measures?dealId=${encodeURIComponent(dealId)}`,
      );
      if (!res.ok) throw new Error("Failed to fetch PIBI measures");
      return res.json();
    },
    staleTime: 30_000,
  });

  const allMeasures = useMemo(() => {
    const instructed = data?.instructedMeasures ?? [];
    const all = [...proposedMeasures];
    for (const m of instructed) {
      if (!all.includes(m)) all.push(m);
    }
    return all;
  }, [proposedMeasures, data?.instructedMeasures]);

  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [initialised, setInitialised] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!data) return;
    const initial =
      data.pibiMeasures.length > 0
        ? data.pibiMeasures
        : data.approvedMeasures;
    setSelected(new Set(initial));
    setInitialised(true);
    setError(null);
  }, [dealId, data]);

  function toggleMeasure(measure: string) {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(measure)) {
        next.delete(measure);
      } else {
        next.add(measure);
      }
      return next;
    });
  }

  async function handleSave() {
    setSubmitting(true);
    setError(null);
    const measureNames = Array.from(selected);
    try {
      const res = await fetch(
        `/api/portfolio/${portfolioId}/pibi-measures`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ dealId, measureNames }),
        },
      );
      if (!res.ok) {
        const json = await res.json().catch(() => ({}));
        setError(
          typeof json.error === "string"
            ? json.error
            : "Failed to save PIBI selections",
        );
        return;
      }
      const json = (await res.json()) as {
        ok: boolean;
        hubspotSync: "ok" | "failed";
        hubspotError?: string;
      };
      if (json.hubspotSync === "failed") {
        setError(
          json.hubspotError
            ? `Saved locally — HubSpot sync failed: ${json.hubspotError}`
            : "Saved locally — HubSpot sync failed",
        );
      }
      queryClient.invalidateQueries({
        queryKey: ["pibiMeasures", portfolioId, dealId],
      });
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Failed to save PIBI selections",
      );
    } finally {
      setSubmitting(false);
    }
  }

  if (!canEdit) return null;

  if (isLoading || !initialised) {
    return (
      <p
        data-testid="pibi-selector-loading"
        className="text-xs text-gray-400 py-2"
      >
        Loading…
      </p>
    );
  }

  if (allMeasures.length === 0) {
    return (
      <p className="text-xs text-gray-400 py-2">
        No measures associated with this deal yet.
      </p>
    );
  }

  return (
    <div className="space-y-3">
      <p className="text-xs text-gray-500 font-medium">PIBI Measure Selection</p>
      <div
        data-testid="pibi-measure-selector"
        className="flex flex-wrap gap-2"
      >
        {allMeasures.map((measure) => {
          const checked = selected.has(measure);
          const isApproved = (data?.approvedMeasures ?? []).includes(measure);
          return (
            <label
              key={measure}
              data-testid={`pibi-measure-option-${measure}`}
              className={`flex items-center gap-1.5 cursor-pointer px-2.5 py-1 rounded-full text-xs border transition-colors ${
                checked
                  ? "bg-brandblue/10 border-brandblue/40 text-brandblue font-medium"
                  : "bg-gray-50 border-gray-200 text-gray-600 hover:bg-gray-100"
              }`}
            >
              <input
                type="checkbox"
                className="sr-only"
                checked={checked}
                onChange={() => toggleMeasure(measure)}
                disabled={submitting}
                data-testid={`pibi-measure-checkbox-${measure}`}
              />
              <span
                className={`w-3 h-3 rounded-sm border flex items-center justify-center shrink-0 ${
                  checked
                    ? "bg-brandblue border-brandblue"
                    : "bg-white border-gray-300"
                }`}
              >
                {checked && (
                  <svg viewBox="0 0 10 8" className="w-2 h-2 fill-white">
                    <path d="M1 4l3 3 5-6" stroke="white" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                )}
              </span>
              {measure}
              {isApproved && (
                <span className="text-[10px] text-emerald-600 font-semibold ml-0.5">
                  ✓
                </span>
              )}
            </label>
          );
        })}
      </div>
      <div className="flex items-center justify-between gap-3">
        <p className="text-[11px] text-gray-400">
          Tick measures going for PIBI. Approved measures are pre-ticked (✓).
        </p>
        <button
          type="button"
          data-testid="pibi-selector-save"
          onClick={handleSave}
          disabled={submitting}
          className="text-xs font-medium px-3 py-1.5 rounded-lg bg-brandblue text-white hover:bg-brandmidblue disabled:opacity-50 transition-colors"
        >
          {submitting ? "Saving…" : "Save PIBI Selections"}
        </button>
      </div>
      {error && (
        <p
          data-testid="pibi-selector-error"
          className="text-xs text-red-600 bg-red-50 px-3 py-2 rounded-lg"
        >
          {error}
        </p>
      )}
    </div>
  );
}
