package com.fieldlabel.collector.data.remote

import com.fieldlabel.collector.domain.model.CollectionRecord
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.SetOptions
import kotlinx.coroutines.tasks.await
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class FirestoreDataSource @Inject constructor(
    private val db: FirebaseFirestore,
    private val auth: FirebaseAuth
) {
    private val userId: String
        get() = auth.currentUser?.uid ?: "anonymous"

    private fun recordsCollection() =
        db.collection("collections").document(userId).collection("records")

    /** 単一レコードをFirestoreへ保存（新規 or 上書き） */
    suspend fun upsert(record: CollectionRecord) {
        val data = mapOf(
            "locationId"     to record.locationId,
            "specimenNumber" to record.specimenNumber,
            "specimenId"     to record.specimenId,
            "collectionDate" to record.collectionDate.toString(),
            "latitude"       to record.latitude,
            "longitude"      to record.longitude,
            "altitude"       to record.altitude,
            "address"        to record.address,
            "collectorName"  to record.collectorName,
            "notes"          to record.notes,
            "createdAt"      to record.createdAt.toString(),
            "syncedAt"       to System.currentTimeMillis()
        )
        recordsCollection().document(record.id).set(data, SetOptions.merge()).await()
    }

    /** 未同期レコードを一括アップロード（最大500件/バッチ） */
    suspend fun batchUpsert(records: List<CollectionRecord>) {
        if (records.isEmpty()) return
        records.chunked(400).forEach { chunk ->
            val batch = db.batch()
            chunk.forEach { record ->
                val ref = recordsCollection().document(record.id)
                val data = mapOf(
                    "locationId"     to record.locationId,
                    "specimenNumber" to record.specimenNumber,
                    "specimenId"     to record.specimenId,
                    "collectionDate" to record.collectionDate.toString(),
                    "latitude"       to record.latitude,
                    "longitude"      to record.longitude,
                    "altitude"       to record.altitude,
                    "address"        to record.address,
                    "collectorName"  to record.collectorName,
                    "notes"          to record.notes,
                    "createdAt"      to record.createdAt.toString(),
                    "syncedAt"       to System.currentTimeMillis()
                )
                batch.set(ref, data, SetOptions.merge())
            }
            batch.commit().await()
        }
    }

    /**
     * 匿名認証でサインイン（ユーザー登録不要でFirestoreを使えるようにする）
     * 初回起動時にDIから呼ばれる
     */
    suspend fun ensureSignedIn() {
        if (auth.currentUser == null) {
            auth.signInAnonymously().await()
        }
    }
}
