package com.anypreta.bountyboard.data.net

import com.anypreta.bountyboard.data.model.AuditEntry
import com.anypreta.bountyboard.data.model.Comment
import com.anypreta.bountyboard.data.model.Conversation
import com.anypreta.bountyboard.data.model.ConversationSummary
import com.anypreta.bountyboard.data.model.Customer
import com.anypreta.bountyboard.data.model.CustomerRef
import com.anypreta.bountyboard.data.model.LeaderboardEntry
import com.anypreta.bountyboard.data.model.Message
import com.anypreta.bountyboard.data.model.Notification
import com.anypreta.bountyboard.data.model.PoolDeveloper
import com.anypreta.bountyboard.data.model.Task
import com.anypreta.bountyboard.data.model.TimeLogEntry
import com.anypreta.bountyboard.data.model.User
import com.anypreta.bountyboard.data.model.UserCard
import com.google.gson.JsonObject

// ---- Auth ----
data class LoginRequest(val email: String, val password: String)
data class RegisterRequest(val email: String, val name: String, val password: String)
data class ChangePasswordRequest(val currentPassword: String, val newPassword: String)
data class ForgotRequest(val email: String)
data class ResetRequest(val token: String, val newPassword: String)

data class AuthResponse(
    val user: User = User(),
    val mustChangePassword: Boolean = false,
    val oidcEnabled: Boolean = false,
)

data class RevokedResponse(val revoked: Int = 0)

// ---- Board / tasks ----
data class BoardResponse(
    val tasks: List<Task> = emptyList(),
    val customers: List<CustomerRef> = emptyList(),
)

data class MyTasksResponse(val tasks: List<Task> = emptyList())

data class ConsultantBoardResponse(
    val customers: List<Customer> = emptyList(),
    val tasks: List<Task> = emptyList(),
)

data class TaskResponse(val task: Task = Task())
data class TasksResponse(val tasks: List<Task> = emptyList())
data class CommentResponse(val comment: Comment = Comment())
data class TimeEntryResponse(val entry: TimeLogEntry = TimeLogEntry())
data class JobResponse(val jobId: String = "")
data class BulkResult(val published: Int = 0, val archived: Int = 0, val failed: List<String> = emptyList())

// ---- Task mutation bodies ----
data class ClaimBody(val note: String? = null)
data class CommentBody(val body: String)
data class TimeBody(val minutes: Int, val note: String? = null)
data class ApproveClaimBody(val developerId: String)
data class DeclineClaimBody(val developerId: String)
data class ChecklistItem(val criterion: String, val ok: Boolean)
data class ReviewBody(val decision: String, val note: String? = null, val checklist: List<ChecklistItem>? = null)
data class SubdivideConstraints(val minTasks: Int? = null, val maxTasks: Int? = null)
data class SubdivideBody(val note: String? = null, val constraints: SubdivideConstraints? = null, val confirmReplace: Boolean? = null)
data class ExtendBody(val note: String)
data class AssignAiContext(val repositoryUrl: String? = null, val branch: String? = null, val instructions: String? = null)
data class AssignAiBody(val context: AssignAiContext? = null)
data class IdsBody(val ids: List<String>)
data class TaskPatchBody(
    val title: String? = null,
    val description: String? = null,
    val acceptanceCriteria: List<String>? = null,
    val effortCoefficient: Double? = null,
    val budget: Double? = null,
    val cascadeBudget: Boolean? = null,
    val version: Int,
)

// ---- Messaging ----
data class ConversationsResponse(val conversations: List<ConversationSummary> = emptyList())
data class ConversationResponse(val conversation: Conversation = Conversation())
data class MessagesResponse(val messages: List<Message> = emptyList())
data class MessageResponse(val message: Message = Message())
data class MarkedResponse(val marked: Int = 0)
data class CreateConversationBody(
    val kind: String,
    val title: String? = null,
    val customerId: String? = null,
    val participantIds: List<String> = emptyList(),
)
data class SendMessageBody(val body: String, val attachments: List<String> = emptyList())

// ---- Notifications ----
data class NotificationsResponse(
    val notifications: List<Notification> = emptyList(),
    val unread: Long = 0,
)
data class NotificationsReadBody(val ids: List<String> = emptyList())

// ---- Shared / directory ----
data class UsersResponse(val users: List<User> = emptyList(), val nextCursor: String? = null)
data class UserResponse(val user: User = User())
data class CardResponse(val card: UserCard = UserCard())
data class LeaderboardResponse(
    val leaderboard: List<LeaderboardEntry>? = null,
    val entries: List<LeaderboardEntry>? = null,
) {
    fun items(): List<LeaderboardEntry> = leaderboard ?: entries ?: emptyList()
}

// ---- Consultant pool ----
data class PoolResponse(val developers: List<PoolDeveloper> = emptyList())
data class PoolAddBody(val developerId: String)

// ---- Admin ----
data class CustomersResponse(val customers: List<Customer> = emptyList(), val nextCursor: String? = null)
data class CustomerResponse(val customer: Customer = Customer())
data class TestConnectionResult(val ok: Boolean = false, val latencyMs: Long = 0, val error: String? = null)
data class AuditResponse(val entries: List<AuditEntry> = emptyList(), val nextCursor: String? = null)
data class CustomerBody(
    val name: String? = null,
    val type: String? = null,
    val baseUrl: String? = null,
    val projectKey: String? = null,
    val pollIntervalSec: Int? = null,
    val defaultBudget: Double? = null,
    val consultantIds: List<String>? = null,
    val credentials: Map<String, String>? = null,
    val archived: Boolean? = null,
    val version: Int? = null,
)

// ---- Profile ----
data class ProfilePatchBody(
    val name: String? = null,
    val bio: String? = null,
    val contact: com.anypreta.bountyboard.data.model.Contact? = null,
    val extra: Map<String, Any?>? = null,
    val settings: ProfileSettingsPatch? = null,
    val version: Int? = null,
)
data class ProfileSettingsPatch(
    val theme: String? = null,
    val navLayout: String? = null,
    val leaderboardOptOut: Boolean? = null,
)
data class AvatarResponse(val fileId: String = "")

/** Generic error envelope: {"error":{"code","message"}}. */
data class ApiErrorEnvelope(val error: ApiErrorBody? = null)
data class ApiErrorBody(val code: String = "", val message: String = "")

/** Loosely-typed payloads (settings, service-status, metrics). */
typealias JsonMap = JsonObject
