import React, { useState, useEffect } from 'react';
import Button from './ui/Button';
import { Input, Textarea } from './ui/FormField';

function widthToSpan(pct) {
  if (pct <= 8)  return 1;
  if (pct <= 17) return 2;
  if (pct <= 25) return 3;
  if (pct <= 33) return 4;
  if (pct <= 42) return 5;
  if (pct <= 50) return 6;
  if (pct <= 67) return 8;
  if (pct <= 75) return 9;
  return 12;
}
import Alert from './ui/Alert';
import { animalsApi, experimentsApi } from '../api/client';

export default function SubjectInfoForm({ animal, subjectTemplate = [], experimentId, onTemplateUpdate, onSaved, onCancel }) {
  const activeFields = subjectTemplate.filter((f) => f.active);

  function buildInitialValues() {
    const vals = {};
    for (const f of activeFields) {
      vals[f.key] = animal?.subject_info?.[f.fieldId] ?? '';
    }
    return vals;
  }

  const [values, setValues] = useState(buildInitialValues);
  const [apiError, setApiError] = useState(null);
  const [loading, setLoading] = useState(false);
  const [savingTagFor, setSavingTagFor] = useState(null);

  useEffect(() => {
    setValues(buildInitialValues());
    setApiError(null);
  }, [animal, subjectTemplate]);

  const set = (key) => (e) => setValues((v) => ({ ...v, [key]: e.target.value }));

  async function saveTag(field) {
    const value = (values[field.key] ?? '').trim();
    if (!value || !experimentId || !onTemplateUpdate) return;
    setSavingTagFor(field.fieldId);
    try {
      const updatedTemplate = subjectTemplate.map((f) =>
        f.fieldId === field.fieldId
          ? { ...f, tags: [...(f.tags ?? []), value] }
          : f
      );
      await experimentsApi.updateSubjectTemplate(experimentId, updatedTemplate);
      onTemplateUpdate(updatedTemplate);
    } catch (_) {
    } finally {
      setSavingTagFor(null);
    }
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setLoading(true);
    setApiError(null);
    try {
      // Preserve any fields not in the current active template
      const existing = animal?.subject_info ?? {};
      const updates = {};
      for (const f of activeFields) {
        updates[f.fieldId] = values[f.key] || null;
      }
      const merged = { ...existing, ...updates };

      const updated = await animalsApi.update(animal.id, { subject_info: merged });
      onSaved(updated);
    } catch (err) {
      setApiError(err);
    } finally {
      setLoading(false);
    }
  }

  if (activeFields.length === 0) {
    return (
      <div className="text-center py-6">
        <p className="text-sm text-gray-400 italic">No subject info fields configured for this experiment.</p>
        <p className="text-xs text-gray-400 mt-1">Use "Subject Template" on the experiment page to add fields.</p>
        <div className="flex justify-end mt-4">
          <Button variant="secondary" type="button" onClick={onCancel}>Close</Button>
        </div>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} noValidate>
      {apiError && (
        <Alert type="error" message={apiError.message} details={apiError.details} onDismiss={() => setApiError(null)} />
      )}

      <div className="grid grid-cols-12 gap-x-3 gap-y-2 mb-4">
        {activeFields.map((field) => {
          const isTextarea = field.type === 'textarea';
          const span = isTextarea ? 12 : widthToSpan(field.width ?? 100);
          const fieldTags = field.tags ?? [];
          const currentValue = (values[field.key] ?? '').trim();
          const canSaveTag = experimentId && onTemplateUpdate && currentValue && !fieldTags.includes(currentValue) && !field.tagsDisabled;
          return (
            <div key={field.fieldId} className={`col-span-${span} flex items-start gap-2`}>
              <label className="text-xs font-medium text-gray-500 whitespace-nowrap w-28 shrink-0 text-right pt-1.5">{field.label}</label>
              <div className="flex-1 min-w-0">
                {isTextarea ? (
                  <Textarea name={field.key} value={values[field.key] ?? ''} onChange={set(field.key)} disabled={loading} />
                ) : (
                  <Input name={field.key} value={values[field.key] ?? ''} onChange={set(field.key)} disabled={loading} />
                )}
                {(fieldTags.length > 0 || canSaveTag) && (
                  <div className="flex flex-wrap items-center gap-1.5 mt-1">
                    {fieldTags.map((tag) => (
                      <button key={tag} type="button" title={`Quick-fill: ${tag}`}
                        onClick={() => setValues((v) => ({ ...v, [field.key]: tag }))}
                        className="inline-flex items-center px-2 py-0.5 rounded-full bg-indigo-50 border border-indigo-200 text-indigo-700 text-xs font-medium hover:bg-indigo-100 transition-colors">
                        {tag}
                      </button>
                    ))}
                    {canSaveTag && (
                      <button type="button" onClick={() => saveTag(field)} disabled={savingTagFor === field.fieldId}
                        title="Save current value as a quick-fill tag"
                        className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full border border-dashed border-indigo-300 text-indigo-500 text-xs hover:border-indigo-500 hover:text-indigo-700 transition-colors disabled:opacity-50">
                        {savingTagFor === field.fieldId ? '…' : '+ Save as tag'}
                      </button>
                    )}
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>

      <div className="flex justify-end gap-3 pt-2 border-t border-gray-100">
        <Button variant="secondary" type="button" onClick={onCancel} disabled={loading}>Cancel</Button>
        <Button type="submit" loading={loading}>Save</Button>
      </div>
    </form>
  );
}
