import { Capacitor } from '@capacitor/core'
import { Preferences } from '@capacitor/preferences'

// 로컬 알림(앱 전용) — 가계부 기록 리마인더 + 구독 만료 임박 알림.
// 서버 푸시(FCM) 없이 기기에서 예약되며, 앱을 켜지 않아도 예약 시간에 표시된다.

const PREF_ENABLED = 'notif_enabled'
const PREF_HOUR = 'notif_hour'
const ENTRY_BASE = 5000 // 가계부 리마인더 id 5000~5006 (7일 롤링)
const ENTRY_DAYS = 7
const EXPIRY_ID = 5100 // 구독 만료 임박 id

let LN = null
async function ln() {
  if (!Capacitor.isNativePlatform()) return null
  if (!LN) LN = (await import('@capacitor/local-notifications')).LocalNotifications
  return LN
}

async function cancelIds(ids) {
  const n = await ln()
  if (!n) return
  try {
    await n.cancel({ notifications: ids.map((id) => ({ id })) })
  } catch {
    /* 무시 */
  }
}

export const reminders = {
  isNative() {
    return Capacitor.isNativePlatform()
  },

  async getSettings() {
    const e = (await Preferences.get({ key: PREF_ENABLED })).value
    const h = (await Preferences.get({ key: PREF_HOUR })).value
    return { enabled: e === '1', hour: h != null ? Number(h) : 21 }
  },

  async setSettings({ enabled, hour }) {
    await Preferences.set({ key: PREF_ENABLED, value: enabled ? '1' : '0' })
    if (hour != null) await Preferences.set({ key: PREF_HOUR, value: String(hour) })
  },

  /** 알림 권한 요청 (Android 13+). 허용되면 true */
  async ensurePermission() {
    const n = await ln()
    if (!n) return false
    let p = await n.checkPermissions()
    if (p.display !== 'granted') p = await n.requestPermissions()
    return p.display === 'granted'
  },

  /** 가계부 리마인더 — 향후 7일 매일 예약(오늘 이미 기록했으면 오늘은 제외) */
  async scheduleEntryReminder(hasEntryToday = false) {
    const n = await ln()
    if (!n) return
    await cancelIds(Array.from({ length: ENTRY_DAYS }, (_, i) => ENTRY_BASE + i))
    const { enabled, hour } = await this.getSettings()
    if (!enabled) return
    const now = new Date()
    const list = []
    for (let i = 0; i < ENTRY_DAYS; i++) {
      const at = new Date(now)
      at.setDate(now.getDate() + i)
      at.setHours(hour, 0, 0, 0)
      if (at <= now) continue
      if (i === 0 && hasEntryToday) continue
      list.push({
        id: ENTRY_BASE + i,
        title: '돈돼지 가계부',
        body: '오늘 가계부 기록을 잊지 않으셨나요? 📝',
        schedule: { at },
      })
    }
    if (list.length) {
      try {
        await n.schedule({ notifications: list })
      } catch {
        /* 무시 */
      }
    }
  },

  /** 오늘 기록을 완료하면 오늘자 리마인더만 취소 */
  async clearTodayReminder() {
    await cancelIds([ENTRY_BASE])
  },

  /**
   * 구독 만료 임박 알림 — 해지(자동갱신 off) 상태에서 만료 3일 전 예약.
   * sub: { premium, autoRenew, expiresAt }
   */
  async scheduleExpiryReminder(sub) {
    const n = await ln()
    if (!n) return
    await cancelIds([EXPIRY_ID])
    const { enabled } = await this.getSettings()
    if (!enabled || !sub || !sub.premium || sub.autoRenew || !sub.expiresAt) return
    const exp = new Date(sub.expiresAt)
    if (Number.isNaN(exp.getTime())) return
    const at = new Date(exp.getTime() - 3 * 24 * 60 * 60 * 1000)
    at.setHours(10, 0, 0, 0)
    if (at <= new Date()) return
    try {
      await n.schedule({
        notifications: [{
          id: EXPIRY_ID,
          title: '돈돼지 가계부',
          body: `프리미엄 구독이 ${exp.getFullYear()}.${exp.getMonth() + 1}.${exp.getDate()}에 만료돼요. 계속 이용하려면 갱신해 주세요.`,
          schedule: { at },
        }],
      })
    } catch {
      /* 무시 */
    }
  },

  /** 알림 전체 해제 (토글 off) */
  async cancelAll() {
    await cancelIds([...Array.from({ length: ENTRY_DAYS }, (_, i) => ENTRY_BASE + i), EXPIRY_ID])
  },
}
