use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};

/// 插件数据记录响应
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct PluginDataResp {
    pub id: String,
    pub data: serde_json::Value,
    pub created_at: Option<DateTime<Utc>>,
    pub updated_at: Option<DateTime<Utc>>,
    pub version: Option<i32>,
}

/// 创建插件数据请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct CreatePluginDataReq {
    pub data: serde_json::Value,
}

/// 更新插件数据请求（全量替换）
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UpdatePluginDataReq {
    pub data: serde_json::Value,
    pub version: i32,
}

/// 部分更新请求（PATCH — 只合并提供的字段）
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct PatchPluginDataReq {
    pub data: serde_json::Value,
    pub version: i32,
}

/// 插件数据列表查询参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct PluginDataListParams {
    pub page: Option<u64>,
    pub page_size: Option<u64>,
    /// Base64 编码的游标（用于 Keyset 分页）
    pub cursor: Option<String>,
    pub search: Option<String>,
    /// JSON 格式过滤: {"field":"value"}
    pub filter: Option<String>,
    pub sort_by: Option<String>,
    /// "asc" or "desc"
    pub sort_order: Option<String>,
}

/// 聚合查询响应项
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct AggregateItem {
    /// 分组键（字段值）
    pub key: String,
    /// 计数
    pub count: i64,
}

/// 多聚合查询响应项
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct AggregateMultiRow {
    /// 分组键
    pub key: String,
    /// 计数
    pub count: i64,
    /// 聚合指标: {"sum_amount": 5000.0, "avg_price": 25.5}
    #[serde(default)]
    pub metrics: std::collections::HashMap<String, f64>,
}

/// 聚合查询参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct AggregateQueryParams {
    /// 分组字段名
    pub group_by: String,
    /// JSON 格式过滤: {"field":"value"}
    pub filter: Option<String>,
}

/// 多聚合查询请求体
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct AggregateMultiReq {
    /// 分组字段名
    pub group_by: String,
    /// 聚合定义列表: [{"func": "sum", "field": "amount"}]
    pub aggregations: Vec<AggregateDefDto>,
    /// JSON 格式过滤
    pub filter: Option<serde_json::Value>,
}

/// 单个聚合定义
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct AggregateDefDto {
    /// 聚合函数: count, sum, avg, min, max
    pub func: String,
    /// 字段名
    pub field: String,
}

/// 统计查询参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct CountQueryParams {
    /// 搜索关键词
    pub search: Option<String>,
    /// JSON 格式过滤: {"field":"value"}
    pub filter: Option<String>,
}

/// 批量操作请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct BatchActionReq {
    /// 操作类型: "batch_delete" 或 "batch_update"
    pub action: String,
    /// 记录 ID 列表（上限 100）
    pub ids: Vec<String>,
    /// batch_update 时的更新数据
    pub data: Option<serde_json::Value>,
}

/// 时间序列查询参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct TimeseriesParams {
    /// 时间字段名
    pub time_field: String,
    /// 时间粒度: "day" / "week" / "month"
    pub time_grain: String,
    /// 开始日期 (ISO)
    pub start: Option<String>,
    /// 结束日期 (ISO)
    pub end: Option<String>,
}

/// 时间序列数据项
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct TimeseriesItem {
    /// 时间周期
    pub period: String,
    /// 计数
    pub count: i64,
}

// ─── 跨插件引用 DTO ──────────────────────────────────────────────────

/// 批量标签解析请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ResolveLabelsReq {
    /// 字段名 → UUID 列表
    pub fields: std::collections::HashMap<String, Vec<String>>,
}

/// 批量标签解析响应
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ResolveLabelsResp {
    /// 字段名 → { uuid: label } 映射
    pub labels: serde_json::Value,
    /// 字段名 → 目标插件元信息
    pub meta: serde_json::Value,
}

/// 公开实体信息（实体注册表查询响应）
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct PublicEntityResp {
    pub manifest_id: String,
    pub plugin_id: String,
    pub entity_name: String,
    pub display_name: String,
}

// ─── 导入导出 DTO ──────────────────────────────────────────────────

/// 数据导出参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct ExportParams {
    /// JSON 格式过滤: {"field":"value"}
    pub filter: Option<String>,
    /// 搜索关键词
    pub search: Option<String>,
    /// 排序字段
    pub sort_by: Option<String>,
    /// "asc" or "desc"
    pub sort_order: Option<String>,
    /// 导出格式: "json" (默认) | "csv" | "xlsx"
    pub format: Option<String>,
}

/// 导出结果 — 根据格式返回不同内容
pub enum ExportPayload {
    Json(Vec<serde_json::Value>),
    Csv(Vec<u8>),
    Xlsx(Vec<u8>),
}

/// 数据导入请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ImportReq {
    /// 导入数据行列表，每行是一个 JSON 对象
    pub rows: Vec<serde_json::Value>,
}

/// 数据导入结果
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ImportResult {
    /// 成功导入行数
    pub success_count: usize,
    /// 失败行数
    pub error_count: usize,
    /// 每行错误详情: [{ row: 0, errors: ["字段 xxx 必填"] }]
    #[serde(default)]
    pub errors: Vec<ImportRowError>,
}

/// 单行导入错误
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ImportRowError {
    /// 行号（0-based）
    pub row: usize,
    /// 错误消息列表
    pub errors: Vec<String>,
}

// ─── 市场目录 DTO ──────────────────────────────────────────────────

/// 市场条目列表查询参数
#[derive(Debug, Serialize, Deserialize, IntoParams)]
pub struct MarketListParams {
    pub page: Option<u64>,
    pub page_size: Option<u64>,
    pub category: Option<String>,
    pub search: Option<String>,
}

/// 市场条目响应（不含二进制数据）
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct MarketEntryResp {
    pub id: String,
    pub plugin_id: String,
    pub name: String,
    pub version: String,
    pub description: Option<String>,
    pub author: Option<String>,
    pub category: Option<String>,
    pub tags: Option<serde_json::Value>,
    pub icon_url: Option<String>,
    pub screenshots: Option<serde_json::Value>,
    pub min_platform_version: Option<String>,
    pub status: String,
    pub download_count: i32,
    pub rating_avg: f64,
    pub rating_count: i32,
    pub changelog: Option<String>,
    pub created_at: Option<chrono::DateTime<chrono::Utc>>,
    pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
}

/// 市场条目详情响应（含完整信息）
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct MarketEntryDetailResp {
    #[serde(flatten)]
    pub entry: MarketEntryResp,
    /// 依赖提示（安装时检查 manifest.dependencies）
    pub dependency_warnings: Vec<String>,
}

/// 提交评分/评论请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct SubmitReviewReq {
    /// 评分 1-5
    pub rating: i32,
    /// 评论内容
    pub review_text: Option<String>,
}

/// 评论响应
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct MarketReviewResp {
    pub id: String,
    pub user_id: String,
    pub market_entry_id: String,
    pub rating: i32,
    pub review_text: Option<String>,
    pub created_at: Option<chrono::DateTime<chrono::Utc>>,
}

// ─── 对账扫描 DTO ──────────────────────────────────────────────────

/// 对账报告
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ReconciliationReport {
    /// 有效引用数
    pub valid_count: i64,
    /// 悬空引用数
    pub dangling_count: i64,
    /// 悬空引用详情
    pub details: Vec<DanglingRef>,
}

/// 悬空引用详情
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct DanglingRef {
    /// 实体名
    pub entity: String,
    /// 字段名
    pub field: String,
    /// 记录 ID
    pub record_id: String,
    /// 悬空的 UUID 值
    pub dangling_value: String,
}

// ─── 自定义视图 DTO ──────────────────────────────────────────────────

/// 用户视图配置请求
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UserViewReq {
    pub view_name: String,
    pub view_config: serde_json::Value,
    pub is_default: Option<bool>,
}

/// 用户视图响应
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UserViewResp {
    pub id: String,
    pub plugin_id: String,
    pub entity_name: String,
    pub view_name: String,
    pub view_config: serde_json::Value,
    pub is_default: bool,
    pub created_at: Option<chrono::DateTime<chrono::Utc>>,
    pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
}
