const sendEmail = require('./Email')
const {
    renderEmail,
    escapeNl2br,
    pEsc,
    kv,
    panel,
    notice,
    codeBox
} = require('./emailLayout')

class emailTemplate {
    stramptoTime(time) {
        if (time < 10)
            return ''
        return new Date(+time).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })
    }

    async checkEmail(email, code) {
        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc('您正在进行邮箱验证。如非本人操作，请忽略本邮件。'),
            pEsc('您的验证码为：'),
            codeBox(code),
            notice('验证码 5 分钟内有效，超时请重新获取。', 'danger')
        ].join('')
        await sendEmail(
            email,
            '🔑 邮箱验证码',
            renderEmail({
                pageTitle: '邮箱验证码',
                headline: '🔑 邮箱验证码',
                variant: 'default',
                bodyHtml,
                footerExtra: '请勿向他人泄露验证码。'
            })
        )
    }

    async bindEmailSuccess(email) {
        const time = this.stramptoTime(new Date().getTime())
        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc('您的沐晨乐跑账号绑定邮箱已成功更新。'),
            panel(kv('操作时间', time)),
            pEsc('如非本人操作，请尽快联系客服处理。', { last: true })
        ].join('')
        await sendEmail(
            email,
            '✅ 邮箱换绑成功',
            renderEmail({
                pageTitle: '邮箱换绑成功',
                headline: '✅ 邮箱换绑成功',
                variant: 'success',
                bodyHtml
            })
        )
    }

    async registerSuccess(email, username) {
        const time = new Date().getTime()
        const bodyHtml = [
            pEsc(`尊敬的 ${username}：`),
            pEsc('您已成功注册沐晨乐跑账号，账号信息如下：'),
            panel([
                kv('用户名', username),
                kv('注册时间', this.stramptoTime(time))
            ].join('')),
            pEsc('感谢您的使用。', { last: true })
        ].join('')
        await sendEmail(
            email,
            '✅ 注册成功',
            renderEmail({
                pageTitle: '注册成功',
                headline: '✅ 注册成功',
                variant: 'success',
                bodyHtml,
                footerExtra: '如非本人注册，请尽快联系客服处理。'
            })
        )
    }

    async updateSuccess(email, data) {
        const autoNote = data.auto_run === 0
            ? '当前未开启自动乐跑。如需跑步，请登录沐晨乐跑后手动发起。'
            : '已为您开启自动乐跑，系统将按计划代为完成跑步任务，请留意后续邮件提醒。'

        const bodyHtml = [
            pEsc(`尊敬的 ${data.name}：`),
            pEsc('您的乐跑账号登录信息已更新成功，详情如下：'),
            panel([
                kv('学号', data.account),
                kv('年级', data.grade_id),
                kv('学院', data.academy_name),
                kv('更新时间', this.stramptoTime(new Date().getTime()))
            ].join('')),
            notice(autoNote, 'neutral'),
            notice('请勿在其他设备登录该乐跑账号，以免登录状态失效并需重新绑定。', 'neutral'),
            pEsc('如需帮助，请联系沐晨乐跑客服。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '✅ 乐跑账号更新成功',
            renderEmail({
                pageTitle: '乐跑账号更新成功',
                headline: '✅ 乐跑账号信息已更新',
                variant: 'success',
                bodyHtml
            })
        )
    }

    async lepaoOver(email, data) {
        const targetKm = Number(data.target_km ?? data.target_count) || 0
        const monthKm = Number(data.month_km ?? data.term_num) || 0
        const progressPanel = targetKm > 0
            ? panel([
                kv('本月目标', `${targetKm} km`),
                kv('本月已完成', `${monthKm} km`)
            ].join(''))
            : ''

        const bodyHtml = [
            pEsc(`尊敬的 ${data.name}：`),
            pEsc('您设定的乐跑目标已全部完成，系统已为您关闭自动乐跑功能。'),
            progressPanel,
            pEsc('感谢您的配合。若仍需跑步，可在沐晨乐跑中按需重新开启相关功能。'),
            notice('如有疑问，请通过沐晨乐跑工单反馈。', 'neutral'),
            pEsc('祝您学习生活愉快。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '🏁 乐跑目标已完成',
            renderEmail({
                pageTitle: '乐跑目标已完成',
                headline: '🏁 乐跑目标已全部完成',
                variant: 'success',
                bodyHtml
            })
        )
    }

    async lepaoSuccess(email, data) {
        const targetKm = Number(data.target_km ?? data.target_count) || 0
        const monthKm = Number(data.month_km ?? data.term_num) || 0
        const totalKm = Number(data.total_km ?? data.total_num) || 0
        const timeSec = Number(data.time) || 0
        const distanceKm = Number(data.distance) || 0
        const runZone = data.run_zone_name || data.pass_tit || '—'
        const paceStr =
            distanceKm > 0 && timeSec > 0
                ? this.calculatePace(timeSec, distanceKm)
                : '—'
        const timeStr = timeSec > 0 ? this.formatSecondsToMinSec(timeSec) : '—'

        let goalLines = ''
        if (targetKm === 0) {
            const cumulative = totalKm || monthKm
            goalLines = kv('累计里程', cumulative ? `${cumulative} km` : '—')
        } else {
            goalLines = [
                kv('本月目标', `${targetKm} km`),
                kv('本月已完成', `${monthKm} km`),
                kv('累计里程', totalKm ? `${totalKm} km` : '—')
            ].join('')
        }

        const bodyHtml = [
            pEsc(`尊敬的 ${data.name}：`),
            pEsc('系统已成功代您完成一次乐跑，摘要如下：'),
            panel([
                kv('学号', data.account),
                kv('跑区', runZone),
                kv('用时', timeStr),
                kv('平均配速', paceStr),
                kv('距离', distanceKm ? `${distanceKm} km` : '—'),
                goalLines
            ].join('')),
            notice('若已开启自动乐跑，请勿在其他设备登录该乐跑账号，以免登录状态失效。', 'neutral')
        ].join('')

        await sendEmail(
            email,
            '✅ 乐跑成功通知',
            renderEmail({
                pageTitle: '乐跑成功',
                headline: '✅ 乐跑成功通知',
                variant: 'success',
                bodyHtml
            })
        )
    }

    async lepaoFail(email, data) {
        const time = new Date().getTime()
        const displayName = data.name ?? data.account

        const bodyHtml = [
            pEsc(`尊敬的 ${displayName}：`),
            pEsc('系统在尝试执行乐跑任务时未成功，详情如下：'),
            panel([
                kv('学号', data.account),
                kv('时间', this.stramptoTime(time)),
                kv('原因', data.reason)
            ].join('')),
            notice('若为登录失效，请在沐晨乐跑登录器中重新完成登录后再试。', 'warning'),
            pEsc('若问题持续存在，请联系沐晨乐跑客服并说明学号与失败时间，便于排查。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '❌ 乐跑失败通知',
            renderEmail({
                pageTitle: '乐跑失败',
                headline: '❌ 乐跑未能完成',
                variant: 'danger',
                bodyHtml
            })
        )
    }

    async orderNewReply(email, data) {
        const files = Array.isArray(data.files) ? data.files : []
        const filesNote = files.length > 0
            ? notice('本回复包含附件，请登录沐晨乐跑官网，在工单详情中查看。', 'neutral')
            : ''

        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc(`您提交的工单（编号 ${data.id}）有新的回复：`),
            panel([
                '<p><strong>回复内容：</strong></p>',
                `<p style="margin-top:8px;line-height:1.55;">${escapeNl2br(data.content)}</p>`,
                kv('回复时间', this.stramptoTime(new Date().getTime()))
            ].join('')),
            filesNote,
            notice('请登录沐晨乐跑官网，在工单详情中回复。', 'warning'),
            pEsc('感谢您的理解与配合。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '💬 工单新回复',
            renderEmail({
                pageTitle: '工单状态更新',
                headline: '💬 工单有新回复',
                variant: 'default',
                bodyHtml
            })
        )
    }

    async sendCountRequestNotifyAdmins(email, data) {
        const bodyHtml = [
            pEsc('尊敬的管理员：'),
            pEsc('系统收到一条新的「赠送次数」申请，请及时登录管理后台审核处理。'),
            panel([
                kv('申请 ID', String(data.requestId)),
                kv('赠送人', data.senderUsername),
                kv('接收人', data.receiverUsername),
                kv('赠送次数', String(data.count)),
                kv('申请时间', this.stramptoTime(data.createTime))
            ].join('')),
            notice('请前往沐晨乐跑管理后台完成审核。', 'warning'),
            pEsc('谢谢。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '⏳ 赠送次数待审核',
            renderEmail({
                pageTitle: '赠送次数待审核',
                headline: '⏳ 赠送次数待审核',
                variant: 'warning',
                bodyHtml
            })
        )
    }

    async lepaoAdminWarning(email, data) {
        const time = new Date().getTime()
        const safe = (v) => (v === undefined || v === null) ? '' : String(v)
        const subject = '🚨 乐跑异常告警'

        const bodyHtml = [
            pEsc('尊敬的管理员：'),
            pEsc('自动乐跑流程中出现非常见错误，请关注是否为接口变更、网络异常或程序缺陷，并及时跟进。'),
            panel([
                kv('账号', safe(data.account)),
                kv('姓名', safe(data.name)),
                kv('任务', safe(data.taskType)),
                kv('TraceId', safe(data.traceId)),
                kv('时间', this.stramptoTime(time)),
                kv('错误信息', safe(data.reason)),
                kv('错误码', safe(data.code))
            ].join('')),
            pEsc('以上为系统自动告警，如需更多信息请结合服务端日志进一步排查。', { last: true })
        ].join('')

        await sendEmail(
            email,
            subject,
            renderEmail({
                pageTitle: '乐跑异常告警',
                headline: '🚨 乐跑异常告警',
                headlineSuffixHtml: '<span class="tag">非常见错误</span>',
                variant: 'danger',
                bodyHtml
            })
        )
    }

    async sendCountRequestApproved(email, data) {
        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc('您收到的一笔赠送次数申请已通过审核，次数已到账：'),
            panel([
                kv('赠送人', data.senderUsername),
                kv('到账次数', String(data.count)),
                kv('审核时间', this.stramptoTime(data.reviewTime))
            ].join('')),
            pEsc('您可在沐晨乐跑中查看账户余额与明细。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '✅ 赠送次数审核通过',
            renderEmail({
                pageTitle: '赠送次数审核通过',
                headline: '✅ 赠送次数已到账',
                variant: 'success',
                bodyHtml
            })
        )
    }

    async sendCountRequestRejected(email, data) {
        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc('您发起的一笔赠送次数申请未通过审核，相关次数已退回至您的账户：'),
            panel([
                kv('接收人', data.receiverUsername),
                kv('退回次数', String(data.count)),
                kv('审核时间', this.stramptoTime(data.reviewTime)),
                kv('拒绝原因', data.rejectReason)
            ].join('')),
            notice('如有疑问，请通过沐晨乐跑联系客服处理。', 'neutral'),
            pEsc('感谢您的理解。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '⚠️ 赠送次数审核未通过',
            renderEmail({
                pageTitle: '赠送次数审核未通过',
                headline: '⚠️ 赠送次数审核未通过',
                variant: 'warning',
                bodyHtml
            })
        )
    }

    async powerCheck(email, data) {
        const gap = Number(data.lowest) - Number(data.now_balance)
        const gapStr = Number.isFinite(gap) ? gap.toFixed(2) : ''

        const bodyHtml = [
            pEsc('尊敬的用户：'),
            pEsc(`${data.building}${data.room} 宿舍电费已低于您设定的提醒阈值，请关注余额并及时充值。`),
            panel([
                kv('校区', data.area),
                kv('楼栋', data.building),
                kv('寝室号', data.room),
                kv('当前余额', `￥${data.now_balance}`),
                kv('提醒阈值', `￥${data.lowest}`),
                kv('最近扣费时间', data.now_change_time)
            ].join('')),
            notice(
                gapStr !== ''
                    ? `当前余额已低于提醒阈值 ${gapStr} 元，建议尽快充值以免影响用电。`
                    : '当前余额已低于提醒阈值，建议尽快充值以免影响用电。',
                'warning'
            ),
            pEsc('您可在沐晨乐跑中调整提醒阈值或管理电费订阅。', { last: true })
        ].join('')

        await sendEmail(
            email,
            '⚡ 宿舍电费提醒',
            renderEmail({
                pageTitle: '宿舍电费提醒',
                headline: '⚡ 宿舍电费余额提醒',
                variant: 'warning',
                bodyHtml
            })
        )
    }

    formatSecondsToMinSec(totalSeconds) {
        const minutes = Math.floor(totalSeconds / 60)
        const seconds = totalSeconds % 60

        return `${minutes}分${seconds.toString().padStart(2, '0')}秒`
    }

    calculatePace(seconds, kilometers) {
        const paceInSeconds = seconds / kilometers
        const minutes = Math.floor(paceInSeconds / 60)
        const remainingSeconds = Math.round(paceInSeconds % 60)

        return `${minutes}'${remainingSeconds.toString().padStart(2, '0')}''`
    }
}

const EmailTemplate = new emailTemplate()
module.exports = EmailTemplate
