// ---------------------------------------------------------------------------
// Residences 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 CreateResidenceRequest {
  name: string;
  property_type_id?: number;
  street_address?: string;
  apartment_unit?: string;
  city?: string;
  state_province?: string;
  postal_code?: string;
  country?: string;
  bedrooms?: number;
  bathrooms?: number;
  square_footage?: number;
  lot_size?: number;
  year_built?: number;
  description?: string;
  purchase_date?: string;
  purchase_price?: number;
  is_primary?: boolean;
}

export interface UpdateResidenceRequest {
  name?: string;
  property_type_id?: number;
  street_address?: string;
  apartment_unit?: string;
  city?: string;
  state_province?: string;
  postal_code?: string;
  country?: string;
  bedrooms?: number;
  bathrooms?: number;
  square_footage?: number;
  lot_size?: number;
  year_built?: number;
  description?: string;
  purchase_date?: string;
  purchase_price?: number;
  is_primary?: boolean;
}

export interface ResidenceResponse {
  id: number;
  name: string;
  property_type_id?: number;
  property_type?: ResidenceTypeResponse;
  street_address: string;
  apartment_unit: string;
  city: string;
  state_province: string;
  postal_code: string;
  country: string;
  bedrooms?: number;
  bathrooms?: number;
  square_footage?: number;
  lot_size?: number;
  year_built?: number;
  description: string;
  purchase_date?: string;
  purchase_price?: number;
  is_primary: boolean;
  is_owner: boolean;
  owner_id: number;
  user_count: number;
  overdue_count?: number;
  created_at: string;
  updated_at: string;
}

export interface ResidenceTypeResponse {
  id: number;
  name: string;
  icon: string;
}

export interface MyResidenceResponse {
  residence: ResidenceResponse;
  task_summary: TaskSummary;
}

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

export interface ResidenceSummaryResponse {
  total_residences: number;
  total_summary: TaskSummary;
  residences: MyResidenceResponse[];
}

export interface ResidenceUserResponse {
  id: number;
  username: string;
  email: string;
  first_name: string;
  last_name: string;
  is_owner: boolean;
}

export interface ShareCodeResponse {
  code: string;
  residence_id: number;
  expires_at: string;
  created_at: string;
}

export interface SharePackageResponse {
  code: string;
  residence_id: number;
  residence_name: string;
  owner_name: string;
  expires_at: string;
}

export interface GenerateShareCodeRequest {
  expires_in_hours?: number;
}

export interface JoinWithCodeRequest {
  code: string;
}

export interface TasksReportResponse {
  message: string;
  residence_name: string;
  recipient_email: string;
  pdf_generated: boolean;
  email_sent: boolean;
  report: Record<string, unknown>;
}

export interface MessageResponse {
  message: string;
}

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

/** List all residences the current user has access to. */
export function listResidences(): Promise<ResidenceResponse[]> {
  return apiFetch<ResidenceResponse[]>('/residences/');
}

/** Get the user's residences with task summaries. */
export async function getMyResidences(): Promise<MyResidenceResponse[]> {
  // Go API returns { "residences": [ResidenceResponse, ...] }
  // Each ResidenceResponse has overdue_count but no full task_summary.
  // We fetch the kanban data in parallel and compute real per-residence counts.
  const [resData, kanbanData] = await Promise.all([
    apiFetch<{ residences: ResidenceResponse[] }>('/residences/my-residences/'),
    apiFetch<{ columns: { name: string; tasks: { residence_id: number }[] }[] }>('/tasks/').catch(() => null),
  ]);

  const residences = resData.residences ?? [];

  // Build per-residence task counts from kanban columns
  const countsMap = new Map<number, TaskSummary>();
  if (kanbanData?.columns) {
    for (const col of kanbanData.columns) {
      for (const task of col.tasks) {
        let c = countsMap.get(task.residence_id);
        if (!c) {
          c = { total: 0, overdue: 0, due_soon: 0, in_progress: 0, completed: 0 };
          countsMap.set(task.residence_id, c);
        }
        c.total++;
        if (col.name === 'overdue_tasks') c.overdue++;
        else if (col.name === 'due_soon_tasks') c.due_soon++;
        else if (col.name === 'in_progress_tasks') c.in_progress++;
        else if (col.name === 'completed_tasks') c.completed++;
      }
    }
  }

  return residences.map((r) => ({
    residence: r,
    task_summary: countsMap.get(r.id) ?? {
      total: 0,
      overdue: r.overdue_count ?? 0,
      due_soon: 0,
      in_progress: 0,
      completed: 0,
    },
  }));
}

/** Get aggregated task summary across all residences. */
export function getSummary(): Promise<ResidenceSummaryResponse> {
  return apiFetch<ResidenceSummaryResponse>('/residences/summary/');
}

/** Get a single residence by ID. */
export function getResidence(id: number): Promise<ResidenceResponse> {
  return apiFetch<ResidenceResponse>(`/residences/${id}/`);
}

/** Create a new residence. */
export function createResidence(
  data: CreateResidenceRequest,
): Promise<ResidenceResponse> {
  return apiFetch<ResidenceResponse>('/residences/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

/** Update an existing residence. */
export function updateResidence(
  id: number,
  data: UpdateResidenceRequest,
): Promise<ResidenceResponse> {
  return apiFetch<ResidenceResponse>(`/residences/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data),
  });
}

/** Delete a residence. Only the owner can delete. */
export function deleteResidence(
  id: number,
): Promise<MessageResponse> {
  return apiFetch<MessageResponse>(`/residences/${id}/`, {
    method: 'DELETE',
  });
}

/** Get the active share code for a residence. */
export function getShareCode(
  residenceId: number,
): Promise<{ share_code: ShareCodeResponse | null }> {
  return apiFetch<{ share_code: ShareCodeResponse | null }>(
    `/residences/${residenceId}/share-code/`,
  );
}

/** Generate a new share code for a residence. */
export function generateShareCode(
  residenceId: number,
  data?: GenerateShareCodeRequest,
): Promise<ShareCodeResponse> {
  return apiFetch<ShareCodeResponse>(
    `/residences/${residenceId}/generate-share-code/`,
    {
      method: 'POST',
      body: JSON.stringify(data ?? {}),
    },
  );
}

/** Generate a share package (code + residence metadata). */
export function generateSharePackage(
  residenceId: number,
  data?: GenerateShareCodeRequest,
): Promise<SharePackageResponse> {
  return apiFetch<SharePackageResponse>(
    `/residences/${residenceId}/generate-share-package/`,
    {
      method: 'POST',
      body: JSON.stringify(data ?? {}),
    },
  );
}

/** Join a residence using a 6-character share code. */
export function joinWithCode(
  data: JoinWithCodeRequest,
): Promise<ResidenceResponse> {
  return apiFetch<ResidenceResponse>('/residences/join-with-code/', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

/** List users of a residence. */
export function getResidenceUsers(
  residenceId: number,
): Promise<ResidenceUserResponse[]> {
  return apiFetch<ResidenceUserResponse[]>(
    `/residences/${residenceId}/users/`,
  );
}

/** Remove a user from a residence. Only the owner can remove users. */
export function removeResidenceUser(
  residenceId: number,
  userId: number,
): Promise<MessageResponse> {
  return apiFetch<MessageResponse>(
    `/residences/${residenceId}/users/${userId}/`,
    { method: 'DELETE' },
  );
}

/** Generate and email a tasks report PDF for a residence. */
export function generateTasksReport(
  residenceId: number,
  email?: string,
): Promise<TasksReportResponse> {
  return apiFetch<TasksReportResponse>(
    `/residences/${residenceId}/generate-tasks-report/`,
    {
      method: 'POST',
      body: JSON.stringify(email ? { email } : {}),
    },
  );
}
