package com.tt.honeyDue.ui.screens.task

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tt.honeyDue.analytics.AnalyticsEvents
import com.tt.honeyDue.analytics.PostHogAnalytics
import com.tt.honeyDue.models.BulkCreateTasksRequest
import com.tt.honeyDue.models.BulkCreateTasksResponse
import com.tt.honeyDue.models.TaskCreateRequest
import com.tt.honeyDue.models.TaskTemplate
import com.tt.honeyDue.models.TaskTemplatesGroupedResponse
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

/**
 * ViewModel for [TaskTemplatesBrowserScreen]. Loads grouped templates,
 * manages category filter, multi-select state, and bulk-create submission.
 *
 * [loadTemplates] and [bulkCreate] are injected as suspend functions so
 * the ViewModel can be unit-tested without hitting [APILayer] singletons.
 *
 * [analytics] is a plain lambda so tests can verify PostHog event names and
 * payloads.
 *
 * [fromOnboarding] picks which analytics event family to fire on successful
 * apply:
 *   - true  → onboarding_browse_template_accepted + onboarding_tasks_created
 *   - false → task_template_accepted + task_templates_bulk_created
 * (event names match iOS AnalyticsManager.swift)
 */
class TaskTemplatesBrowserViewModel(
    private val residenceId: Int,
    private val fromOnboarding: Boolean = false,
    private val loadTemplates: suspend (Boolean) -> ApiResult<TaskTemplatesGroupedResponse> = { force ->
        APILayer.getTaskTemplatesGrouped(forceRefresh = force)
    },
    private val bulkCreate: suspend (BulkCreateTasksRequest) -> ApiResult<BulkCreateTasksResponse> = { req ->
        APILayer.bulkCreateTasks(req)
    },
    private val analytics: (String, Map<String, Any>) -> Unit = { name, props ->
        PostHogAnalytics.capture(name, props)
    }
) : ViewModel() {

    private val _templatesState =
        MutableStateFlow<ApiResult<TaskTemplatesGroupedResponse>>(ApiResult.Idle)
    val templatesState: StateFlow<ApiResult<TaskTemplatesGroupedResponse>> =
        _templatesState.asStateFlow()

    /** Category name currently filtered to. null means "All categories". */
    private val _selectedCategory = MutableStateFlow<String?>(null)
    val selectedCategory: StateFlow<String?> = _selectedCategory.asStateFlow()

    /** Template ids the user has selected for bulk creation. */
    private val _selectedTemplateIds = MutableStateFlow<Set<Int>>(emptySet())
    val selectedTemplateIds: StateFlow<Set<Int>> = _selectedTemplateIds.asStateFlow()

    private val _applyState = MutableStateFlow<ApiResult<Int>>(ApiResult.Idle)
    /** Success carries the count of tasks created. */
    val applyState: StateFlow<ApiResult<Int>> = _applyState.asStateFlow()

    /** True when at least one template is selected. */
    val canApply: Boolean
        get() = _selectedTemplateIds.value.isNotEmpty()

    /** All categories parsed from the loaded grouped response. */
    val categoryNames: List<String>
        get() = (_templatesState.value as? ApiResult.Success)
            ?.data?.categories?.map { it.categoryName } ?: emptyList()

    /** Templates filtered by [selectedCategory]. When null returns all. */
    fun filteredTemplates(): List<TaskTemplate> {
        val grouped = (_templatesState.value as? ApiResult.Success)?.data ?: return emptyList()
        val cat = _selectedCategory.value
        return if (cat == null) {
            grouped.categories.flatMap { it.templates }
        } else {
            grouped.categories.firstOrNull { it.categoryName == cat }?.templates ?: emptyList()
        }
    }

    fun load(forceRefresh: Boolean = false) {
        viewModelScope.launch {
            _templatesState.value = ApiResult.Loading
            _templatesState.value = loadTemplates(forceRefresh)
        }
    }

    fun selectCategory(categoryName: String?) {
        _selectedCategory.value = categoryName
    }

    /** Adds the id if absent, removes it if present. */
    fun toggleSelection(templateId: Int) {
        val current = _selectedTemplateIds.value
        _selectedTemplateIds.value = if (templateId in current) {
            current - templateId
        } else {
            current + templateId
        }
    }

    fun clearSelection() {
        _selectedTemplateIds.value = emptySet()
    }

    /** Reset apply state (e.g. after dismissing an error). */
    fun resetApplyState() {
        _applyState.value = ApiResult.Idle
    }

    /**
     * Build one [TaskCreateRequest] per selected template (with templateId
     * backlink) and call bulkCreateTasks. On success fires the configured
     * analytics events and leaves [applyState] as Success(count). On error
     * leaves state as [ApiResult.Error] so the screen can surface it without
     * dismissing.
     */
    fun apply() {
        if (!canApply) return
        val templates = filteredTemplatesAll()
            .filter { it.id in _selectedTemplateIds.value }
        if (templates.isEmpty()) return

        viewModelScope.launch {
            _applyState.value = ApiResult.Loading

            val requests = templates.map { template ->
                TaskCreateRequest(
                    residenceId = residenceId,
                    title = template.title,
                    description = template.description.takeIf { it.isNotBlank() },
                    categoryId = template.categoryId,
                    frequencyId = template.frequencyId,
                    templateId = template.id
                )
            }
            val request = BulkCreateTasksRequest(
                residenceId = residenceId,
                tasks = requests
            )

            val result = bulkCreate(request)
            _applyState.value = when (result) {
                is ApiResult.Success -> {
                    val count = result.data.createdCount
                    if (fromOnboarding) {
                        templates.forEach { template ->
                            analytics(
                                AnalyticsEvents.ONBOARDING_BROWSE_TEMPLATE_ACCEPTED,
                                buildMap {
                                    put("template_id", template.id)
                                    template.categoryId?.let { put("category_id", it) }
                                }
                            )
                        }
                        analytics(
                            AnalyticsEvents.ONBOARDING_TASKS_CREATED,
                            mapOf("count" to count)
                        )
                    } else {
                        templates.forEach { template ->
                            analytics(
                                EVENT_TASK_TEMPLATE_ACCEPTED,
                                buildMap {
                                    put("template_id", template.id)
                                    template.categoryId?.let { put("category_id", it) }
                                }
                            )
                        }
                        analytics(
                            EVENT_TASK_TEMPLATES_BULK_CREATED,
                            mapOf("count" to count)
                        )
                    }
                    ApiResult.Success(count)
                }
                is ApiResult.Error -> ApiResult.Error(result.message, result.code)
                ApiResult.Loading -> ApiResult.Loading
                ApiResult.Idle -> ApiResult.Idle
            }
        }
    }

    /** Full list regardless of category filter. Used by apply() for lookups. */
    private fun filteredTemplatesAll(): List<TaskTemplate> {
        val grouped = (_templatesState.value as? ApiResult.Success)?.data ?: return emptyList()
        return grouped.categories.flatMap { it.templates }
    }

    companion object {
        /** Non-onboarding analytics event names (match iOS AnalyticsEvent.swift). */
        const val EVENT_TASK_TEMPLATE_ACCEPTED = "task_template_accepted"
        const val EVENT_TASK_TEMPLATES_BULK_CREATED = "task_templates_bulk_created"
    }
}
