package com.applemand.zmanim.core.calsync

import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.provider.CalendarContract
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Writes VEVENT-like rows into the user's system calendar via CalendarContract.
 * Caller must already hold WRITE_CALENDAR permission — the UI layer prompts for it
 * before invoking `export`.
 */
@Singleton
class CalendarContractBridge @Inject constructor(
    @ApplicationContext private val context: Context,
) {
    /** Returns inserted event IDs so they can be unsynced later. */
    fun export(calendarId: Long, events: List<IcsEvent>, tzid: String): List<Long> {
        val ids = mutableListOf<Long>()
        val resolver = context.contentResolver
        for (e in events) {
            val cv = ContentValues().apply {
                put(CalendarContract.Events.CALENDAR_ID, calendarId)
                put(CalendarContract.Events.TITLE, e.summary)
                put(CalendarContract.Events.DESCRIPTION, e.description ?: "")
                put(CalendarContract.Events.DTSTART, e.start.toEpochMilli())
                put(CalendarContract.Events.DTEND, (e.end ?: e.start.plusSeconds(60)).toEpochMilli())
                put(CalendarContract.Events.EVENT_TIMEZONE, tzid)
                put(CalendarContract.Events.ALL_DAY, if (e.allDay) 1 else 0)
                put(CalendarContract.Events.HAS_ALARM, 0)
            }
            val uri = runCatching {
                resolver.insert(CalendarContract.Events.CONTENT_URI, cv)
            }.getOrNull() ?: continue
            val id = ContentUris.parseId(uri)
            ids += id
        }
        return ids
    }

    fun delete(eventId: Long): Boolean {
        val uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId)
        return context.contentResolver.delete(uri, null, null) > 0
    }

    /** Read available writable calendars so user can pick a target. */
    fun availableCalendars(): List<CalendarRef> {
        val projection = arrayOf(
            CalendarContract.Calendars._ID,
            CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
            CalendarContract.Calendars.ACCOUNT_NAME,
            CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
        )
        val sel = "${CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL} >= ?"
        val args = arrayOf(CalendarContract.Calendars.CAL_ACCESS_CONTRIBUTOR.toString())
        val out = mutableListOf<CalendarRef>()
        context.contentResolver.query(
            CalendarContract.Calendars.CONTENT_URI, projection, sel, args, null
        )?.use { c ->
            val idCol = c.getColumnIndexOrThrow(CalendarContract.Calendars._ID)
            val nameCol = c.getColumnIndexOrThrow(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME)
            val accCol = c.getColumnIndexOrThrow(CalendarContract.Calendars.ACCOUNT_NAME)
            while (c.moveToNext()) {
                out += CalendarRef(c.getLong(idCol), c.getString(nameCol) ?: "", c.getString(accCol) ?: "")
            }
        }
        return out
    }
}

data class CalendarRef(val id: Long, val displayName: String, val account: String)
