import { apiGet, apiPost, apiPut, apiDelete } from './client';

export interface ReminderStats {
  readonly totalLists: number;
  readonly totalReminders: number;
  readonly completedCount?: number;
  readonly lastSyncAt?: string;
}

export interface Reminder {
  readonly reminderIdentifier: string;
  readonly calendarIdentifier: string;
  readonly title: string;
  readonly notes: string | null;
  readonly dueDate: string | null;
  readonly priority: number;
  readonly isCompleted: boolean;
}

export interface ReminderInput {
  readonly calendarIdentifier: string;
  readonly title: string;
  readonly notes?: string;
  readonly dueDate?: string;
  readonly priority?: number;
  readonly isCompleted?: boolean;
}

export type ReminderUpdate = Partial<ReminderInput>;

export interface MutationResult {
  readonly sendQueueId: string;
}

interface Envelope<T> {
  readonly success: boolean;
  readonly data: T;
}

function qs(params: Record<string, string | number | boolean | undefined>): string {
  const sp = new URLSearchParams();
  for (const [k, v] of Object.entries(params)) {
    if (v !== undefined && v !== '') sp.set(k, String(v));
  }
  const s = sp.toString();
  return s ? `?${s}` : '';
}

function rethrow(label: string, err: unknown): never {
  if (err instanceof Error) throw err;
  throw new Error(`${label} failed`);
}

export async function fetchReminderStats(): Promise<ReminderStats> {
  try {
    const res = await apiGet<Envelope<ReminderStats>>('/my/reminders/stats');
    return res.data;
  } catch (err) {
    rethrow('fetchReminderStats', err);
  }
}

export interface ReminderFilter {
  readonly calendarId?: string;
  readonly completed?: boolean;
  readonly limit?: number;
}

export async function fetchReminders(filter: ReminderFilter = {}): Promise<Reminder[]> {
  try {
    const res = await apiGet<Envelope<{ reminders: Reminder[] }>>(
      `/my/reminders${qs({ ...filter })}`,
    );
    return res.data.reminders;
  } catch (err) {
    rethrow('fetchReminders', err);
  }
}

export async function createReminder(
  input: ReminderInput,
  deviceId: string,
): Promise<MutationResult> {
  try {
    const res = await apiPost<Envelope<MutationResult>>(
      `/my/reminders${qs({ deviceId })}`,
      input,
    );
    return res.data;
  } catch (err) {
    rethrow('createReminder', err);
  }
}

export async function updateReminder(
  reminderIdentifier: string,
  patch: ReminderUpdate,
  deviceId: string,
): Promise<MutationResult> {
  try {
    const res = await apiPut<Envelope<MutationResult>>(
      `/my/reminders/${encodeURIComponent(reminderIdentifier)}${qs({ deviceId })}`,
      patch,
    );
    return res.data;
  } catch (err) {
    rethrow('updateReminder', err);
  }
}

export async function deleteReminder(
  reminderIdentifier: string,
  deviceId: string,
): Promise<MutationResult> {
  try {
    const res = await apiDelete<Envelope<MutationResult>>(
      `/my/reminders/${encodeURIComponent(reminderIdentifier)}${qs({ deviceId })}`,
    );
    return res.data;
  } catch (err) {
    rethrow('deleteReminder', err);
  }
}
