/**
 * TaskDetailPanel — display a task and manage its subtask checklist.
 *
 * Subtasks are loaded lazily from the entry if absent and updated via the
 * `createSubtask` / `updateSubtask` API endpoints (T05).
 */

import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import clsx from 'clsx';
import {
  createSubtask,
  getEntry,
  updateSubtask,
  type CalendarEntry,
  type Subtask,
} from '@/api/calendar';
import { formatDateShort } from '@/utils/date';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';

export interface TaskDetailPanelProps {
  entry: CalendarEntry;
  onClose: () => void;
  /** Notifies the parent that subtasks (or the entry) changed. */
  onChanged: (entry: CalendarEntry) => void;
}

function priorityClass(p: string): string {
  switch (p) {
    case 'high':
      return 'bg-danger-100 text-danger-800';
    case 'low':
      return 'bg-secondary-100 text-secondary-700';
    default:
      return 'bg-warning-100 text-warning-800';
  }
}

export function TaskDetailPanel({ entry, onClose, onChanged }: TaskDetailPanelProps) {
  const { t } = useTranslation();
  const [subtasks, setSubtasks] = useState<Subtask[]>(entry.subtasks ?? []);
  const [loading, setLoading] = useState(false);
  const [newTitle, setNewTitle] = useState('');
  const [error, setError] = useState<string | null>(null);

  // If parent hands us an entry without subtasks, fetch them
  useEffect(() => {
    let cancelled = false;
    if (entry.entry_type !== 'task') return;
    if ((entry.subtasks?.length ?? 0) > 0) {
      setSubtasks(entry.subtasks ?? []);
      return;
    }
    setLoading(true);
    getEntry(entry.id)
      .then((full) => {
        if (cancelled) return;
        setSubtasks(full.subtasks ?? []);
        onChanged(full);
      })
      .catch((e: Error) => {
        if (!cancelled) setError(e.message);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [entry.id, entry.entry_type, entry.subtasks, onChanged]);

  const handleAdd = async () => {
    const title = newTitle.trim();
    if (!title) return;
    setError(null);
    try {
      const created = await createSubtask(entry.id, { title });
      setSubtasks((cur) => [...cur, created]);
      setNewTitle('');
    } catch (e) {
      setError((e as Error).message ?? t('calendar.errorSave'));
    }
  };

  const handleToggle = async (sub: Subtask) => {
    setError(null);
    // optimistic update
    const previous = sub.done;
    setSubtasks((cur) =>
      cur.map((s) => (s.id === sub.id ? { ...s, done: !previous } : s))
    );
    try {
      const updated = await updateSubtask(entry.id, sub.id, { done: !previous });
      setSubtasks((cur) => cur.map((s) => (s.id === sub.id ? updated : s)));
    } catch (e) {
      // revert
      setSubtasks((cur) =>
        cur.map((s) => (s.id === sub.id ? { ...s, done: previous } : s))
      );
      setError((e as Error).message ?? t('calendar.errorSave'));
    }
  };

  return (
    <aside
      className="fixed inset-y-0 right-0 z-40 w-full sm:w-96 bg-white shadow-xl border-l border-secondary-200 overflow-y-auto"
      data-testid="task-detail-panel"
    >
      <div className="p-4 border-b border-secondary-200 flex items-center justify-between">
        <h2 className="text-lg font-semibold text-secondary-900">{entry.title}</h2>
        <button
          type="button"
          onClick={onClose}
          className="text-secondary-500 hover:text-secondary-900"
          aria-label={t('calendar.cancel')}
          data-testid="task-detail-close"
        >
          ✕
        </button>
      </div>

      <div className="p-4 space-y-4">
        <div className="flex flex-wrap gap-2 text-xs">
          <span className={clsx('px-2 py-0.5 rounded font-medium uppercase', priorityClass(entry.priority))}>
            {entry.priority}
          </span>
          <span className="px-2 py-0.5 rounded bg-secondary-100 text-secondary-700">
            {t(`calendar.status.${entry.status}`)}
          </span>
          {entry.due_date && (
            <span className="px-2 py-0.5 rounded bg-primary-50 text-primary-700">
              {formatDateShort(entry.due_date)}
            </span>
          )}
        </div>

        {entry.description && (
          <p className="text-sm text-secondary-700 whitespace-pre-wrap">
            {entry.description}
          </p>
        )}

        <div className="border-t border-secondary-200 pt-4">
          <h3 className="text-sm font-semibold text-secondary-900 mb-2">
            {t('calendar.subtasks.title')}
          </h3>

          {loading && (
            <div className="text-xs text-secondary-500 mb-2">{t('calendar.loading')}</div>
          )}

          <ul className="space-y-1 mb-3" data-testid="subtask-list">
            {subtasks.length === 0 && !loading && (
              <li className="text-xs text-secondary-400 italic">
                {t('calendar.subtasks.empty')}
              </li>
            )}
            {subtasks.map((sub) => (
              <li
                key={sub.id}
                className="flex items-start gap-2"
                data-testid={`subtask-item-${sub.id}`}
              >
                <input
                  type="checkbox"
                  checked={sub.done}
                  onChange={() => handleToggle(sub)}
                  className="mt-1 h-4 w-4 rounded border-secondary-300 text-primary-600 focus:ring-primary-500"
                  data-testid={`subtask-toggle-${sub.id}`}
                />
                <span
                  className={clsx(
                    'text-sm flex-1',
                    sub.done && 'line-through text-secondary-400'
                  )}
                >
                  {sub.title}
                </span>
              </li>
            ))}
          </ul>

          <form
            onSubmit={(e) => {
              e.preventDefault();
              void handleAdd();
            }}
            className="flex gap-2"
            data-testid="subtask-add-form"
          >
            <Input
              value={newTitle}
              onChange={(e) => setNewTitle(e.target.value)}
              placeholder={t('calendar.subtasks.addPlaceholder')}
              data-testid="subtask-add-input"
            />
            <Button
              type="submit"
              variant="primary"
              size="sm"
              disabled={!newTitle.trim()}
              data-testid="subtask-add-button"
            >
              {t('calendar.subtasks.add')}
            </Button>
          </form>
        </div>

        {error && (
          <div
            className="text-sm text-danger-700 bg-danger-50 border border-danger-200 rounded-md p-2"
            data-testid="task-detail-error"
          >
            {error}
          </div>
        )}
      </div>
    </aside>
  );
}

export default TaskDetailPanel;
