/**
 * CalendarDetail - right column detail panel for the Calendar plugin.
 *
 * Shows entry details (title, type, status, priority, dates, location,
 * description, calendar info), subtask checklist for tasks, linked entities,
 * and action buttons (Edit, Delete).
 * Pattern follows DMS FileDetails.
 */

import React, { useEffect, useState } from 'react';
import clsx from 'clsx';
import { useTranslation } from 'react-i18next';
import {
  createSubtask,
  getEntry,
  updateSubtask,
  type Calendar,
  type CalendarEntry,
  type Subtask,
} from '@/api/calendar';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Calendar as CalendarIcon, Pencil, Trash2, X } from 'lucide-react';

function formatDate(dateStr: string | null | undefined): string {
  if (!dateStr) return '-';
  try {
    const d = new Date(dateStr);
    return d.toLocaleDateString(undefined, {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch {
    return dateStr;
  }
}

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 interface CalendarDetailProps {
  entry: CalendarEntry | null;
  calendar: Calendar | null;
  onEdit: () => void;
  onDelete: () => void;
  onClose: () => void;
  onEntryChanged: (entry: CalendarEntry) => void;
}

export function CalendarDetail({
  entry,
  calendar,
  onEdit,
  onDelete,
  onClose,
  onEntryChanged,
}: CalendarDetailProps) {
  const { t } = useTranslation();
  const [subtasks, setSubtasks] = useState<Subtask[]>(entry?.subtasks ?? []);
  const [loadingSubtasks, setLoadingSubtasks] = useState(false);
  const [newSubtaskTitle, setNewSubtaskTitle] = useState('');
  const [subtaskError, setSubtaskError] = useState<string | null>(null);

  // Load subtasks if entry is a task and subtasks are missing
  useEffect(() => {
    if (!entry) {
      setSubtasks([]);
      return;
    }
    if (entry.entry_type !== 'task') {
      setSubtasks([]);
      return;
    }
    if ((entry.subtasks?.length ?? 0) > 0) {
      setSubtasks(entry.subtasks ?? []);
      return;
    }
    let cancelled = false;
    setLoadingSubtasks(true);
    getEntry(entry.id)
      .then((full) => {
        if (cancelled) return;
        setSubtasks(full.subtasks ?? []);
        onEntryChanged(full);
      })
      .catch((e: Error) => {
        if (!cancelled) setSubtaskError(e.message);
      })
      .finally(() => {
        if (!cancelled) setLoadingSubtasks(false);
      });
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [entry?.id, entry?.entry_type, entry?.subtasks]);

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

  const handleToggleSubtask = async (sub: Subtask) => {
    if (!entry) return;
    setSubtaskError(null);
    const prev = sub.done;
    setSubtasks((cur) => cur.map((s) => (s.id === sub.id ? { ...s, done: !prev } : s)));
    try {
      const updated = await updateSubtask(entry.id, sub.id, { done: !prev });
      setSubtasks((cur) => cur.map((s) => (s.id === sub.id ? updated : s)));
    } catch (e) {
      setSubtasks((cur) => cur.map((s) => (s.id === sub.id ? { ...s, done: prev } : s)));
      setSubtaskError((e as Error).message ?? t('calendar.errorSave'));
    }
  };

  if (!entry) {
    return (
      <div
        className="flex flex-col items-center justify-center h-full p-6 text-center"
        data-testid="calendar-detail-empty"
      >
        <CalendarIcon className="w-12 h-12 text-secondary-300 mb-3" aria-hidden="true" strokeWidth={1.5} />
        <p className="text-sm font-medium text-secondary-600">{t('calendar.detail.noSelection')}</p>
        <p className="mt-1 text-xs text-secondary-400">{t('calendar.detail.noSelectionHint')}</p>
      </div>
    );
  }

  const isTask = entry.entry_type === 'task';

  return (
    <div className="flex flex-col h-full" data-testid="calendar-detail">
      {/* Header with close button */}
      <div className="flex items-center justify-between px-4 py-3 border-b border-secondary-200">
        <h3 className="text-sm font-semibold text-secondary-900 truncate" title={entry.title}>
          {entry.title}
        </h3>
        <button
          onClick={onClose}
          className="p-1 rounded text-secondary-400 hover:text-secondary-600 hover:bg-secondary-100 min-h-touch min-w-touch"
          aria-label={t('common.close')}
          data-testid="calendar-detail-close"
        >
          <X className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
        </button>
      </div>

      {/* Scrollable content */}
      <div className="flex-1 overflow-y-auto p-4">
        {/* Badges */}
        <div className="flex flex-wrap gap-2 mb-4">
          <span
            className={clsx(
              'px-2 py-0.5 rounded text-xs font-medium uppercase',
              isTask ? 'bg-warning-100 text-warning-800' : 'bg-primary-100 text-primary-800',
            )}
          >
            {entry.entry_type}
          </span>
          <span className="px-2 py-0.5 rounded bg-secondary-100 text-secondary-700 text-xs">
            {t(`calendar.status.${entry.status}`)}
          </span>
          <span className={clsx('px-2 py-0.5 rounded text-xs font-medium uppercase', priorityClass(entry.priority))}>
            {entry.priority}
          </span>
        </div>

        {/* Action buttons */}
        <div className="grid grid-cols-2 gap-2 mb-6">
          <button
            onClick={onEdit}
            className="inline-flex items-center justify-center gap-1.5 px-3 py-2 rounded-md text-xs font-medium bg-primary-50 text-primary-700 hover:bg-primary-100 min-h-touch"
            data-testid="calendar-detail-edit"
          >
            <Pencil className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
            {t('calendar.detail.edit')}
          </button>
          <button
            onClick={onDelete}
            className="inline-flex items-center justify-center gap-1.5 px-3 py-2 rounded-md text-xs font-medium bg-danger-50 text-danger-700 hover:bg-danger-100 min-h-touch"
            data-testid="calendar-detail-delete"
          >
            <Trash2 className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
            {t('calendar.detail.delete')}
          </button>
        </div>

        {/* Metadata section */}
        <div className="space-y-3">
          <h4 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide">
            {t('calendar.detail.title')}
          </h4>
          <dl className="space-y-2">
            <div className="flex justify-between text-sm">
              <dt className="text-secondary-500">{t('calendar.detail.type')}</dt>
              <dd className="text-secondary-900 font-medium capitalize">{entry.entry_type}</dd>
            </div>
            <div className="flex justify-between text-sm">
              <dt className="text-secondary-500">{t('calendar.detail.status')}</dt>
              <dd className="text-secondary-900 font-medium">{t(`calendar.status.${entry.status}`)}</dd>
            </div>
            <div className="flex justify-between text-sm">
              <dt className="text-secondary-500">{t('calendar.detail.priority')}</dt>
              <dd className="text-secondary-900 font-medium capitalize">{entry.priority}</dd>
            </div>
            <div className="flex justify-between text-sm">
              <dt className="text-secondary-500">{t('calendar.detail.start')}</dt>
              <dd className="text-secondary-900">{formatDate(entry.start_at)}</dd>
            </div>
            <div className="flex justify-between text-sm">
              <dt className="text-secondary-500">{t('calendar.detail.end')}</dt>
              <dd className="text-secondary-900">{formatDate(entry.end_at)}</dd>
            </div>
            {entry.location && (
              <div className="flex justify-between text-sm">
                <dt className="text-secondary-500">{t('calendar.detail.location')}</dt>
                <dd className="text-secondary-900">{entry.location}</dd>
              </div>
            )}
            {calendar && (
              <div className="flex justify-between text-sm items-center">
                <dt className="text-secondary-500">{t('calendar.detail.calendar')}</dt>
                <dd className="text-secondary-900 font-medium flex items-center gap-1.5">
                  <span
                    className="w-3 h-3 rounded-full flex-shrink-0"
                    style={{ backgroundColor: calendar.color || '#3b82f6' }}
                    aria-hidden="true"
                  />
                  {calendar.name}
                </dd>
              </div>
            )}
          </dl>
        </div>

        {/* Description */}
        {entry.description && (
          <div className="mt-6 space-y-2">
            <h4 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide">
              {t('calendar.detail.description')}
            </h4>
            <p className="text-sm text-secondary-700 whitespace-pre-wrap">{entry.description}</p>
          </div>
        )}

        {/* Subtasks (for tasks) */}
        {isTask && (
          <div className="mt-6 border-t border-secondary-200 pt-4">
            <h4 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide mb-2">
              {t('calendar.detail.subtasks')}
            </h4>

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

            <ul className="space-y-1 mb-3" data-testid="calendar-detail-subtask-list">
              {subtasks.length === 0 && !loadingSubtasks && (
                <li className="text-xs text-secondary-400 italic">
                  {t('calendar.detail.subtasks.empty')}
                </li>
              )}
              {subtasks.map((sub) => (
                <li
                  key={sub.id}
                  className="flex items-start gap-2"
                  data-testid={`calendar-detail-subtask-${sub.id}`}
                >
                  <input
                    type="checkbox"
                    checked={sub.done}
                    onChange={() => handleToggleSubtask(sub)}
                    className="mt-1 h-4 w-4 rounded border-secondary-300 text-primary-600 focus:ring-primary-500"
                    data-testid={`calendar-detail-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 handleAddSubtask();
              }}
              className="flex gap-2"
              data-testid="calendar-detail-subtask-add-form"
            >
              <Input
                value={newSubtaskTitle}
                onChange={(e) => setNewSubtaskTitle(e.target.value)}
                placeholder={t('calendar.detail.subtasks.addPlaceholder')}
                data-testid="calendar-detail-subtask-add-input"
              />
              <Button
                type="submit"
                variant="primary"
                size="sm"
                disabled={!newSubtaskTitle.trim()}
                data-testid="calendar-detail-subtask-add-button"
              >
                {t('calendar.detail.subtasks.add')}
              </Button>
            </form>

            {subtaskError && (
              <div
                className="mt-2 text-xs text-danger-700 bg-danger-50 border border-danger-200 rounded-md p-2"
                data-testid="calendar-detail-subtask-error"
              >
                {subtaskError}
              </div>
            )}
          </div>
        )}

        {/* Linked entities */}
        {entry.links && entry.links.length > 0 && (
          <div className="mt-6 border-t border-secondary-200 pt-4">
            <h4 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide mb-2">
              {t('calendar.detail.links')}
            </h4>
            <ul className="space-y-1">
              {entry.links.map((link) => (
                <li
                  key={link.id}
                  className="flex items-center gap-2 text-sm text-secondary-700"
                >
                  <span className="px-1.5 py-0.5 rounded text-xs bg-secondary-100 text-secondary-600 capitalize">
                    {link.entity_type}
                  </span>
                  <span className="font-mono text-xs">{link.entity_id}</span>
                </li>
              ))}
            </ul>
          </div>
        )}

        {(!entry.links || entry.links.length === 0) && (
          <div className="mt-6 border-t border-secondary-200 pt-4">
            <h4 className="text-xs font-semibold text-secondary-500 uppercase tracking-wide mb-2">
              {t('calendar.detail.links')}
            </h4>
            <p className="text-xs text-secondary-400 italic">{t('calendar.detail.noLinks')}</p>
          </div>
        )}
      </div>
    </div>
  );
}

export default CalendarDetail;
