export type PaymentMethod = 'Cash' | 'Check' | 'Zelle' | 'PayPal' | 'Other';
export type SessionStatus = 'Draft' | 'Submitted' | 'Reconciled';

export interface PagedResult<T> {
  items: T[];
  totalCount: number;
  page: number;
  pageSize: number;
  totalPages: number;
}

// ── Giving categories ─────────────────────────────────────────────
export interface GivingCategoryDto {
  id: number;
  name_en: string;
  name_zh: string | null;
  description_en: string | null;
  description_zh: string | null;
  isActive: boolean;
  sortOrder: number;
  /** Display-only bilingual label, computed in the API service. */
  label?: string;
}
export interface CreateGivingCategoryRequest {
  name_en: string;
  name_zh: string | null;
  description_en: string | null;
  description_zh: string | null;
  sortOrder: number;
}
export interface UpdateGivingCategoryRequest extends CreateGivingCategoryRequest {
  isActive: boolean;
}

// ── Single giving ─────────────────────────────────────────────────
export interface GivingListItemDto {
  id: number;
  memberId: number | null;
  memberName: string | null;
  givingCategoryId: number;
  categoryName: string;
  amount: number;
  paymentMethod: PaymentMethod;
  givingDate: string;       // yyyy-MM-dd
  isAnonymous: boolean;
  offeringSessionId: number | null;
}
export interface CreateGivingRequest {
  memberId: number | null;
  givingCategoryId: number;
  amount: number;
  paymentMethod: PaymentMethod;
  checkNumber: string | null;
  zelleReferenceCode: string | null;
  payPalTransactionId: string | null;
  givingDate: string;       // yyyy-MM-dd
  isAnonymous: boolean;
  notes: string | null;
}
export type UpdateGivingRequest = CreateGivingRequest;

// ── Offering session (batch) ──────────────────────────────────────
export interface OfferingGivingLineRequest {
  memberId: number | null;
  givingCategoryId: number;
  amount: number;
  paymentMethod: PaymentMethod;
  checkNumber: string | null;
  zelleReferenceCode: string | null;
  payPalTransactionId: string | null;
  isAnonymous: boolean;
  notes: string | null;
}
export interface CreateOfferingSessionRequest {
  sessionDate: string;      // yyyy-MM-dd
  cashTotal: number;
  checkTotal: number;
  notes: string | null;
  givings: OfferingGivingLineRequest[];
}
export interface OfferingGivingLineDto {
  id: number;
  memberId: number | null;
  memberName: string | null;
  givingCategoryId: number;
  categoryName: string;
  amount: number;
  paymentMethod: PaymentMethod;
  checkNumber: string | null;
  zelleReferenceCode: string | null;
  payPalTransactionId: string | null;
  isAnonymous: boolean;
  notes: string | null;
}
export interface OfferingSessionDto {
  id: number;
  sessionDate: string;
  status: SessionStatus;
  cashTotal: number;
  checkTotal: number;
  systemTotal: number;
  difference: number;
  notes: string | null;
  hasProof: boolean;
  givings: OfferingGivingLineDto[];
}
export interface OfferingSessionListItemDto {
  id: number;
  sessionDate: string;
  status: SessionStatus;
  cashTotal: number;
  checkTotal: number;
  systemTotal: number;
  difference: number;
  lineCount: number;
  hasProof: boolean;
  sundayAttendanceCount?: number | null;
}

/** A row held in the client-side batch buffer before submit. */
export interface OfferingBufferLine extends OfferingGivingLineRequest {
  memberName: string | null;   // for display only
  categoryName: string;        // for display only
}

// ── Mobile offering entry (anonymous, one line at a time) ─────────
/** Minimal member fields the anonymous giver typeahead needs. */
export interface MemberTypeaheadDto {
  id: number;
  nickName: string | null;
  firstName_en: string;
  lastName_en: string;
  entity: string | null;
}
/** A day's session as the mobile page sees it. */
export interface OfferingEntrySummaryDto {
  sessionId: number | null;    // null when no session exists for the date yet
  sessionDate: string;         // yyyy-MM-dd
  status: SessionStatus | null;
  systemTotal: number;
  lineCount: number;
  hasProof: boolean;           // a merged paper-proof PDF is attached to this session
  lines: OfferingGivingLineDto[];
}
/** One-shot payload that seeds the mobile page. */
export interface OfferingEntryBootstrapDto {
  sessionDate: string;         // yyyy-MM-dd
  categories: GivingCategoryDto[];
  summary: OfferingEntrySummaryDto;
}
/** Body of POST /api/offering-entry/lines. */
export interface AppendOfferingLineRequest {
  date: string;                // yyyy-MM-dd
  line: OfferingGivingLineRequest;
}
/** Body of POST /api/offering-entry/members — quick-add a giver (created as Visitor). */
export interface QuickAddMemberRequest {
  firstName_en: string;
  lastName_en: string;
  nickName: string | null;
  firstName_zh: string | null;
  lastName_zh: string | null;
  entity: string | null;
  phoneCell: string | null;
}
/** Returned from append + broadcast over the OfferingEntryHub. */
export interface OfferingEntryLineAddedDto {
  sessionId: number;
  sessionDate: string;         // yyyy-MM-dd
  status: SessionStatus;
  systemTotal: number;
  lineCount: number;
  line: OfferingGivingLineDto;
}
