/**
 * FaceGallery.jsx — Enrolled person management.
 *
 * Services:
 *   /social/enrollment/list_persons   (ListPersons.srv)
 *   /social/enrollment/enroll_person  (EnrollPerson.srv)
 *   /social/enrollment/delete_person  (DeletePerson.srv)
 *
 * Topics (live detections):
 *   /social/face_detections (FaceDetectionArray) — optional, shows live bboxes
 */

import { useEffect, useState, useCallback } from 'react';

function PersonCard({ person, onDelete, liveDetection }) {
  const [deleting, setDeleting] = useState(false);

  const enrolledAt = person.enrolled_at
    ? new Date(person.enrolled_at.sec * 1000).toLocaleDateString()
    : '—';

  const handleDelete = async () => {
    if (!confirm(`Delete ${person.person_name}?`)) return;
    setDeleting(true);
    try {
      await onDelete(person.person_id);
    } finally {
      setDeleting(false);
    }
  };

  const isActive = liveDetection?.face_id === person.person_id;

  return (
    <div className={`bg-gray-900 rounded-lg border p-3 flex flex-col gap-2 transition-colors ${
      isActive ? 'border-green-600 bg-green-950' : 'border-gray-800'
    }`}>
      {/* Avatar placeholder */}
      <div className="w-full aspect-square rounded bg-gray-800 border border-gray-700 flex items-center justify-center relative overflow-hidden">
        <svg className="w-12 h-12 text-gray-600" fill="currentColor" viewBox="0 0 24 24">
          <path d="M12 12c2.7 0 4.8-2.1 4.8-4.8S14.7 2.4 12 2.4 7.2 4.5 7.2 7.2 9.3 12 12 12zm0 2.4c-3.2 0-9.6 1.6-9.6 4.8v2.4h19.2v-2.4c0-3.2-6.4-4.8-9.6-4.8z"/>
        </svg>
        {isActive && (
          <div className="absolute inset-0 border-2 border-green-500 rounded pointer-events-none" />
        )}
        <div className="absolute top-1 right-1">
          <div className={`w-2 h-2 rounded-full ${isActive ? 'bg-green-400' : 'bg-gray-700'}`} />
        </div>
      </div>

      {/* Info */}
      <div>
        <div className="text-cyan-300 text-sm font-bold truncate">{person.person_name}</div>
        <div className="text-gray-600 text-xs">ID: {person.person_id}</div>
        <div className="text-gray-600 text-xs">Samples: {person.sample_count}</div>
        <div className="text-gray-600 text-xs">Enrolled: {enrolledAt}</div>
      </div>

      {/* Delete */}
      <button
        onClick={handleDelete}
        disabled={deleting}
        className="w-full py-1 text-xs rounded border border-red-900 text-red-400 hover:bg-red-950 hover:border-red-700 disabled:opacity-40 transition-colors"
      >
        {deleting ? 'Deleting…' : 'Delete'}
      </button>
    </div>
  );
}

export function FaceGallery({ subscribe, callService }) {
  const [persons, setPersons] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [enrolling, setEnrolling] = useState(false);
  const [newName, setNewName] = useState('');
  const [newSamples, setNewSamples] = useState(5);
  const [liveDetections, setLiveDetections] = useState([]);

  const loadPersons = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await callService(
        '/social/enrollment/list_persons',
        'saltybot_social_msgs/srv/ListPersons',
        {}
      );
      setPersons(result?.persons ?? []);
    } catch (e) {
      setError('Service unavailable: ' + (e?.message ?? e));
    } finally {
      setLoading(false);
    }
  }, [callService]);

  useEffect(() => {
    loadPersons();
  }, [loadPersons]);

  // Live face detections
  useEffect(() => {
    const unsub = subscribe(
      '/social/face_detections',
      'saltybot_social_msgs/FaceDetectionArray',
      (msg) => setLiveDetections(msg.faces ?? [])
    );
    return unsub;
  }, [subscribe]);

  const handleEnroll = async () => {
    if (!newName.trim()) return;
    setEnrolling(true);
    setError(null);
    try {
      const result = await callService(
        '/social/enrollment/enroll_person',
        'saltybot_social_msgs/srv/EnrollPerson',
        { name: newName.trim(), mode: 'capture', n_samples: newSamples }
      );
      if (result?.success) {
        setNewName('');
        await loadPersons();
      } else {
        setError(result?.message ?? 'Enrollment failed');
      }
    } catch (e) {
      setError('Enroll error: ' + (e?.message ?? e));
    } finally {
      setEnrolling(false);
    }
  };

  const handleDelete = async (personId) => {
    try {
      await callService(
        '/social/enrollment/delete_person',
        'saltybot_social_msgs/srv/DeletePerson',
        { person_id: personId }
      );
      await loadPersons();
    } catch (e) {
      setError('Delete error: ' + (e?.message ?? e));
    }
  };

  return (
    <div className="space-y-4">
      {/* Enroll new person */}
      <div className="bg-gray-950 rounded-lg border border-cyan-950 p-4">
        <div className="text-cyan-700 text-xs font-bold tracking-widest mb-3">ENROLL NEW PERSON</div>
        <div className="flex flex-col sm:flex-row gap-2">
          <input
            type="text"
            placeholder="Person name…"
            value={newName}
            onChange={(e) => setNewName(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && handleEnroll()}
            className="flex-1 bg-gray-900 border border-gray-700 rounded px-3 py-1.5 text-sm text-gray-200 placeholder-gray-600 focus:outline-none focus:border-cyan-700"
          />
          <div className="flex items-center gap-2">
            <span className="text-gray-500 text-xs shrink-0">Samples:</span>
            <input
              type="number"
              min={1}
              max={20}
              value={newSamples}
              onChange={(e) => setNewSamples(Number(e.target.value))}
              className="w-16 bg-gray-900 border border-gray-700 rounded px-2 py-1.5 text-sm text-gray-200 focus:outline-none focus:border-cyan-700"
            />
          </div>
          <button
            onClick={handleEnroll}
            disabled={enrolling || !newName.trim()}
            className="px-4 py-1.5 rounded bg-cyan-950 hover:bg-cyan-900 border border-cyan-700 text-cyan-300 text-sm disabled:opacity-40 transition-colors"
          >
            {enrolling ? 'Capturing…' : 'Enroll'}
          </button>
        </div>
        {enrolling && (
          <div className="mt-2 text-amber-400 text-xs animate-pulse">
            Capturing face samples — look at the camera…
          </div>
        )}
      </div>

      {/* Error */}
      {error && (
        <div className="bg-red-950 border border-red-800 rounded px-3 py-2 text-red-300 text-xs">
          {error}
        </div>
      )}

      {/* Gallery header */}
      <div className="flex items-center justify-between">
        <div className="text-cyan-700 text-xs font-bold tracking-widest">
          ENROLLED PERSONS ({persons.length})
        </div>
        <div className="flex items-center gap-2">
          {liveDetections.length > 0 && (
            <div className="flex items-center gap-1 text-green-400 text-xs">
              <div className="w-1.5 h-1.5 rounded-full bg-green-400 animate-pulse" />
              {liveDetections.length} detected
            </div>
          )}
          <button
            onClick={loadPersons}
            disabled={loading}
            className="px-2 py-1 rounded border border-gray-700 text-gray-400 hover:text-gray-200 text-xs disabled:opacity-40 transition-colors"
          >
            {loading ? '…' : 'Refresh'}
          </button>
        </div>
      </div>

      {/* Grid */}
      {loading && persons.length === 0 ? (
        <div className="text-gray-600 text-sm text-center py-8">Loading…</div>
      ) : persons.length === 0 ? (
        <div className="text-gray-600 text-sm text-center py-8 border border-dashed border-gray-800 rounded-lg">
          No enrolled persons
        </div>
      ) : (
        <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
          {persons.map((p) => (
            <PersonCard
              key={p.person_id}
              person={p}
              onDelete={handleDelete}
              liveDetection={liveDetections.find(d => d.face_id === p.person_id)}
            />
          ))}
        </div>
      )}
    </div>
  );
}
