/**
 * CalendarTree - left sidebar calendar selector for the Calendar plugin.
 *
 * Groups calendars by type (personal, team, project, company) with color dots,
 * visibility checkboxes, and a "New Calendar" button at the bottom.
 * Pattern follows DMS SourceTree.
 */

import React, { useState } from 'react';
import clsx from 'clsx';
import { useTranslation } from 'react-i18next';
import type { Calendar, CalendarType } from '@/api/calendar';

const TYPE_ORDER: CalendarType[] = ['personal', 'team', 'project', 'company'];

interface CalendarRowProps {
  calendar: Calendar;
  selected: boolean;
  visible: boolean;
  onSelect: () => void;
  onToggleVisibility: () => void;
}

function CalendarRow({ calendar, selected, visible, onSelect, onToggleVisibility }: CalendarRowProps) {
  return (
    <div
      className={clsx(
        'flex items-center gap-2 px-2 py-1.5 rounded-md text-sm cursor-pointer',
        'hover:bg-secondary-100 motion-safe:transition-colors',
        'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
        selected && 'bg-primary-50 text-primary-700 font-medium',
      )}
      style={{ paddingLeft: '20px' }}
      onClick={onSelect}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          onSelect();
        }
      }}
      tabIndex={0}
      role="button"
      aria-label={calendar.name}
      data-testid={`calendar-tree-row-${calendar.id}`}
    >
      <input
        type="checkbox"
        checked={visible}
        onChange={(e) => {
          e.stopPropagation();
          onToggleVisibility();
        }}
        onClick={(e) => e.stopPropagation()}
        className="flex-shrink-0 h-3.5 w-3.5 rounded border-secondary-300 text-primary-600 focus:ring-primary-500"
        aria-label={`toggle visibility ${calendar.name}`}
        data-testid={`calendar-tree-visibility-${calendar.id}`}
      />
      <span
        className="flex-shrink-0 w-3 h-3 rounded-full"
        style={{ backgroundColor: calendar.color || '#3b82f6' }}
        aria-hidden="true"
      />
      <span className="truncate flex-1">{calendar.name}</span>
    </div>
  );
}

interface TypeSectionProps {
  type: CalendarType;
  calendars: Calendar[];
  activeCalendarId: string | null;
  visibleCalendarIds: Set<string>;
  onSelect: (id: string) => void;
  onToggleVisibility: (id: string) => void;
}

function TypeSection({
  type,
  calendars,
  activeCalendarId,
  visibleCalendarIds,
  onSelect,
  onToggleVisibility,
}: TypeSectionProps) {
  const { t } = useTranslation();
  const [expanded, setExpanded] = useState(true);

  if (calendars.length === 0) return null;

  return (
    <div className="mb-1">
      <div
        className={clsx(
          'flex items-center gap-1 px-2 py-1.5 rounded-md text-sm font-semibold cursor-pointer',
          'hover:bg-secondary-100 motion-safe:transition-colors',
        )}
        onClick={() => setExpanded((p) => !p)}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            setExpanded((p) => !p);
          }
        }}
        tabIndex={0}
        role="button"
        aria-expanded={expanded}
        aria-label={t(`calendar.type.${type}`)}
      >
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation();
            setExpanded((p) => !p);
          }}
          className="flex-shrink-0 w-4 h-4 flex items-center justify-center text-secondary-400 hover:text-secondary-600"
          aria-label={expanded ? 'Collapse' : 'Expand'}
        >
          <svg className="w-3 h-3 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={expanded ? 'M19 9l-7 7-7-7' : 'M9 5l7 7-7 7'} />
          </svg>
        </button>
        <span className="truncate text-secondary-700">{t(`calendar.type.${type}`)}</span>
        <span className="ml-auto text-xs text-secondary-400">{calendars.length}</span>
      </div>
      {expanded && (
        <ul role="group" className="space-y-0 mt-0.5">
          {calendars.map((cal) => (
            <li key={cal.id}>
              <CalendarRow
                calendar={cal}
                selected={activeCalendarId === cal.id}
                visible={
                  visibleCalendarIds.size === 0 || visibleCalendarIds.has(cal.id)
                }
                onSelect={() => onSelect(cal.id)}
                onToggleVisibility={() => onToggleVisibility(cal.id)}
              />
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

export interface CalendarTreeProps {
  calendars: Calendar[];
  activeCalendarId: string | null;
  visibleCalendarIds: Set<string>;
  onSelect: (id: string) => void;
  onToggleVisibility: (id: string) => void;
  onCreate: () => void;
  loading: boolean;
}

export function CalendarTree({
  calendars,
  activeCalendarId,
  visibleCalendarIds,
  onSelect,
  onToggleVisibility,
  onCreate,
  loading,
}: CalendarTreeProps) {
  const { t } = useTranslation();

  if (loading) {
    return (
      <div className="space-y-2 p-2" data-testid="calendar-tree-loading">
        {[1, 2, 3].map((i) => (
          <div key={i} className="h-8 bg-secondary-100 rounded animate-pulse" />
        ))}
      </div>
    );
  }

  const grouped = new Map<CalendarType, Calendar[]>();
  for (const type of TYPE_ORDER) {
    grouped.set(type, []);
  }
  for (const cal of calendars) {
    const list = grouped.get(cal.type) ?? grouped.get('personal')!;
    list.push(cal);
  }

  return (
    <nav aria-label={t('calendar.tree.title')} data-testid="calendar-tree" className="flex flex-col h-full">
      <div className="px-3 py-2 border-b border-secondary-200">
        <h2 className="text-sm font-semibold text-secondary-900">{t('calendar.tree.title')}</h2>
      </div>

      <div className="flex-1 overflow-y-auto p-2">       {calendars.length === 0 ? (
          <p className="text-xs text-secondary-400 italic px-2 py-4 text-center">
            {t('calendar.noCalendars')}
          </p>
        ) : (
          TYPE_ORDER.map((type) => (
            <TypeSection
              key={type}
              type={type}
              calendars={grouped.get(type) ?? []}
              activeCalendarId={activeCalendarId}
              visibleCalendarIds={visibleCalendarIds}
              onSelect={onSelect}
              onToggleVisibility={onToggleVisibility}
            />
          ))
        )}
      </div>

      <div className="p-2 border-t border-secondary-200">
        <button
          type="button"
          onClick={onCreate}
          className={clsx(
            'w-full inline-flex items-center justify-center gap-1.5 px-3 py-2 rounded-md text-sm font-medium',
            'bg-primary-50 text-primary-700 hover:bg-primary-100 min-h-touch',
          )}
          data-testid="calendar-tree-new"
        >
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
          </svg>
          {t('calendar.tree.newCalendar')}
        </button>
      </div>
    </nav>
  );
}

export default CalendarTree;
