package com.anypreta.bountyboard.data.model

import com.google.gson.annotations.SerializedName

// ---------------------------------------------------------------------------
// User
// ---------------------------------------------------------------------------

data class Roles(
    val admin: Boolean = false,
    val consultant: Boolean = false,
    val developer: Boolean = false,
)

data class Contact(
    val phone: String? = null,
    val location: String? = null,
    val links: List<String>? = null,
)

data class NotificationPrefs(
    val email: Boolean = true,
    val inApp: Boolean = true,
)

data class UserSettings(
    val theme: String? = "light",
    val navLayout: String? = "side",
    val notifications: NotificationPrefs? = null,
    val leaderboardOptOut: Boolean = false,
)

data class User(
    val id: String = "",
    val email: String = "",
    val name: String = "",
    val avatarFileId: String? = null,
    val bio: String? = null,
    val contact: Contact? = null,
    val extra: Map<String, Any?>? = null,
    val roles: Roles = Roles(),
    val settings: UserSettings? = null,
    val disabled: Boolean = false,
    val lastSeenAt: String? = null,
    val createdAt: String? = null,
    val updatedAt: String? = null,
    val version: Int = 0,
) {
    fun initials(): String {
        val parts = name.trim().split(Regex("\\s+")).filter { it.isNotEmpty() }
        return when {
            parts.isEmpty() -> email.take(1).uppercase()
            parts.size == 1 -> parts[0].take(2).uppercase()
            else -> (parts[0].take(1) + parts.last().take(1)).uppercase()
        }
    }

    fun roleLabel(): String = buildList {
        if (roles.admin) add("Admin")
        if (roles.consultant) add("Consultant")
        if (roles.developer) add("Developer")
    }.joinToString(" · ").ifEmpty { "User" }
}

// ---------------------------------------------------------------------------
// Customer (== "project")
// ---------------------------------------------------------------------------

data class Ticketing(
    val type: String = "demo",
    val baseUrl: String? = null,
    val projectKey: String? = null,
    val pollIntervalSec: Int = 60,
    val consultantIdentities: Map<String, String>? = null,
    val lastSyncAt: String? = null,
    val lastSyncStatus: String? = null,
    val lastSyncError: String? = null,
    val hasCredentials: Boolean = false,
)

data class Customer(
    val id: String = "",
    val name: String = "",
    val ticketing: Ticketing = Ticketing(),
    val consultantIds: List<String>? = null,
    val defaultBudget: Double = 0.0,
    val archived: Boolean = false,
    val createdAt: String? = null,
    val updatedAt: String? = null,
    val version: Int = 0,
)

/** Lightweight {id,name} used in board filter dropdowns. */
data class CustomerRef(
    val id: String = "",
    val name: String = "",
)

// ---------------------------------------------------------------------------
// Task
// ---------------------------------------------------------------------------

data class External(
    val system: String? = null,
    val key: String? = null,
    val url: String? = null,
    val type: String? = null,
    val orphaned: Boolean = false,
)

data class Assignee(
    val kind: String = "human",
    val userId: String? = null,
    val jobId: String? = null,
)

data class ClaimRequest(
    val developerId: String = "",
    val note: String? = null,
    val at: String? = null,
)

data class TaskAttachment(
    val name: String? = null,
    val url: String? = null,
    val mimeType: String? = null,
    val fileId: String? = null,
)

data class TimelineEntry(
    val at: String? = null,
    val actorId: String? = null,
    val event: String? = null,
    val data: Map<String, Any?>? = null,
)

data class Comment(
    val id: String = "",
    val authorId: String = "",
    val body: String = "",
    val at: String? = null,
)

data class TimeLogEntry(
    val developerId: String = "",
    val minutes: Int = 0,
    val note: String? = null,
    val at: String? = null,
)

data class Task(
    val id: String = "",
    val customerId: String = "",
    val consultantId: String = "",
    val origin: String = "imported",
    val parentId: String? = null,
    val rootId: String? = null,
    val external: External? = null,
    val title: String = "",
    val description: String = "",
    val acceptanceCriteria: List<String>? = null,
    val attachments: List<TaskAttachment>? = null,
    val links: List<String>? = null,
    val effortCoefficient: Double = 0.0,
    val budget: Double = 0.0,
    val bounty: Double = 0.0,
    val status: String = "imported",
    val assignee: Assignee? = null,
    val claimRequests: List<ClaimRequest>? = null,
    val atomizationNote: String? = null,
    val timeline: List<TimelineEntry>? = null,
    val comments: List<Comment>? = null,
    val timeLog: List<TimeLogEntry>? = null,
    val publishedAt: String? = null,
    val createdAt: String? = null,
    val updatedAt: String? = null,
    val version: Int = 0,
)

// ---------------------------------------------------------------------------
// Messaging
// ---------------------------------------------------------------------------

data class ConversationSummary(
    val id: String = "",
    val kind: String = "dm",
    val title: String? = null,
    val customerId: String? = null,
    val participantIds: List<String>? = null,
    val creatorId: String? = null,
    val lastMessageAt: String? = null,
    val unread: Int = 0,
)

data class Conversation(
    val id: String = "",
    val kind: String = "dm",
    val customerId: String? = null,
    val title: String? = null,
    val creatorId: String? = null,
    val participantIds: List<String>? = null,
    val lastMessageAt: String? = null,
    val createdAt: String? = null,
)

data class MessageAttachment(
    val fileId: String = "",
    val name: String? = null,
    val mimeType: String? = null,
    val size: Long = 0,
    val isImage: Boolean = false,
)

data class ReadReceipt(
    val userId: String = "",
    val at: String? = null,
)

data class Message(
    val id: String = "",
    val conversationId: String = "",
    val senderId: String = "",
    val body: String = "",
    val attachments: List<MessageAttachment>? = null,
    val readBy: List<ReadReceipt>? = null,
    val editedAt: String? = null,
    val deletedAt: String? = null,
)

// ---------------------------------------------------------------------------
// Notifications
// ---------------------------------------------------------------------------

data class Notification(
    val id: String = "",
    val userId: String = "",
    val kind: String = "",
    val title: String = "",
    val body: String = "",
    val link: String? = null,
    val readAt: String? = null,
    val createdAt: String? = null,
) {
    val isUnread: Boolean get() = readAt == null
}

// ---------------------------------------------------------------------------
// Misc shared
// ---------------------------------------------------------------------------

data class UserCard(
    val id: String = "",
    val name: String = "",
    val bio: String? = null,
    val roles: Roles = Roles(),
    val avatarFileId: String? = null,
    val contact: Contact? = null,
    val extra: Map<String, Any?>? = null,
)

data class PoolDeveloper(
    val id: String = "",
    val name: String = "",
    val email: String = "",
    val avatarFileId: String? = null,
    val inPool: Boolean = false,
    val bio: String? = null,
)

data class LeaderboardEntry(
    val developerId: String = "",
    val name: String = "",
    val avatarFileId: String? = null,
    val totalBounty: Double = 0.0,
    val tasksCompleted: Int = 0,
    val rank: Int = 0,
)

data class FileUploadResult(
    val fileId: String = "",
    val name: String = "",
    val mimeType: String = "",
    val size: Long = 0,
    val isImage: Boolean = false,
)

data class ServiceHealth(
    val atomizer: ServiceState? = null,
    val workPerformer: ServiceState? = null,
)

data class ServiceState(
    val healthy: Boolean = false,
    val breaker: String? = null,
    val latencyMs: Long = 0,
    val error: String? = null,
)

// ---------------------------------------------------------------------------
// Metrics (flexible — server returns rich aggregations)
// ---------------------------------------------------------------------------

data class MetricsSeriesPoint(
    val bucket: String = "",
    val amount: Double = 0.0,
    val count: Int = 0,
)

data class MetricsBreakdown(
    val key: String = "",
    val label: String = "",
    val totalBounty: Double = 0.0,
    val tasksCompleted: Int = 0,
)

data class Metrics(
    val totalBounty: Double = 0.0,
    val tasksCompleted: Int = 0,
    val approvalRate: Double = 0.0,
    val avgLeadTimeHours: Double = 0.0,
    val timeLoggedMinutes: Long = 0,
    val boardDepth: Int = 0,
    val series: List<MetricsSeriesPoint>? = null,
    val byCustomer: List<MetricsBreakdown>? = null,
    val byDeveloper: List<MetricsBreakdown>? = null,
)

data class AuditEntry(
    val id: String = "",
    val at: String? = null,
    val actorId: String? = null,
    val action: String = "",
    val entity: String = "",
    val entityId: String? = null,
    val diff: Map<String, Any?>? = null,
)
