import type { GlobalBirthProfile } from "./global-birth-payloads.ts"; const usableActiveStatuses = new Set(["accepted", "confirmed"]); export const ACCOUNT_BIRTH_SELECT = "name,birth_date,reported_birth_time,active_birth_time,birth_time,birth_time_status,country_code,province_code,city_code,district_code,latitude,longitude,timezone_offset,timezone_id" as const; export type AccountBirthRow = Readonly<{ name?: unknown; birth_date?: unknown; reported_birth_time?: unknown; active_birth_time?: unknown; birth_time?: unknown; birth_time_status?: unknown; country_code?: unknown; province_code?: unknown; city_code?: unknown; district_code?: unknown; latitude?: unknown; longitude?: unknown; timezone_offset?: unknown; timezone_id?: unknown; }>; function asAccountBirthRow(row: unknown): AccountBirthRow { if (!row || typeof row !== "object" || Array.isArray(row)) return {}; return row as AccountBirthRow; } function text(value: unknown): string | undefined { if (typeof value !== "string") return undefined; const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : undefined; } function calendarDate(value: unknown): string | undefined { if (value instanceof Date && Number.isFinite(value.getTime())) { return value.toISOString().slice(0, 10); } const raw = text(value)?.slice(0, 10); return raw && /^\d{4}-\d{2}-\d{2}$/.test(raw) ? raw : undefined; } function clock(value: unknown): string | undefined { const raw = text(value); const match = raw ? /^(\d{1,2}):(\d{2})/.exec(raw) : null; if (!match) return undefined; const hour = Number.parseInt(match[1], 10); const minute = Number.parseInt(match[2], 10); if (hour < 0 || hour > 23 || minute < 0 || minute > 59) return undefined; return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`; } function finiteNumber(value: unknown): number | undefined { if (typeof value === "number" && Number.isFinite(value)) return value; if (typeof value === "string" && value.trim()) { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : undefined; } return undefined; } function selectedClock(row: AccountBirthRow): string | undefined { const status = text(row.birth_time_status) ?? ""; const active = clock(row.active_birth_time) ?? clock(row.birth_time); const reported = clock(row.reported_birth_time); if (usableActiveStatuses.has(status) && active) return active; return reported ?? active; } export function globalBirthProfileFromAccountRow(row: unknown): GlobalBirthProfile & { birthTimeStatus?: string; } { const accountRow = asAccountBirthRow(row); return { name: text(accountRow.name), date: calendarDate(accountRow.birth_date), time: selectedClock(accountRow), countryCode: text(accountRow.country_code), provinceCode: text(accountRow.province_code), cityCode: text(accountRow.city_code), districtCode: text(accountRow.district_code), latitude: finiteNumber(accountRow.latitude) ?? null, longitude: finiteNumber(accountRow.longitude) ?? null, timezoneOffset: finiteNumber(accountRow.timezone_offset) ?? null, timezoneId: text(accountRow.timezone_id), birthTimeStatus: text(accountRow.birth_time_status), }; } export function globalBirthProfileFromStoredChart(value: unknown): GlobalBirthProfile | null { if (!value || typeof value !== "object" || Array.isArray(value)) return null; const record = value as Record; const profile = globalBirthProfileFromAccountRow({ name: record.name, birth_date: record.date ?? record.birth_date, reported_birth_time: record.reportedTime ?? record.reported_birth_time, active_birth_time: record.time ?? record.active_birth_time, birth_time: record.birth_time, birth_time_status: record.birthTimeStatus ?? record.birth_time_status, country_code: record.countryCode ?? record.country_code, province_code: record.provinceCode ?? record.province_code, city_code: record.cityCode ?? record.city_code, district_code: record.districtCode ?? record.district_code, latitude: record.latitude, longitude: record.longitude, timezone_offset: record.timezoneOffset ?? record.timezone_offset, timezone_id: record.timezoneId ?? record.timezone_id, }); if (!profile.date || !profile.time) return null; return profile; }