// ---------------------------------------------------------------------------
// Tasks API client  (client-side)
// ---------------------------------------------------------------------------

import { apiFetch } from './client';

// ---------------------------------------------------------------------------
// Request / response shapes
// TODO: import from @/lib/types once the shared types package is finalised
// ---------------------------------------------------------------------------

export interface CreateTaskRequest {
  residence_id: number;
  title: string;
  description?: string;
  category_id?: number;
  priority_id?: number;
  frequency_id?: number;
  custom_interval_days?: number;
  in_progress?: boolean;
  assigned_to_id?: number;
  due_date?: string;
  estimated_cost?: number;
  contractor_id?: number;
}

export interface UpdateTaskRequest {
  title?: string;
  description?: string;
  category_id?: number;
  priority_id?: number;
  frequency_id?: number;
  custom_interval_days?: number;
  in_progress?: boolean;
  assigned_to_id?: number;
  due_date?: string;
  estimated_cost?: number;
  actual_cost?: number;
  contractor_id?: number;
}

export interface TaskResponse {
  id: number;
  residence_id: number;
  residence_name: string;
  title: string;
  description: string;
  category_id?: number;
  category?: LookupResponse;
  priority_id?: number;
  priority?: LookupResponse;
  frequency_id?: number;
  frequency?: LookupResponse;
  custom_interval_days?: number;
  in_progress: boolean;
  is_cancelled: boolean;
  is_archived: boolean;
  assigned_to_id?: number;
  assigned_to?: TaskUserResponse;
  due_date?: string;
  next_due_date?: string;
  estimated_cost?: number;
  actual_cost?: number;
  contractor_id?: number;
  contractor?: TaskContractorResponse;
  completion_count: number;
  last_completed_at?: string;
  created_by_id: number;
  created_at: string;
  updated_at: string;
}

export interface LookupResponse {
  id: number;
  name: string;
  icon?: string;
  color?: string;
}

export interface TaskUserResponse {
  id: number;
  username: string;
  first_name: string;
  last_name: string;
}

export interface TaskContractorResponse {
  id: number;
  name: string;
  company: string;
}

/** Kanban board response returned by ListTasks and GetTasksByResidence. */
export interface KanbanResponse {
  columns: KanbanColumn[];
  total_summary: TaskTotalSummary;
}

export interface KanbanColumn {
  name: string;
  display_name: string;
  count: number;
  tasks: TaskResponse[];
}

export interface TaskTotalSummary {
  total: number;
  overdue: number;
  due_soon: number;
  in_progress: number;
  completed: number;
  upcoming: number;
}

// --- Task Completions ---

export interface CreateCompletionRequest {
  task_id: number;
  completed_at?: string;
  notes?: string;
  actual_cost?: number;
  rating?: number;
  image_urls?: string[];
}

export interface UpdateCompletionRequest {
  notes?: string;
  actual_cost?: number;
  rating?: number;
  image_urls?: string[];
}

export interface CompletionResponse {
  id: number;
  task_id: number;
  task_title: string;
  completed_at: string;
  completed_by_id: number;
  completed_by?: TaskUserResponse;
  notes: string;
  actual_cost?: number;
  rating?: number;
  images: CompletionImageResponse[];
  created_at: string;
}

export interface CompletionImageResponse {
  id: number;
  image_url: string;
  caption: string;
}

export interface MessageResponse {
  message: string;
}

// ---------------------------------------------------------------------------
// API functions
// ---------------------------------------------------------------------------

/**
 * List all tasks for the current user (kanban board).
 * @param days  Number of days for "due soon" threshold (default 30)
 */
export function listTasks(days?: number): Promise<KanbanResponse> {
  const params = days != null ? `?days=${days}` : '';
  return apiFetch<KanbanResponse>(`/tasks/${params}`);
}

/** Get tasks for a specific residence (kanban board). */
export function getTasksByResidence(
  residenceId: number,
  days?: number,
): Promise<KanbanResponse> {
  const params = days != null ? `?days=${days}` : '';
  return apiFetch<KanbanResponse>(
    `/tasks/by-residence/${residenceId}/${params}`,
  );
}

/** Get a single task by ID. */
export function getTask(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/`);
}

/** Create a new task. */
export function createTask(data: CreateTaskRequest): Promise<TaskResponse> {
  return apiFetch<TaskResponse>('/tasks/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

/** Update an existing task. */
export function updateTask(
  id: number,
  data: UpdateTaskRequest,
): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

/** Delete a task. */
export function deleteTask(id: number): Promise<MessageResponse> {
  return apiFetch<MessageResponse>(`/tasks/${id}/`, {
    method: 'DELETE',
  });
}

/** Mark a task as in-progress. */
export function markInProgress(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/mark-in-progress/`, {
    method: 'POST',
  });
}

/** Cancel a task. */
export function cancelTask(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/cancel/`, {
    method: 'POST',
  });
}

/** Un-cancel a previously cancelled task. */
export function uncancelTask(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/uncancel/`, {
    method: 'POST',
  });
}

/** Archive a task. */
export function archiveTask(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/archive/`, {
    method: 'POST',
  });
}

/** Un-archive a previously archived task. */
export function unarchiveTask(id: number): Promise<TaskResponse> {
  return apiFetch<TaskResponse>(`/tasks/${id}/unarchive/`, {
    method: 'POST',
  });
}

/** Quick-complete a task (lightweight, for widgets). Returns void (204). */
export function quickComplete(id: number): Promise<void> {
  return apiFetch<void>(`/tasks/${id}/quick-complete/`, {
    method: 'POST',
  });
}

// --- Task Completions ---

/** Get completions for a specific task. */
export function getTaskCompletions(
  taskId: number,
): Promise<CompletionResponse[]> {
  return apiFetch<CompletionResponse[]>(`/tasks/${taskId}/completions/`);
}

/** List all completions for the current user. */
export function listCompletions(): Promise<CompletionResponse[]> {
  return apiFetch<CompletionResponse[]>('/task-completions/');
}

/** Get a single completion by ID. */
export function getCompletion(id: number): Promise<CompletionResponse> {
  return apiFetch<CompletionResponse>(`/task-completions/${id}/`);
}

/** Create a new task completion (JSON). */
export function createCompletion(
  data: CreateCompletionRequest,
): Promise<CompletionResponse> {
  return apiFetch<CompletionResponse>('/task-completions/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

/**
 * Create a task completion with image upload (multipart/form-data).
 * Use this when the user attaches photos to the completion.
 */
export function createCompletionWithImages(
  data: {
    task_id: number;
    notes?: string;
    actual_cost?: number;
    completed_at?: string;
  },
  images: File[],
): Promise<CompletionResponse> {
  const formData = new FormData();
  formData.append('task_id', String(data.task_id));
  if (data.notes) formData.append('notes', data.notes);
  if (data.actual_cost != null)
    formData.append('actual_cost', String(data.actual_cost));
  if (data.completed_at) formData.append('completed_at', data.completed_at);
  for (const image of images) {
    formData.append('images', image);
  }

  return apiFetch<CompletionResponse>('/task-completions/', {
    method: 'POST',
    body: formData,
  });
}

/** Update an existing completion. */
export function updateCompletion(
  id: number,
  data: UpdateCompletionRequest,
): Promise<CompletionResponse> {
  return apiFetch<CompletionResponse>(`/task-completions/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

/** Delete a completion. */
export function deleteCompletion(id: number): Promise<MessageResponse> {
  return apiFetch<MessageResponse>(`/task-completions/${id}/`, {
    method: 'DELETE',
  });
}
