/**
 * CSV layout matching the Toggl Detailed Report EXPORT. This file becomes
 * the invoicing-sheet import going forward (Rian's workflow ends here —
 * no further round-trip through Toggl).
 *
 * Columns (exact order, including empty placeholders so the receiving
 * sheet's parser stays happy):
 *   Member, Email, Client, Project, Project end, Description, Teams,
 *   Start date, Stop date, Project start, Start time, Stop time,
 *   Duration, Tags
 *
 * - Date: YYYY-MM-DD
 * - Time: HH:MM:SS (24-hour, local)
 * - Duration: HH:MM:SS
 * - Tags: original employee email (for traceability)
 * - Project end / Teams / Project start: emitted as "-" to match
 *   Toggl's placeholder convention for missing values.
 */

import Papa from 'papaparse'

export type TogglRow = {
  Member: string
  Email: string
  Client: string
  Project: string
  'Project end': string
  Description: string
  Teams: string
  'Start date': string
  'Stop date': string
  'Project start': string
  'Start time': string
  'Stop time': string
  Duration: string
  Tags: string
}

export const TOGGL_COLUMNS: (keyof TogglRow)[] = [
  'Member',
  'Email',
  'Client',
  'Project',
  'Project end',
  'Description',
  'Teams',
  'Start date',
  'Stop date',
  'Project start',
  'Start time',
  'Stop time',
  'Duration',
  'Tags',
]

export function formatDurationSeconds(s: number): string {
  const h = Math.floor(s / 3600)
  const m = Math.floor((s % 3600) / 60)
  const sec = s % 60
  return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`
}

// Naive timestamp 'YYYY-MM-DD HH:MM:SS' (or with T) -> { date, time }
export function splitNaiveTimestamp(ts: string): { date: string; time: string } {
  const s = ts.replace('T', ' ').trim()
  // Postgres may return e.g. '2026-04-25T14:10:47' or '2026-04-25 14:10:47'
  const m = s.match(/^(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})/)
  if (m) return { date: m[1], time: m[2] }
  // Best-effort fallback
  return { date: s.slice(0, 10), time: s.slice(11, 19) || '00:00:00' }
}

export type EligibleEntry = {
  source_user_email: string
  operator: string | null   // "Bowden Works" / "PlusROI" — emitted as Toggl's Client column
  client: string | null     // end client — recombined into Toggl's Project column
  project: string | null
  description: string | null
  billable: boolean | null
  start_at: string
  end_at: string | null
  converted_user: string
  converted_duration_seconds: number
}

export const ADI_EMAIL = 'info@adipramono.com'

/** Recombine end client + project name into the Toggl project format. */
export function joinClientProject(
  client: string | null,
  project: string | null,
): string {
  if (client && project) return `${client} : ${project}`
  return project ?? client ?? ''
}

export type BuildTogglCsvOptions = {
  /**
   * Value to put in the **Teams** column (column G, 7th). Used by the
   * invoicing sheet to tag every row with the billing month — e.g.
   * `'2026-04'`. Defaults to `'-'` (Toggl's placeholder convention).
   */
  teams?: string
  /**
   * Whether to emit the header row. The invoicing-sheet import doesn't
   * use one, so we default to `false`. Pass `true` if you need a
   * human-readable preview.
   */
  header?: boolean
}

export function buildTogglCsv(
  entries: EligibleEntry[],
  options: BuildTogglCsvOptions = {},
): string {
  const teamsValue = options.teams && options.teams.trim() !== ''
    ? options.teams
    : '-'
  const header = options.header ?? false

  const rows = entries.map<TogglRow>((e) => {
    const startBits = splitNaiveTimestamp(e.start_at)
    const endBits = e.end_at
      ? splitNaiveTimestamp(e.end_at)
      : { date: startBits.date, time: startBits.time }
    return {
      Member: e.converted_user,
      Email: ADI_EMAIL,
      Client: e.operator ?? '',
      Project: joinClientProject(e.client, e.project),
      'Project end': '-',
      Description: e.description ?? '',
      Teams: teamsValue,
      'Start date': startBits.date,
      'Stop date': endBits.date,
      'Project start': '-',
      'Start time': startBits.time,
      'Stop time': endBits.time,
      Duration: formatDurationSeconds(e.converted_duration_seconds),
      Tags: e.source_user_email,
    }
  })

  return Papa.unparse(rows, {
    columns: TOGGL_COLUMNS as string[],
    header,
  })
}

/**
 * An entry is eligible for transfer when it has everything Toggl import requires.
 * Returns null if eligible, otherwise a string explaining why it's blocked.
 */
/**
 * What's missing on this row that prevents it from being attached to
 * an invoice. Mirrors the SQL "blocked" predicate in
 * entries_filter_totals / project_summary and the JS ELIGIBILITY_COLUMNS
 * in entries/actions.ts. Update all three together.
 *
 * Converted_user + converted_duration_seconds are intentionally not
 * required — they're Toggl-export plumbing that the invoice flow
 * doesn't read.
 */
export function blockerReason(e: {
  team_member_id: string | null
  operator: string | null
  client: string | null
  project: string | null
  description: string | null
  start_at: string | null
  end_at: string | null
  source_user_email: string | null
}): string | null {
  if (!e.team_member_id) return 'Unknown person — pick a Team member.'
  if (!e.operator) return 'Missing operator (BW / PlusROI).'
  if (!e.client) return 'Missing client.'
  if (!e.project) return 'Missing project.'
  if (!e.description) return 'Missing description.'
  if (!e.start_at) return 'Missing start time.'
  if (!e.end_at) return 'Missing end time.'
  if (!e.source_user_email) return 'Missing source email.'
  return null
}
