"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimezoneService = void 0;
const luxon_1 = require("luxon");
const ct = __importStar(require("countries-and-timezones"));
// 自定义默认时区映射表
const defaultTimezoneMap = {
    BR: "America/Sao_Paulo", // 巴西（圣保罗）
    RU: "Europe/Moscow", // 俄罗斯（莫斯科）
    US: "America/New_York", // 美国（纽约，代表东部时区）
    IN: "Asia/Kolkata", // 印度（加尔各答）
    MX: "America/Mexico_City", // 墨西哥（墨西哥城）
    AR: "America/Argentina/Buenos_Aires", // 阿根廷（布宜诺斯艾利斯）
    ID: "Asia/Jakarta", // 印尼（雅加达）
    ES: "Europe/Madrid", // 西班牙（马德里）
    CL: "America/Santiago", // 智利（圣地亚哥）
    CO: "America/Bogota", // 哥伦比亚（波哥大）
    FR: "Europe/Paris", // 法国（巴黎）
    IT: "Europe/Rome", // 意大利（罗马）
    PL: "Europe/Warsaw", // 波兰（华沙）
    DE: "Europe/Berlin", // 德国（柏林）
    RO: "Europe/Bucharest", // 罗马尼亚（布加勒斯特）
    GB: "Europe/London", // 英国（伦敦）
    UA: "Europe/Kyiv", // 乌克兰（基辅）
    TR: "Europe/Istanbul", // 土耳其（伊斯坦布尔）
    JP: "Asia/Tokyo", // 日本（东京）
    PH: "Asia/Manila", // 菲律宾（马尼拉）
    KR: "Asia/Seoul", // 韩国（首尔）
    CA: "America/Toronto", // 加拿大（多伦多，代表东部时区）
    IR: "Asia/Tehran", // 伊朗（德黑兰）
    TH: "Asia/Bangkok", // 泰国（曼谷）
    CR: "America/Costa_Rica", // 哥斯达黎加（圣何塞）
    ZA: "Africa/Johannesburg", // 南非（约翰内斯堡）
    VE: "America/Caracas", // 委内瑞拉（加拉加斯）
    AU: "Australia/Sydney", // 澳大利亚（悉尼，代表东部时区）
    PK: "Asia/Karachi", // 巴基斯坦（卡拉奇）
    VN: "Asia/Ho_Chi_Minh", // 越南（胡志明市）
    HU: "Europe/Budapest", // 匈牙利（布达佩斯）
    PT: "Europe/Lisbon", // 葡萄牙（里斯本）
    EG: "Africa/Cairo", // 埃及（开罗）
    CN: "Asia/Shanghai", // 中国（上海）
};
/**
 * 这是一个处理时区转换的单例服务。
 */
class TimezoneService {
    constructor() {
        /**
         * 将 YYYY-MM-DD 格式的日期转换为指定时区的时间范围（00:00:00 至 23:59:59.999）
         * @param dateStr 日期字符串（YYYY-MM-DD）
         * @param timeZone 时区（如 'Asia/Shanghai'、'America/New_York'）
         * @returns 包含 start（UTC 开始时间）和 end（UTC 结束时间）的对象，转换失败返回null
         */
        this.getTimeRangeInTimeZone = (dateStr, timeZone = "America/Los_Angeles") => {
            if (!dateStr)
                return null;
            // 解析日期字符串
            const [year, month, day] = dateStr.split("-").map(Number);
            if (!year || !month || !day || month < 1 || month > 12 || day < 1 || day > 31) {
                console.error("Invalid date format. Expected YYYY-MM-DD");
                return null;
            }
            try {
                // 1. 在指定时区创建当天00:00:00的日期
                // 使用Intl.DateTimeFormat解析指定时区的日期
                const formatter = new Intl.DateTimeFormat("en-US", {
                    timeZone,
                    year: "numeric",
                    month: "2-digit",
                    day: "2-digit",
                    hour: "2-digit",
                    minute: "2-digit",
                    second: "2-digit",
                    hour12: false,
                });
                // 构造指定时区的当天0点字符串
                const dateStrInTimeZone = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")} 00:00:00`;
                const parts = formatter.formatToParts(new Date(dateStrInTimeZone));
                // 提取指定时区的年月日时分秒
                const dateParts = {};
                parts.forEach((part) => {
                    if (["year", "month", "day", "hour", "minute", "second"].includes(part.type)) {
                        dateParts[part.type] = parseInt(part.value, 10);
                    }
                });
                // 2. 计算指定时区的00:00:00对应的UTC时间
                const startInTimeZone = new Date(dateParts.year, dateParts.month - 1, // 月份从0开始
                dateParts.day, dateParts.hour, dateParts.minute, dateParts.second);
                // 3. 计算指定时区的23:59:59.999对应的UTC时间
                const endInTimeZone = new Date(startInTimeZone);
                endInTimeZone.setHours(23, 59, 59, 999);
                return {
                    start: new Date(startInTimeZone.toISOString()),
                    end: new Date(endInTimeZone.toISOString()),
                };
            }
            catch (error) {
                console.error("Error converting date to time zone:", error);
                return null;
            }
        };
    }
    static getInstance() {
        if (!TimezoneService.instance) {
            TimezoneService.instance = new TimezoneService();
        }
        return TimezoneService.instance;
    }
    /**
     * 根据国家代码获取对应的时区。
     * 优先从自定义映射表中查找，如果找不到，则退回到 countries-and-timezones 库的第一个时区。
     * 如果仍找不到，默认返回 'UTC'。
     * @param countryCode 国家代码（如 'US', 'CN'）
     * @returns 时区字符串（如 'Asia/Shanghai'）
     */
    getTimezoneByCountryCode(countryCode) {
        const uppercaseCc = countryCode.toUpperCase();
        // 1. 优先从自定义映射表中查找
        if (defaultTimezoneMap[uppercaseCc]) {
            return defaultTimezoneMap[uppercaseCc];
        }
        // 2. 如果自定义映射表中没有，则退回到 countries-and-timezones 库
        const country = ct.getCountry(uppercaseCc);
        if (country && country.timezones && country.timezones.length > 0) {
            return country.timezones[0];
        }
        // 3. 最终默认值
        return "UTC";
    }
    getNowInTimezone(timezone) {
        return luxon_1.DateTime.now().setZone(timezone);
    }
    getUTCFromTimezoneDate(localDateTime, timezone) {
        const zonedTime = localDateTime.setZone(timezone, { keepLocalTime: true });
        return zonedTime.toJSDate();
    }
    getPlannedSendTime(cc, targetHour) {
        const now = luxon_1.DateTime.now().toUTC();
        const timezone = this.getTimezoneByCountryCode(cc || "US");
        const plannedTime = now.setZone(timezone).set({ hour: targetHour, minute: 0, second: 0, millisecond: 0 });
        let plannedSendAt = plannedTime.toUTC();
        if (plannedSendAt < now) {
            plannedSendAt = plannedSendAt.plus({ days: 1 });
        }
        return plannedSendAt.toJSDate();
    }
}
exports.TimezoneService = TimezoneService;
// ---
// 示例用法（非代码库一部分，仅供测试）
if (require.main === module) {
    const timezoneService = TimezoneService.getInstance();
    const userCountryCode = "RU";
    const targetHour = 8; // 巴西当地早上8点
    // 验证 getPlannedSendTime 方法
    const plannedTimeUTC = timezoneService.getPlannedSendTime(userCountryCode, targetHour);
    const plannedTimeUTCISO = plannedTimeUTC.toISOString();
    // 获取北京时间，用于对比
    const beijingTimezone = timezoneService.getTimezoneByCountryCode("CN");
    const beijingTime = luxon_1.DateTime.fromJSDate(plannedTimeUTC, { zone: beijingTimezone });
    console.log(`--- 计算结果 ---`);
    console.log(`用户国家：${userCountryCode}`);
    console.log(`目标时区：${timezoneService.getTimezoneByCountryCode(userCountryCode)}`);
    console.log(`目标当地时间：${targetHour}:00:00`);
    console.log(`计算出的UTC计划发送时间：${plannedTimeUTCISO}`);
    console.log(`对应的北京时间：${beijingTime.toLocaleString(luxon_1.DateTime.DATETIME_FULL)}`);
    console.log(`对应的北京时间（ISO）：${beijingTime.toISO()}`);
}
