import { sql } from "drizzle-orm";
import {
  datetime,
  index,
  int,
  mysqlTable,
  text,
  uniqueIndex,
  varchar,
} from "drizzle-orm/mysql-core";

const timestamp = (name: string) =>
  datetime(name, { mode: "string", fsp: 3 })
    .notNull()
    .default(sql`CURRENT_TIMESTAMP(3)`);

export const partners = mysqlTable("partners", {
  id: varchar("id", { length: 64 }).primaryKey(),
  name: varchar("name", { length: 255 }).notNull(),
  wecomName: varchar("wecom_name", { length: 255 }).notNull(),
  owner: varchar("owner", { length: 255 }).notNull().default("运营组"),
  claimedTotal: int("claimed_total").notNull().default(0),
  completedTotal: int("completed_total").notNull().default(0),
  createdAt: timestamp("created_at"),
});

export const tasks = mysqlTable(
  "tasks",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    name: varchar("name", { length: 255 }).notNull(),
    brand: varchar("brand", { length: 255 }).notNull(),
    quantity: int("quantity").notNull(),
    claimedQuantity: int("claimed_quantity").notNull().default(0),
    dueAt: varchar("due_at", { length: 32 }).notNull(),
    status: varchar("status", { length: 32 }).notNull().default("active"),
    taskType: varchar("task_type", { length: 32 })
      .notNull()
      .default("content_publish"),
    platform: varchar("platform", { length: 32 }).notNull().default("小红书"),
    contentFormat: varchar("content_format", { length: 32 })
      .notNull()
      .default("image_text"),
    sourceUrl: text("source_url").notNull(),
    sourceSheetId: varchar("source_sheet_id", { length: 255 }).notNull().default(""),
    sourceSheetName: varchar("source_sheet_name", { length: 255 }).notNull().default(""),
    sourceSyncedAt: datetime("source_synced_at", { mode: "string", fsp: 3 }),
    shareToken: varchar("share_token", { length: 128 }),
    collectionStartDate: varchar("collection_start_date", { length: 32 }),
    collectionDays: text("collection_days").notNull(),
    collectionScheduleUpdatedAt: datetime("collection_schedule_updated_at", {
      mode: "string",
      fsp: 3,
    }),
    createdAt: timestamp("created_at"),
  },
  (table) => [uniqueIndex("tasks_share_token_idx").on(table.shareToken)],
);

export const contents = mysqlTable("contents", {
  id: varchar("id", { length: 64 }).primaryKey(),
  taskId: varchar("task_id", { length: 64 }).notNull(),
  title: text("title").notNull(),
  body: text("body").notNull(),
  imageAssets: text("image_assets").notNull(),
  videoAssets: text("video_assets").notNull(),
  status: varchar("status", { length: 32 }).notNull().default("available"),
  source: varchar("source", { length: 255 }).notNull().default("飞书内容表"),
  sourceRow: int("source_row"),
  createdAt: timestamp("created_at"),
});

export const accounts = mysqlTable(
  "accounts",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    platform: varchar("platform", { length: 32 }).notNull().default("小红书"),
    platformUid: varchar("platform_uid", { length: 255 }).notNull(),
    publicAccountId: varchar("public_account_id", { length: 255 }).notNull().default(""),
    nickname: varchar("nickname", { length: 255 }).notNull(),
    profileUrl: text("profile_url").notNull(),
    ipLocation: varchar("ip_location", { length: 255 }).notNull().default("待识别"),
    followers: int("followers").notNull().default(0),
    gender: varchar("gender", { length: 16 }).notNull().default(""),
    bio: text("bio").notNull().default(""),
    tags: varchar("tags", { length: 500 }).notNull().default(""),
    postCount: int("post_count").notNull().default(0),
    avgViews: int("avg_views").notNull().default(0),
    cooperationSource: varchar("cooperation_source", { length: 500 })
      .notNull()
      .default(""),
    currentContact: varchar("current_contact", { length: 255 })
      .notNull()
      .default(""),
    firstSeenAt: timestamp("first_seen_at"),
    lastSeenAt: timestamp("last_seen_at"),
  },
  (table) => [
    uniqueIndex("accounts_platform_uid_idx").on(table.platform, table.platformUid),
  ],
);

export const claims = mysqlTable(
  "claims",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    taskId: varchar("task_id", { length: 64 }).notNull(),
    partnerId: varchar("partner_id", { length: 64 }).notNull(),
    claimantName: varchar("claimant_name", { length: 255 }).notNull(),
    claimToken: varchar("claim_token", { length: 128 }).notNull(),
    quantity: int("quantity").notNull(),
    createdAt: timestamp("created_at"),
  },
  (table) => [
    uniqueIndex("claims_claim_token_idx").on(table.claimToken),
    index("claims_task_partner_created_idx").on(
      table.taskId,
      table.partnerId,
      table.createdAt,
    ),
  ],
);

export const delegationBundles = mysqlTable(
  "delegation_bundles",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    taskId: varchar("task_id", { length: 64 }).notNull(),
    claimId: varchar("claim_id", { length: 64 }).notNull(),
    partnerId: varchar("partner_id", { length: 64 }).notNull(),
    label: varchar("label", { length: 255 }).notNull(),
    shareToken: varchar("share_token", { length: 128 }).notNull(),
    quantity: int("quantity").notNull(),
    status: varchar("status", { length: 32 }).notNull().default("active"),
    createdAt: timestamp("created_at"),
    updatedAt: timestamp("updated_at"),
    revokedAt: datetime("revoked_at", { mode: "string", fsp: 3 }),
  },
  (table) => [
    uniqueIndex("delegation_bundles_share_token_idx").on(table.shareToken),
    index("delegation_bundles_claim_created_idx").on(table.claimId, table.createdAt),
  ],
);

export const distributions = mysqlTable("distributions", {
  id: varchar("id", { length: 64 }).primaryKey(),
  taskId: varchar("task_id", { length: 64 }).notNull(),
  contentId: varchar("content_id", { length: 64 }).notNull(),
  partnerId: varchar("partner_id", { length: 64 }).notNull(),
  claimId: varchar("claim_id", { length: 64 }),
  delegationBundleId: varchar("delegation_bundle_id", { length: 64 }),
  accountId: varchar("account_id", { length: 64 }),
  publishUrl: text("publish_url"),
  publishTime: datetime("publish_time", { mode: "string", fsp: 3 }),
  publishScreenshotKey: varchar("publish_screenshot_key", { length: 512 }),
  resultScreenshotKey: text("result_screenshot_key"),
  resultSubmittedAt: datetime("result_submitted_at", { mode: "string", fsp: 3 }),
  status: varchar("status", { length: 32 }).notNull().default("claimed"),
  claimedAt: timestamp("claimed_at"),
  screenshotKey: varchar("screenshot_key", { length: 512 }),
  ocrStatus: varchar("ocr_status", { length: 32 }).notNull().default("none"),
  exposure: int("exposure"),
  views: int("views"),
  d2Likes: int("d2_likes"),
  d2Comments: int("d2_comments"),
  d2Collects: int("d2_collects"),
  d5Likes: int("d5_likes"),
  d5Comments: int("d5_comments"),
  d5Collects: int("d5_collects"),
  d7Likes: int("d7_likes"),
  d7Comments: int("d7_comments"),
  d7Collects: int("d7_collects"),
  latestLikes: int("latest_likes"),
  latestComments: int("latest_comments"),
  latestCollects: int("latest_collects"),
  latestShares: int("latest_shares"),
  collectionStatus: varchar("collection_status", { length: 32 })
    .notNull()
    .default("pending"),
  collectionStatusDescription: text("collection_status_description"),
  collectionUpdatedAt: datetime("collection_updated_at", { mode: "string", fsp: 3 }),
  lastCollectionDay: int("last_collection_day"),
  updatedAt: timestamp("updated_at"),
});

export const collectionRuns = mysqlTable(
  "collection_runs",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    taskId: varchar("task_id", { length: 64 }).notNull(),
    distributionId: varchar("distribution_id", { length: 64 }).notNull(),
    scheduledDate: varchar("scheduled_date", { length: 32 }).notNull(),
    scheduleDay: int("schedule_day"),
    scheduledAt: datetime("scheduled_at", { mode: "string", fsp: 3 }).notNull(),
    status: varchar("status", { length: 32 }).notNull().default("pending"),
    likes: int("likes"),
    comments: int("comments"),
    collects: int("collects"),
    shares: int("shares"),
    statusDescription: text("status_description"),
    startedAt: datetime("started_at", { mode: "string", fsp: 3 }),
    completedAt: datetime("completed_at", { mode: "string", fsp: 3 }),
    createdAt: timestamp("created_at"),
  },
  (table) => [
    uniqueIndex("collection_runs_distribution_date_idx").on(
      table.distributionId,
      table.scheduledDate,
    ),
    index("collection_runs_task_date_idx").on(table.taskId, table.scheduledDate),
  ],
);

export const users = mysqlTable(
  "users",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    username: varchar("username", { length: 255 }).notNull(),
    passwordHash: varchar("password_hash", { length: 255 }).notNull(),
    passwordSalt: varchar("password_salt", { length: 255 }).notNull(),
    passwordIterations: int("password_iterations").notNull(),
    role: varchar("role", { length: 32 }).notNull(),
    createdAt: timestamp("created_at"),
    updatedAt: timestamp("updated_at"),
  },
  (table) => [uniqueIndex("users_username_idx").on(table.username)],
);

export const authSessions = mysqlTable(
  "auth_sessions",
  {
    tokenHash: varchar("token_hash", { length: 128 }).primaryKey(),
    userId: varchar("user_id", { length: 64 }).notNull(),
    expiresAt: datetime("expires_at", { mode: "string", fsp: 3 }).notNull(),
    createdAt: timestamp("created_at"),
  },
  (table) => [
    index("auth_sessions_user_id_idx").on(table.userId),
    index("auth_sessions_expires_at_idx").on(table.expiresAt),
  ],
);

export const mcpExportTokens = mysqlTable(
  "mcp_export_tokens",
  {
    tokenHash: varchar("token_hash", { length: 128 }).primaryKey(),
    kind: varchar("kind", { length: 64 }).notNull(),
    payload: text("payload").notNull(),
    expiresAt: datetime("expires_at", { mode: "string", fsp: 3 }).notNull(),
    createdAt: timestamp("created_at"),
  },
  (table) => [index("mcp_export_tokens_expires_at_idx").on(table.expiresAt)],
);

export const backgroundJobs = mysqlTable(
  "background_jobs",
  {
    id: varchar("id", { length: 64 }).primaryKey(),
    type: varchar("type", { length: 64 }).notNull(),
    payload: text("payload").notNull(),
    status: varchar("status", { length: 32 }).notNull().default("pending"),
    attempts: int("attempts").notNull().default(0),
    availableAt: datetime("available_at", { mode: "string", fsp: 3 }).notNull(),
    lockedAt: datetime("locked_at", { mode: "string", fsp: 3 }),
    completedAt: datetime("completed_at", { mode: "string", fsp: 3 }),
    lastError: text("last_error"),
    createdAt: timestamp("created_at"),
    updatedAt: timestamp("updated_at"),
  },
  (table) => [index("background_jobs_pending_idx").on(table.status, table.availableAt)],
);
