// Copyright: © 2026 TWWIM UG. All rights reserved. (www.twwim.com)
/**
 * OperatorAvailabilityToggle — pill-shaped switch in the Comm Center header.
 *
 *  - green dot  + "I'm available" when isAvailable=true
 *  - grey dot   + "I'm away"      when isAvailable=false
 *  - neutral pill ("Not an operator") when the API returns 403 (caller is
 *    ADMIN / MANAGER / WORKER — they have no presence state to flip)
 *  - spinner while a mutation is in flight
 *
 * Click flips the value via PATCH /operator/availability. Persistence lives
 * in customer_data.company_membership.is_available; presence is the only
 * thing this toggle moves — routing logic (AI vs operator) is unchanged.
 */

import { Loader2 } from 'lucide-react';
import {
  useOperatorAvailability,
  useSetOperatorAvailability,
} from '../hooks/useOperatorAvailability';

interface ApiLikeError {
  status?: number;
  response?: { status?: number };
}

function statusOf(err: unknown): number | undefined {
  const candidate = err as ApiLikeError | null;
  return candidate?.status ?? candidate?.response?.status;
}

export function OperatorAvailabilityToggle() {
  const query = useOperatorAvailability();
  const mutation = useSetOperatorAvailability();

  // 403 → caller is not an OPERATOR; render a neutral disabled pill so the UI
  // doesn't lie about a non-existent presence flag.
  if (statusOf(query.error) === 403) {
    return (
      <span
        className="inline-flex items-center gap-2 rounded-full bg-gray-50 px-3 py-1.5 text-xs font-medium text-gray-500 ring-1 ring-inset ring-gray-200"
        data-testid="operator-availability-toggle"
        data-state="forbidden"
      >
        <span className="size-2 rounded-full bg-gray-300" />
        Not an operator
      </span>
    );
  }

  if (query.isLoading) {
    return (
      <span
        className="inline-flex items-center gap-2 rounded-full bg-gray-50 px-3 py-1.5 text-xs font-medium text-gray-500 ring-1 ring-inset ring-gray-200"
        data-testid="operator-availability-toggle"
        data-state="loading"
      >
        <Loader2 size={12} className="animate-spin" />
        Loading…
      </span>
    );
  }

  if (query.isError || !query.data) {
    return (
      <span
        className="inline-flex items-center gap-2 rounded-full bg-red-50 px-3 py-1.5 text-xs font-medium text-red-600 ring-1 ring-inset ring-red-200"
        data-testid="operator-availability-toggle"
        data-state="error"
      >
        <span className="size-2 rounded-full bg-red-400" />
        Availability unavailable
      </span>
    );
  }

  const { isAvailable } = query.data;
  const onToggle = () => {
    if (mutation.isPending) return;
    mutation.mutate({ isAvailable: !isAvailable });
  };

  const palette = isAvailable
    ? 'bg-emerald-50 text-emerald-700 ring-emerald-200 hover:bg-emerald-100'
    : 'bg-gray-50 text-gray-600 ring-gray-200 hover:bg-gray-100';

  const dot = isAvailable
    ? 'bg-emerald-500 animate-pulse'
    : 'bg-gray-400';

  return (
    <button
      type="button"
      onClick={onToggle}
      disabled={mutation.isPending}
      aria-pressed={isAvailable}
      data-testid="operator-availability-toggle"
      data-state={isAvailable ? 'available' : 'away'}
      className={`inline-flex items-center gap-2 rounded-full px-3 py-1.5 text-xs font-medium ring-1 ring-inset transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${palette}`}
    >
      {mutation.isPending ? (
        <Loader2 size={12} className="animate-spin" />
      ) : (
        <span className={`size-2 rounded-full ${dot}`} />
      )}
      {isAvailable ? "I'm available" : "I'm away"}
    </button>
  );
}
