import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useParams, useNavigate, useSearchParams, Link } from 'react-router-dom';
import { format } from 'date-fns';
import {
  ResponsiveContainer, BarChart, Bar, XAxis, YAxis,
  CartesianGrid, Tooltip, Legend,
} from 'recharts';
import { experimentsApi, dailyStatusesApi } from '../api/client';
import Button from '../components/ui/Button';
import Modal from '../components/ui/Modal';
import DailyStatusForm from '../components/DailyStatusForm';
import Alert from '../components/ui/Alert';
import FileDropZone from '../components/FileDropZone';

const BUILTIN_KEYS_SET = new Set(['experiment_description', 'vitals', 'treatment', 'notes']);

function getFieldValue(status, field) {
  if (field.builtin) return status[field.key];
  return status.custom_fields?.[field.fieldId];
}

function cellText(value) {
  if (value === null || value === undefined || String(value).trim() === '') return null;
  return String(value);
}

// ── Inline cell editor ────────────────────────────────────────────────────────

function CellEdit({ value, field, saving, onSave, onCancel }) {
  const [val, setVal] = useState(value ?? '');
  const ref = useRef(null);

  useEffect(() => {
    ref.current?.focus();
    ref.current?.select();
  }, []);

  function handleKey(e) {
    if (e.key === 'Escape') { e.preventDefault(); onCancel(); }
    if (e.key === 'Enter' && field.type !== 'textarea') { e.preventDefault(); onSave(val); }
  }

  const cls = 'w-full text-sm border border-blue-400 rounded px-1.5 py-0.5 focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white disabled:opacity-60';

  if (field.type === 'textarea') {
    return (
      <textarea
        ref={ref} value={val} rows={3} disabled={saving}
        onChange={(e) => setVal(e.target.value)}
        onBlur={() => onSave(val)}
        onKeyDown={handleKey}
        className={cls}
      />
    );
  }
  return (
    <input
      ref={ref} type="text" value={val} disabled={saving}
      onChange={(e) => setVal(e.target.value)}
      onBlur={() => onSave(val)}
      onKeyDown={handleKey}
      className={cls}
    />
  );
}

// ── Page ──────────────────────────────────────────────────────────────────────

export default function ExperimentDayView() {
  const { id, date } = useParams();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();

  const [experiment, setExperiment] = useState(null);
  const [statuses, setStatuses] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [editStatus, setEditStatus] = useState(null);

  // Inline cell editing
  const [editingCell, setEditingCell] = useState(null); // { statusId, fieldId }
  const [cellSaving, setCellSaving] = useState(false);
  const [cellError, setCellError] = useState(null);

  // Day navigation
  const [dayList, setDayList] = useState([]);

  const selectedField = searchParams.get('field') ?? null;

  useEffect(() => {
    setLoading(true);
    Promise.all([
      experimentsApi.get(id),
      experimentsApi.getDayStatuses(id, date),
    ])
      .then(([exp, s]) => {
        setExperiment(exp);
        setStatuses(s);
      })
      .catch((err) => setError(err.message ?? 'Failed to load'))
      .finally(() => setLoading(false));
  }, [id, date]);

  // Fetch ordered list of days with data for this field, for prev/next nav
  useEffect(() => {
    if (!id || !selectedField) return;
    experimentsApi.getCalendar(id, selectedField)
      .then(({ days }) => setDayList(Object.keys(days).sort()))
      .catch(() => {});
  }, [id, selectedField]);

  const dailyTemplate = useMemo(() => {
    if (!experiment) return [];
    return (experiment.template ?? []).filter((f) => f.active);
  }, [experiment]);

  const animals = useMemo(() => experiment?.animals ?? [], [experiment]);

  const statusByAnimal = useMemo(() => {
    const map = {};
    statuses.forEach((s) => { map[s.animal_id] = s; });
    return map;
  }, [statuses]);

  const rows = useMemo(() => {
    return animals
      .map((animal) => ({ animal, status: statusByAnimal[animal.id] }))
      .filter(({ status }) => {
        if (!status) return false;
        if (!selectedField) return true;
        const isBuiltin = BUILTIN_KEYS_SET.has(selectedField);
        const val = isBuiltin ? status[selectedField] : status.custom_fields?.[selectedField];
        return val !== null && val !== undefined && String(val).trim() !== '';
      });
  }, [animals, statusByAnimal, selectedField]);

  const barData = useMemo(() => {
    return rows
      .map(({ animal, status }) => {
        const summary = status?.analysis_summary;
        if (!summary || summary.total === 0) return null;
        return {
          name: animal.animal_name || animal.animal_id_string || animal.id.slice(0, 8),
          total: summary.total,
          success: summary.counts?.Success ?? 0,
          failure: summary.counts?.Failure ?? 0,
        };
      })
      .filter(Boolean);
  }, [rows]);

  // Prev / next days with data
  const currentDayIdx = dayList.indexOf(date);
  const prevDay = currentDayIdx > 0 ? dayList[currentDayIdx - 1] : null;
  const nextDay = currentDayIdx < dayList.length - 1 ? dayList[currentDayIdx + 1] : null;

  function dayNavUrl(d) {
    return `/experiments/${id}/day/${d}${selectedField ? `?field=${selectedField}` : ''}`;
  }

  // Inline cell save
  async function saveCell(status, field, rawValue) {
    const value = rawValue?.trim() || null;
    // Skip save if unchanged
    const current = getFieldValue(status, field);
    const currentNorm = current == null ? null : String(current).trim() || null;
    if (value === currentNorm) { setEditingCell(null); return; }

    setCellSaving(true);
    setCellError(null);
    try {
      let payload;
      if (field.builtin) {
        payload = { [field.key]: value };
      } else {
        payload = { custom_fields: { ...status.custom_fields, [field.fieldId]: value } };
      }
      const updated = await dailyStatusesApi.update(status.id, payload);
      setStatuses((prev) => prev.map((s) => s.id === updated.id ? updated : s));
      setEditingCell(null);
    } catch (err) {
      setCellError(err.message ?? 'Save failed');
    } finally {
      setCellSaving(false);
    }
  }

  const displayDate = date
    ? format(new Date(date + 'T12:00:00'), 'MMMM d, yyyy')
    : date;

  if (loading) {
    return <div className="max-w-5xl mx-auto px-4 py-10 text-center text-gray-400">Loading…</div>;
  }
  if (error) {
    return (
      <div className="max-w-5xl mx-auto px-4 py-10">
        <Alert type="error" message={error} />
      </div>
    );
  }

  return (
    <div className="max-w-6xl mx-auto px-4 py-6">
      {/* Breadcrumb */}
      <nav className="text-sm text-gray-400 mb-4 flex items-center gap-1.5">
        <Link to="/" className="hover:text-blue-600 transition-colors">Dashboard</Link>
        <span>/</span>
        <Link to={`/experiments/${id}`} className="hover:text-blue-600 transition-colors">
          {experiment?.title ?? id}
        </Link>
        <span>/</span>
        <span className="text-gray-700 font-medium">{displayDate}</span>
      </nav>

      <div className="flex items-center justify-between mb-6">
        <h1 className="text-xl font-bold text-gray-900">{displayDate}</h1>
        <Button variant="secondary" onClick={() => navigate(`/experiments/${id}`)}>
          ← Back to experiment
        </Button>
      </div>

      {cellError && (
        <Alert type="error" message={cellError} onDismiss={() => setCellError(null)} className="mb-4" />
      )}

      {/* Status table */}
      {rows.length === 0 ? (
        <div className="text-center py-16 border-2 border-dashed border-gray-200 rounded-xl text-gray-400">
          No data recorded for this day.
        </div>
      ) : (
        <div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden mb-8">
          <div className="overflow-x-auto">
            <table className="text-sm border-collapse min-w-full">
              <thead>
                <tr className="bg-gray-50 border-b border-gray-200">
                  <th className="text-left px-3 py-2 text-xs font-semibold text-gray-500 uppercase tracking-wide whitespace-nowrap sticky left-0 bg-gray-50 z-10 border-r border-gray-200 min-w-[140px]">
                    Subject
                  </th>
                  {dailyTemplate.map((f) => {
                    const header = f.abbr
                      ? (f.unit ? `${f.abbr} (${f.unit})` : f.abbr)
                      : (f.unit ? `${f.label} (${f.unit})` : f.label);
                    return (
                      <th
                        key={f.fieldId}
                        title={f.unit ? `${f.label} (${f.unit})` : f.label}
                        className="text-left px-3 py-2 text-xs font-semibold text-gray-500 uppercase tracking-wide whitespace-nowrap max-w-[220px]"
                        style={{ minWidth: Math.max(80, header.length * 7.5 + 24) }}
                      >
                        {header}
                      </th>
                    );
                  })}
                  <th className="sticky right-0 bg-gray-50 z-10 border-l border-gray-200 px-3 py-2 min-w-[80px]" />
                </tr>
              </thead>
              <tbody>
                {rows.map(({ animal, status }, i) => {
                  const rowBg = i % 2 === 0 ? 'bg-white' : 'bg-gray-50/40';
                  return (
                    <tr key={animal.id} className={`border-b border-gray-100 last:border-0 ${rowBg}`}>
                      {/* Subject name → daily status detail */}
                      <td
                        className={`px-3 py-2 font-medium whitespace-nowrap sticky left-0 z-10 border-r border-gray-100 ${rowBg} ${
                          status
                            ? 'text-blue-600 cursor-pointer hover:text-blue-800 hover:bg-blue-50/40 transition-colors'
                            : 'text-gray-500'
                        }`}
                        onClick={() => status && navigate(`/daily-statuses/${status.id}`)}
                      >
                        {animal.animal_name ?? animal.animal_id_string ?? animal.id.slice(0, 8)}
                        {animal.animal_id_string && animal.animal_name && (
                          <span className="ml-1.5 text-xs text-gray-400 font-normal">
                            {animal.animal_id_string}
                          </span>
                        )}
                      </td>

                      {/* Field cells — click to edit inline */}
                      {dailyTemplate.map((f) => {
                        const isEditing = editingCell?.statusId === status?.id && editingCell?.fieldId === f.fieldId;
                        const text = status ? cellText(getFieldValue(status, f)) : null;
                        return (
                          <td key={f.fieldId} className="px-3 py-1.5 text-gray-700 max-w-[220px] align-top">
                            {isEditing ? (
                              <CellEdit
                                value={text}
                                field={f}
                                saving={cellSaving}
                                onSave={(val) => saveCell(status, f, val)}
                                onCancel={() => setEditingCell(null)}
                              />
                            ) : (
                              <span
                                className="whitespace-pre-wrap break-words block rounded px-0.5 -mx-0.5 cursor-pointer hover:bg-blue-50 transition-colors"
                                title="Click to edit"
                                onClick={() => status && setEditingCell({ statusId: status.id, fieldId: f.fieldId })}
                              >
                                {text ?? <span className="text-gray-300">—</span>}
                              </span>
                            )}
                          </td>
                        );
                      })}

                      <td className={`px-2 py-1.5 sticky right-0 z-10 border-l border-gray-100 ${rowBg}`}>
                        {status && (
                          <Button size="sm" variant="secondary" onClick={() => setEditStatus(status)}>
                            Edit
                          </Button>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Session metrics bar chart */}
      {barData.length > 0 && (
        <div className="bg-white rounded-xl border border-gray-200 shadow-sm p-5 mb-8">
          <h3 className="text-sm font-semibold text-gray-700 mb-3">Session metrics</h3>
          <ResponsiveContainer width="100%" height={220}>
            <BarChart data={barData} margin={{ top: 4, right: 16, left: 0, bottom: 4 }}>
              <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
              <XAxis dataKey="name" tick={{ fontSize: 11 }} />
              <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />
              <Tooltip />
              <Legend wrapperStyle={{ fontSize: 11 }} />
              <Bar dataKey="total" name="Total" fill="#94a3b8" radius={[3, 3, 0, 0]} />
              <Bar dataKey="success" name="Success" fill="#22c55e" radius={[3, 3, 0, 0]} />
              <Bar dataKey="failure" name="Failure" fill="#f87171" radius={[3, 3, 0, 0]} minPointSize={2} />
            </BarChart>
          </ResponsiveContainer>
        </div>
      )}

      {/* Prev / next day navigation */}
      {(prevDay || nextDay) && (
        <div className="flex justify-between items-center mt-2 mb-4">
          <div>
            {prevDay && (
              <button
                type="button"
                onClick={() => navigate(dayNavUrl(prevDay))}
                className="text-sm text-blue-600 hover:text-blue-800 hover:underline"
              >
                ← {format(new Date(prevDay + 'T12:00:00'), 'MMMM d, yyyy')}
              </button>
            )}
          </div>
          <div>
            {nextDay && (
              <button
                type="button"
                onClick={() => navigate(dayNavUrl(nextDay))}
                className="text-sm text-blue-600 hover:text-blue-800 hover:underline"
              >
                {format(new Date(nextDay + 'T12:00:00'), 'MMMM d, yyyy')} →
              </button>
            )}
          </div>
        </div>
      )}

      {/* Session file drop zone */}
      <FileDropZone rows={rows} date={date} />

      {/* Edit modal (full row) */}
      {editStatus && (
        <Modal
          isOpen={!!editStatus}
          onClose={() => setEditStatus(null)}
          title="Edit daily status"
          size="lg"
        >
          <DailyStatusForm
            existing={editStatus}
            animalId={editStatus.animal_id}
            experimentId={id}
            template={dailyTemplate}
            onSuccess={(updated) => {
              setStatuses((prev) => prev.map((s) => s.id === updated.id ? updated : s));
              setEditStatus(null);
            }}
            onCancel={() => setEditStatus(null)}
          />
        </Modal>
      )}
    </div>
  );
}
