/**
 * Calendar Kanban page — three task columns with drag & drop status updates.
 */

import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { KanbanBoard, type KanbanStatus } from '@/components/calendar/KanbanBoard';
import { TaskDetailPanel } from '@/components/calendar/TaskDetailPanel';
import {
  fetchKanbanBoard,
  updateEntry,
  type CalendarEntry,
  type KanbanBoard as KanbanBoardData,
} from '@/api/calendar';

const EMPTY_BOARD: KanbanBoardData = {
  open: [],
  in_progress: [],
  done: [],
  cancelled: [],
};

export function CalendarKanbanPage() {
  const { t } = useTranslation();
  const [board, setBoard] = useState<KanbanBoardData>(EMPTY_BOARD);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedTask, setSelectedTask] = useState<CalendarEntry | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await fetchKanbanBoard();
      setBoard(data);
    } catch (e) {
      setError((e as Error).message ?? t('calendar.errorLoad'));
    } finally {
      setLoading(false);
    }
  }, [t]);

  useEffect(() => {
    void load();
  }, [load]);

  const handleMove = async (entry: CalendarEntry, target: KanbanStatus) => {
    // Optimistic update
    const previous = board;
    const next: KanbanBoardData = {
      open: board.open.filter((e) => e.id !== entry.id),
      in_progress: board.in_progress.filter((e) => e.id !== entry.id),
      done: board.done.filter((e) => e.id !== entry.id),
      cancelled: board.cancelled.filter((e) => e.id !== entry.id),
    };
    next[target] = [...next[target], { ...entry, status: target }];
    setBoard(next);
    try {
      const updated = await updateEntry(entry.id, { status: target });
      setBoard((cur) => {
        const list = cur[target].map((e) => (e.id === updated.id ? updated : e));
        return { ...cur, [target]: list };
      });
    } catch (e) {
      setError((e as Error).message ?? t('calendar.errorSave'));
      setBoard(previous);
    }
  };

  const handleTaskChanged = (updated: CalendarEntry) => {
    setSelectedTask(updated);
    setBoard((cur) => {
      const mapStatus = (s: string): KanbanStatus =>
        s === 'open' || s === 'in_progress' || s === 'done' || s === 'cancelled'
          ? s
          : 'open';
      const target = mapStatus(updated.status);
      const strip = (col: CalendarEntry[]) => col.filter((e) => e.id !== updated.id);
      return {
        open: target === 'open' ? [...strip(cur.open), updated] : strip(cur.open),
        in_progress:
          target === 'in_progress' ? [...strip(cur.in_progress), updated] : strip(cur.in_progress),
        done: target === 'done' ? [...strip(cur.done), updated] : strip(cur.done),
        cancelled:
          target === 'cancelled' ? [...strip(cur.cancelled), updated] : strip(cur.cancelled),
      };
    });
  };

  return (
    <div className="p-6 max-w-7xl mx-auto" data-testid="kanban-page">
      <h1 className="text-2xl font-bold text-secondary-900 mb-4">
        {t('calendar.kanbanTitle')}
      </h1>

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

      <KanbanBoard
        board={board}
        loading={loading}
        onMove={handleMove}
        onSelect={(entry) => setSelectedTask(entry)}
      />

      {selectedTask && (
        <TaskDetailPanel
          entry={selectedTask}
          onClose={() => setSelectedTask(null)}
          onChanged={handleTaskChanged}
        />
      )}
    </div>
  );
}

export default CalendarKanbanPage;
