import {
  Admin,
  Agent,
  AgentLedger,
  AgentListItem,
  AppSettings,
  AreaUnit,
  BhusaBuyer,
  BugReport,
  Customer,
  CustomerLedger,
  DashboardSummary,
  Expense,
  ExpenseCategory,
  ExpenseType,
  FuelPump,
  FuelPumpLedger,
  FuelPumpListItem,
  Harvester,
  HarvesterStatus,
  HarvesterType,
  HarvestType,
  Labour,
  LabourLedger,
  LabourListItem,
  LabourType,
  Payment,
  PartyType,
  PaymentStatus,
  Plot,
  WageType,
} from '@wh/shared';
import { api } from './client';

export interface Paginated<T> {
  items: T[];
  total: number;
  page: number;
  limit: number;
  pages: number;
}

// ---------- Auth ----------
export interface LoginResult {
  accessToken: string;
  admin: Admin;
}
export const authApi = {
  /** identifier may be an email address or a 10-digit mobile number. */
  login: (identifier: string, password: string) =>
    api.post<LoginResult>('/auth/login', { identifier, password }).then((r) => r.data),
  me: () => api.get<Admin>('/auth/me').then((r) => r.data),
  /** Update your own profile: name and/or password (verifies the current one). */
  updateProfile: (input: { name?: string; currentPassword?: string; newPassword?: string }) =>
    api.patch<Admin>('/auth/profile', input).then((r) => r.data),
};

// ---------- Account requests (public self-service owner signup) ----------
export interface AccountRequestInput {
  fullName: string;
  email: string;
  mobile: string;
  harvesterCount: number;
  state: string;
  district: string;
  password: string;
}
export const accountRequestsApi = {
  create: (body: AccountRequestInput) =>
    api.post<{ id: string; status: string }>('/account-requests', body).then((r) => r.data),
};

// ---------- Admins (OWNER only) ----------
export interface CreateAdminInput {
  name: string;
  /** Optional — staff admins can sign in by mobile instead. */
  email?: string;
  password: string;
  phone: string;
  harvesterIds?: string[];
}
export interface UpdateAdminInput {
  name?: string;
  email?: string;
  phone?: string;
  isActive?: boolean;
  harvesterIds?: string[];
}
export const adminsApi = {
  list: () => api.get<Admin[]>('/admins').then((r) => r.data),
  get: (id: string) => api.get<Admin>(`/admins/${id}`).then((r) => r.data),
  create: (body: CreateAdminInput) => api.post<Admin>('/admins', body).then((r) => r.data),
  update: (id: string, body: UpdateAdminInput) =>
    api.patch<Admin>(`/admins/${id}`, body).then((r) => r.data),
  changePassword: (id: string, newPassword: string) =>
    api.patch(`/admins/${id}/password`, { newPassword }).then(() => undefined),
};

// ---------- Harvesters ----------
export interface HarvesterInput {
  name: string;
  registrationNo?: string;
  type: HarvesterType;
  ratePerUnit?: number;
  rateWithBhusa?: number;
  rateWithoutBhusa?: number;
}
export const harvestersApi = {
  list: (status?: HarvesterStatus) =>
    api.get<Harvester[]>('/harvesters', { params: { status } }).then((r) => r.data),
  create: (body: HarvesterInput) => api.post<Harvester>('/harvesters', body).then((r) => r.data),
  update: (id: string, body: Partial<HarvesterInput>) =>
    api.patch<Harvester>(`/harvesters/${id}`, body).then((r) => r.data),
  activate: (id: string) => api.patch<Harvester>(`/harvesters/${id}/activate`).then((r) => r.data),
  deactivate: (id: string) =>
    api.patch<Harvester>(`/harvesters/${id}/deactivate`).then((r) => r.data),
};

// ---------- Customers ----------
export interface CustomerInput {
  name: string;
  phone: string;
  village?: string;
  address?: string;
  deviceContactId?: string;
}
export interface CustomerListItem extends Customer {
  totalBill: number;
  amountPaid: number;
  outstanding: number;
}
export const customersApi = {
  list: (params?: { page?: number; limit?: number; search?: string }) =>
    api.get<Paginated<CustomerListItem>>('/customers', { params }).then((r) => r.data),
  get: (id: string) => api.get<Customer>(`/customers/${id}`).then((r) => r.data),
  create: (body: CustomerInput) => api.post<Customer>('/customers', body).then((r) => r.data),
  update: (id: string, body: Partial<CustomerInput>) =>
    api.patch<Customer>(`/customers/${id}`, body).then((r) => r.data),
  ledger: (id: string) => api.get<CustomerLedger>(`/customers/${id}/ledger`).then((r) => r.data),
};

// ---------- Settings ----------
export interface SettingsInput {
  currency?: string;
  defaultAreaUnit?: AreaUnit;
  firmName?: string;
}
export const settingsApi = {
  get: () => api.get<AppSettings>('/settings').then((r) => r.data),
  update: (body: SettingsInput) => api.patch<AppSettings>('/settings', body).then((r) => r.data),
};

// ---------- Expenses ----------
export interface ExpenseInput {
  harvesterId: string;
  type: ExpenseType;
  /** A custom category id, or null for a built-in type. */
  categoryId?: string | null;
  /** The fuel pump a DIESEL expense was bought from, or null. */
  pumpId?: string | null;
  amount: number;
  date?: string;
  notes?: string;
  attachmentUrl?: string;
  /** Required when type is LABOUR — the labourer being paid. */
  labourId?: string;
}
export const expensesApi = {
  list: (params?: { harvesterId?: string; type?: ExpenseType; from?: string; to?: string }) =>
    api.get<Expense[]>('/expenses', { params }).then((r) => r.data),
  create: (body: ExpenseInput) => api.post<Expense>('/expenses', body).then((r) => r.data),
  update: (id: string, body: Partial<ExpenseInput>) =>
    api.patch<Expense>(`/expenses/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/expenses/${id}`).then(() => undefined),
};

// ---------- Expense categories (custom; OWNER manages) ----------
export interface ExpenseCategoryInput {
  name: string;
  isActive?: boolean;
}
export const expenseCategoriesApi = {
  list: () => api.get<ExpenseCategory[]>('/expense-categories').then((r) => r.data),
  create: (body: ExpenseCategoryInput) =>
    api.post<ExpenseCategory>('/expense-categories', body).then((r) => r.data),
  update: (id: string, body: Partial<ExpenseCategoryInput>) =>
    api.patch<ExpenseCategory>(`/expense-categories/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/expense-categories/${id}`).then(() => undefined),
};

// ---------- Labour ----------
export interface LabourInput {
  name: string;
  mobile: string;
  type: LabourType;
  customType?: string;
  harvesterId: string;
  wageType?: WageType;
  dailyWage?: number;
  customAmount?: number;
  paymentStatus?: PaymentStatus;
}
export const labourApi = {
  list: (harvesterId?: string) =>
    api.get<LabourListItem[]>('/labour', { params: { harvesterId } }).then((r) => r.data),
  create: (body: LabourInput) => api.post<Labour>('/labour', body).then((r) => r.data),
  update: (id: string, body: Partial<LabourInput>) =>
    api.patch<Labour>(`/labour/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/labour/${id}`).then(() => undefined),
  ledger: (id: string) => api.get<LabourLedger>(`/labour/${id}/ledger`).then((r) => r.data),
};

// ---------- Attendance (daily workers) ----------
export const attendanceApi = {
  /** Present dates ('YYYY-MM-DD') for a worker within [from, to]. */
  getRange: (labourId: string, from: string, to: string) =>
    api.get<string[]>('/attendance', { params: { labourId, from, to } }).then((r) => r.data),
  /** Replace a worker's attendance for one week with the given present days. */
  setWeek: (labourId: string, weekStart: string, days: string[]) =>
    api.put<string[]>('/attendance/week', { labourId, weekStart, days }).then((r) => r.data),
};

// ---------- Fuel pumps (diesel vendors) ----------
export interface FuelPumpInput {
  name: string;
  phone?: string;
  harvesterIds: string[];
  isActive?: boolean;
}
export const fuelPumpsApi = {
  list: (harvesterId?: string) =>
    api.get<FuelPumpListItem[]>('/fuel-pumps', { params: { harvesterId } }).then((r) => r.data),
  create: (body: FuelPumpInput) => api.post<FuelPump>('/fuel-pumps', body).then((r) => r.data),
  update: (id: string, body: Partial<FuelPumpInput>) =>
    api.patch<FuelPump>(`/fuel-pumps/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/fuel-pumps/${id}`).then(() => undefined),
  ledger: (id: string) => api.get<FuelPumpLedger>(`/fuel-pumps/${id}/ledger`).then((r) => r.data),
};

// ---------- Agents (commission) ----------
export interface AgentInput {
  name: string;
  phone?: string;
  harvesterId: string;
  commissionRate: number;
  isActive?: boolean;
}
export const agentsApi = {
  list: (harvesterId?: string) =>
    api.get<AgentListItem[]>('/agents', { params: { harvesterId } }).then((r) => r.data),
  create: (body: AgentInput) => api.post<Agent>('/agents', body).then((r) => r.data),
  update: (id: string, body: Partial<AgentInput>) =>
    api.patch<Agent>(`/agents/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/agents/${id}`).then(() => undefined),
  ledger: (id: string) => api.get<AgentLedger>(`/agents/${id}/ledger`).then((r) => r.data),
};

// ---------- Plots (harvesting jobs) ----------
export interface PlotInput {
  customerId: string;
  harvesterId: string;
  plotName: string;
  area: number;
  harvestDate: string;
  harvestType: HarvestType;
  areaUnit?: AreaUnit;
  village?: string;
  remarks?: string;
  ratePerBigha?: number;
  bhusaBuyerId?: string;
  bhusaAmount?: number;
  /** Multiple Bhusa buyers, each with their own amount (Type 2). */
  bhusaBuyers?: BhusaBuyer[];
  /** Commission agent for this job; null clears it. */
  agentId?: string | null;
}
export const plotsApi = {
  list: (params?: { harvesterId?: string; customerId?: string }) =>
    api.get<Plot[]>('/plots', { params }).then((r) => r.data),
  get: (id: string) => api.get<Plot>(`/plots/${id}`).then((r) => r.data),
  create: (body: PlotInput) => api.post<Plot>('/plots', body).then((r) => r.data),
  update: (id: string, body: Partial<PlotInput>) =>
    api.patch<Plot>(`/plots/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/plots/${id}`).then(() => undefined),
};

// ---------- Payments ----------
export interface PaymentInput {
  partyType: PartyType;
  partyId: string;
  amount: number;
  date?: string;
  plotId?: string;
  harvesterId?: string;
  notes?: string;
  attachmentUrl?: string;
}
export const paymentsApi = {
  list: (params?: { partyType?: PartyType; partyId?: string; harvesterId?: string }) =>
    api.get<Payment[]>('/payments', { params }).then((r) => r.data),
  create: (body: PaymentInput) => api.post<Payment>('/payments', body).then((r) => r.data),
  update: (id: string, body: Partial<PaymentInput>) =>
    api.patch<Payment>(`/payments/${id}`, body).then((r) => r.data),
  remove: (id: string) => api.delete(`/payments/${id}`).then(() => undefined),
};

// ---------- Uploads (expense bills / receipts) ----------
export interface UploadFile {
  uri: string;
  name: string;
  mimeType?: string;
}
export const uploadsApi = {
  /** Upload one file (max 5 MB) and get back its public URL. */
  upload: (file: UploadFile) => {
    const form = new FormData();
    // React Native's FormData file shape.
    form.append('file', {
      uri: file.uri,
      name: file.name,
      type: file.mimeType ?? 'application/octet-stream',
    } as unknown as Blob);
    return api
      .post<{ url: string }>('/uploads', form, { headers: { 'Content-Type': 'multipart/form-data' } })
      .then((r) => r.data);
  },
};

// ---------- Bug reports ----------
export interface BugReportInput {
  title: string;
  description: string;
  screenshotUrl?: string;
}
export const bugReportsApi = {
  list: () => api.get<BugReport[]>('/bug-reports').then((r) => r.data),
  create: (input: BugReportInput) => api.post('/bug-reports', input).then((r) => r.data),
};

// ---------- Dashboard ----------
export const dashboardApi = {
  summary: (harvesterId?: string) =>
    api.get<DashboardSummary>('/dashboard/summary', { params: { harvesterId } }).then((r) => r.data),
};

// ---------- Maintenance (OWNER only) ----------
export const maintenanceApi = {
  clearData: (password: string) =>
    api
      .delete<{ deleted: Record<string, number> }>('/maintenance/data', { data: { password } })
      .then((r) => r.data),
};
