// events 도메인 helper (PR-2 UI MVP).
// type 정의 + 표시용 라벨 + lifecycle 호출 wrapper.

import { api } from '$lib/api';

export type EventKind = 'task' | 'calendar_event' | 'activity_log';
export type EventStatus =
  | 'inbox'
  | 'next'
  | 'scheduled'
  | 'in_progress'
  | 'done'
  | 'cancelled'
  | 'deferred';
export type EventSource =
  | 'manual'
  | 'memo'
  | 'email'
  | 'chat'
  | 'webhook'
  | 'git_commit'
  | 'claude_code';
export type EventActor = 'manual' | 'eid' | 'email_ingest' | 'system';

export interface EventItem {
  id: number;
  title: string;
  description: string | null;
  kind: EventKind;
  status: EventStatus;
  due_at: string | null;
  start_at: string | null;
  end_at: string | null;
  started_at: string | null;
  ended_at: string | null;
  all_day: boolean;
  timezone: string | null;
  defer_until: string | null;
  completed_at: string | null;
  cancelled_at: string | null;
  priority: number | null;
  project_tag: string | null;
  tags: unknown[];
  source: EventSource;
  source_ref: string | null;
  raw_metadata: Record<string, unknown>;
  memo_document_id: number | null;
  user_id: number;
  created_by: EventActor;
  created_at: string;
  updated_at: string;
}

export interface EventListResponse {
  items: EventItem[];
  total: number;
}

export const KIND_LABEL: Record<EventKind, string> = {
  task: '할 일',
  calendar_event: '일정',
  activity_log: '기록',
};

export const STATUS_LABEL: Record<EventStatus, string> = {
  inbox: 'Inbox',
  next: '다음',
  scheduled: '예정',
  in_progress: '진행 중',
  done: '완료',
  cancelled: '취소',
  deferred: '연기',
};

export const STATUS_COLOR: Record<EventStatus, string> = {
  inbox: 'bg-slate-100 text-slate-700',
  next: 'bg-indigo-100 text-indigo-700',
  scheduled: 'bg-blue-100 text-blue-700',
  in_progress: 'bg-amber-100 text-amber-700',
  done: 'bg-emerald-100 text-emerald-700',
  cancelled: 'bg-rose-100 text-rose-700',
  deferred: 'bg-slate-100 text-slate-500',
};

export const KIND_COLOR: Record<EventKind, string> = {
  task: 'border-l-4 border-indigo-400',
  calendar_event: 'border-l-4 border-blue-400',
  activity_log: 'border-l-4 border-emerald-400',
};

// ─── API wrappers ───

export interface EventCreatePayload {
  title: string;
  description?: string | null;
  kind: EventKind;
  status?: EventStatus | null;
  due_at?: string | null;
  start_at?: string | null;
  end_at?: string | null;
  started_at?: string | null;
  ended_at?: string | null;
  all_day?: boolean;
  timezone?: string | null;
  priority?: number | null;
  project_tag?: string | null;
  tags?: unknown[];
  memo_document_id?: number | null;
  source?: EventSource;
  source_ref?: string | null;
  raw_metadata?: Record<string, unknown>;
}

export async function createEvent(payload: EventCreatePayload): Promise<EventItem> {
  return api<EventItem>('/events/', {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

// 빠른 행동 기록 (5초 UX 핵심) — title 1개만 받고 서버 default 활용.
export async function logActivity(title: string, projectTag?: string | null): Promise<EventItem> {
  const payload: EventCreatePayload = {
    title,
    kind: 'activity_log',
  };
  if (projectTag) payload.project_tag = projectTag;
  return createEvent(payload);
}

export interface EventPatchPayload {
  title?: string;
  description?: string | null;
  due_at?: string | null;
  start_at?: string | null;
  end_at?: string | null;
  started_at?: string | null;
  ended_at?: string | null;
  all_day?: boolean;
  timezone?: string | null;
  priority?: number | null;
  project_tag?: string | null;
  tags?: unknown[];
  memo_document_id?: number | null;
}

export async function patchEvent(id: number, payload: EventPatchPayload): Promise<EventItem> {
  return api<EventItem>(`/events/${id}`, {
    method: 'PATCH',
    body: JSON.stringify(payload),
  });
}

export async function getEvent(id: number): Promise<EventItem> {
  return api<EventItem>(`/events/${id}`);
}

export async function listToday(timezone = 'Asia/Seoul'): Promise<EventListResponse> {
  return api<EventListResponse>(`/events/today?timezone=${encodeURIComponent(timezone)}`);
}

export async function listInbox(): Promise<EventListResponse> {
  return api<EventListResponse>('/events/inbox');
}

export async function listActivity(fromIso?: string, toIso?: string): Promise<EventListResponse> {
  const params = new URLSearchParams();
  if (fromIso) params.set('from', fromIso);
  if (toIso) params.set('to', toIso);
  const qs = params.toString();
  return api<EventListResponse>(`/events/activity${qs ? '?' + qs : ''}`);
}

export async function listUpcoming(days = 7): Promise<EventListResponse> {
  const now = new Date();
  const to = new Date(now.getTime() + days * 86400_000);
  const params = new URLSearchParams({
    from: now.toISOString(),
    to: to.toISOString(),
    status: 'scheduled,next,deferred',
  });
  return api<EventListResponse>(`/events/?${params.toString()}`);
}

// Lifecycle endpoints

export async function completeEvent(id: number): Promise<EventItem> {
  return api<EventItem>(`/events/${id}/complete`, { method: 'POST' });
}

export async function cancelEvent(id: number): Promise<EventItem> {
  return api<EventItem>(`/events/${id}/cancel`, { method: 'POST' });
}

export async function deferEvent(id: number, deferUntilIso: string): Promise<EventItem> {
  return api<EventItem>(`/events/${id}/defer`, {
    method: 'POST',
    body: JSON.stringify({ defer_until: deferUntilIso }),
  });
}

export async function reactivateEvent(id: number): Promise<EventItem> {
  return api<EventItem>(`/events/${id}/reactivate`, { method: 'POST' });
}

// 표시 유틸

export function formatDateTimeKst(iso: string | null | undefined, opts?: { dateOnly?: boolean }): string {
  if (!iso) return '—';
  const d = new Date(iso);
  if (isNaN(d.getTime())) return '—';
  if (opts?.dateOnly) {
    return d.toLocaleDateString('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', weekday: 'short' });
  }
  return d.toLocaleString('ko-KR', {
    timeZone: 'Asia/Seoul',
    month: 'numeric',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

export function relativeTimeKo(iso: string | null | undefined, nowMs: number = Date.now()): string {
  if (!iso) return '';
  const t = new Date(iso).getTime();
  if (isNaN(t)) return '';
  const diff = nowMs - t;
  const abs = Math.abs(diff);
  const future = diff < 0;
  if (abs < 60_000) return future ? '곧' : '방금';
  const min = Math.round(abs / 60_000);
  if (min < 60) return future ? `${min}분 후` : `${min}분 전`;
  const hr = Math.round(min / 60);
  if (hr < 24) return future ? `${hr}시간 후` : `${hr}시간 전`;
  const day = Math.round(hr / 24);
  if (day < 30) return future ? `${day}일 후` : `${day}일 전`;
  const mo = Math.round(day / 30);
  if (mo < 12) return future ? `${mo}달 후` : `${mo}달 전`;
  const yr = Math.round(mo / 12);
  return future ? `${yr}년 후` : `${yr}년 전`;
}
