import { int, mysqlEnum, mysqlTable, text, timestamp, varchar, tinyint } from "drizzle-orm/mysql-core";
import { relations } from "drizzle-orm";

/**
 * Core user table backing auth flow.
 */
export const users = mysqlTable("users", {
  id: int("id").autoincrement().primaryKey(),
  openId: varchar("openId", { length: 64 }).notNull().unique(),
  name: varchar("name", { length: 255 }),
  email: varchar("email", { length: 320 }).unique(),
  password: varchar("password", { length: 255 }),
  loginMethod: varchar("loginMethod", { length: 64 }).default("local"),
  role: mysqlEnum("role", ["user", "admin", "editor", "operator", "analyst"]).default("user").notNull(),
  createdAt: timestamp("createdAt").defaultNow().notNull(),
  updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
  lastSignedIn: timestamp("lastSignedIn").defaultNow().notNull(),
});

/**
 * Podcast tables
 */
export const podcastApresentadores = mysqlTable("podcast_apresentadores", {
  id: int("id").autoincrement().primaryKey(),
  nome: varchar("nome", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  bio: text("bio"),
  foto: varchar("foto", { length: 500 }),
  reproducoes: int("reproducoes").default(0),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const podcastProgramas = mysqlTable("podcast_programas", {
  id: int("id").autoincrement().primaryKey(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  descricao: text("descricao"),
  capa: varchar("capa", { length: 500 }),
  ano: int("ano"),
  genero: varchar("genero", { length: 100 }),
  categoria: varchar("categoria", { length: 100 }).default("podcast"),
  apresentadorId: int("apresentador_id"),
  status: mysqlEnum("status", ["rascunho", "publicado", "arquivado"]).default("publicado"),
  configAutodj: tinyint("config_autodj").default(1),
  configSequencial: tinyint("config_sequencial").default(1),
  configVinheta: tinyint("config_vinheta").default(0),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const podcastEpisodios = mysqlTable("podcast_episodios", {
  id: int("id").autoincrement().primaryKey(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  descricao: text("descricao"),
  arquivo: varchar("arquivo", { length: 500 }),
  // HUB-INTEGRATION-POINT (Fase 3/4): tipoMidia e videoUrl são a base
  // para suporte a rádio (stream) e audiolivros (audio_video com capítulos).
  // Quando PlayableItem (Fase 1) for implementado, estes campos alimentam
  // o kind e streamUrl do tipo genérico.
  tipoMidia: mysqlEnum("tipo_midia", ["audio", "video", "audio_video"]).default("audio").notNull(),
  videoUrl: varchar("video_url", { length: 500 }),
  capa: varchar("capa", { length: 500 }),
  duracao: int("duracao"),
  reproducoes: int("reproducoes").default(0),
  numeroEpisodio: int("numero_episodio"),
  ordem: int("ordem").default(0),
  tags: text("tags"),
  transcricao: text("transcricao"),
  apresentadorId: int("apresentador_id"),
  programaId: int("programa_id"),
  status: mysqlEnum("status", ["rascunho", "publicado", "agendado"]).default("publicado"),
  dataPublicacao: timestamp("data_publicacao").defaultNow(),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const podcastVinhetas = mysqlTable("podcast_vinhetas", {
  id: int("id").autoincrement().primaryKey(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  arquivo: varchar("arquivo", { length: 500 }).notNull(),
  categoria: mysqlEnum("categoria", ["abertura", "transicao", "encerramento"]).default("transicao"),
  ativo: tinyint("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
});

/**
 * User-specific podcast tables
 */
export const userFavoritos = mysqlTable("user_favoritos", {
  id: int("id").autoincrement().primaryKey(),
  userId: int("user_id").notNull(),
  episodioId: int("episodio_id").notNull(),
  criadoEm: timestamp("criado_em").defaultNow(),
});

export const userHistorico = mysqlTable("user_historico", {
  id: int("id").autoincrement().primaryKey(),
  userId: int("user_id").notNull(),
  episodioId: int("episodio_id").notNull(),
  tocadoEm: timestamp("tocado_em").defaultNow(),
});

export const userPlaylists = mysqlTable("user_playlists", {
  id: int("id").autoincrement().primaryKey(),
  userId: int("user_id").notNull(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  descricao: text("descricao"),
  capa: varchar("capa", { length: 500 }),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const userPlaylistItems = mysqlTable("user_playlist_items", {
  id: int("id").autoincrement().primaryKey(),
  playlistId: int("playlist_id").notNull(),
  episodioId: int("episodio_id").notNull(),
  ordem: int("ordem").default(0),
  adicionadoEm: timestamp("adicionado_em").defaultNow(),
});

// Relations
export const podcastProgramasRelations = relations(podcastProgramas, ({ one, many }) => ({
  apresentador: one(podcastApresentadores, {
    fields: [podcastProgramas.apresentadorId],
    references: [podcastApresentadores.id],
  }),
  episodios: many(podcastEpisodios),
}));

export const podcastEpisodiosRelations = relations(podcastEpisodios, ({ one }) => ({
  programa: one(podcastProgramas, {
    fields: [podcastEpisodios.programaId],
    references: [podcastProgramas.id],
  }),
  apresentador: one(podcastApresentadores, {
    fields: [podcastEpisodios.apresentadorId],
    references: [podcastApresentadores.id],
  }),
}));

export type User = typeof users.$inferSelect;
export type InsertUser = typeof users.$inferInsert;
export type PodcastEpisodio = typeof podcastEpisodios.$inferSelect;
export type PodcastApresentador = typeof podcastApresentadores.$inferSelect;
export type PodcastPrograma = typeof podcastProgramas.$inferSelect;
export type PodcastVinheta = typeof podcastVinhetas.$inferSelect;
export type UserFavorito = typeof userFavoritos.$inferSelect;
export type UserHistorico = typeof userHistorico.$inferSelect;
export type UserPlaylist = typeof userPlaylists.$inferSelect;
export type UserPlaylistItem = typeof userPlaylistItems.$inferSelect;

/**
 * Música tables (Fase 2)
 *
 * Espelha exatamente a convenção de podcast_apresentadores / podcast_programas /
 * podcast_episodios (ADR-003: tabelas paralelas por módulo, nunca polimorfismo).
 * musica_artistas   ~ podcast_apresentadores
 * musica_albuns     ~ podcast_programas (agrupador)
 * musica_faixas     ~ podcast_episodios (conteúdo reproduzível)
 */

export const musicaArtistas = mysqlTable("musica_artistas", {
  id: int("id").autoincrement().primaryKey(),
  nome: varchar("nome", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  bio: text("bio"),
  foto: varchar("foto", { length: 500 }),
  reproducoes: int("reproducoes").default(0),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const musicaAlbuns = mysqlTable("musica_albuns", {
  id: int("id").autoincrement().primaryKey(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  descricao: text("descricao"),
  capa: varchar("capa", { length: 500 }),
  anoLancamento: int("ano_lancamento"),
  genero: varchar("genero", { length: 100 }),
  artistaId: int("artista_id"),
  status: mysqlEnum("status", ["rascunho", "publicado", "arquivado"]).default("publicado"),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

export const musicaFaixas = mysqlTable("musica_faixas", {
  id: int("id").autoincrement().primaryKey(),
  titulo: varchar("titulo", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  descricao: text("descricao"),
  arquivo: varchar("arquivo", { length: 500 }),
  // HUB-INTEGRATION-POINT (Fase 3): mesmo padrão de tipoMidia usado em
  // podcast_episodios — mantém a porta aberta para versões com vídeo
  // (clipes) sem precisar de nova tabela.
  tipoMidia: mysqlEnum("tipo_midia", ["audio", "video", "audio_video"]).default("audio").notNull(),
  videoUrl: varchar("video_url", { length: 500 }),
  capa: varchar("capa", { length: 500 }),
  duracao: int("duracao"),
  reproducoes: int("reproducoes").default(0),
  numeroFaixa: int("numero_faixa"),
  ordem: int("ordem").default(0),
  letra: text("letra"),
  tags: text("tags"),
  artistaId: int("artista_id"),
  albumId: int("album_id"),
  status: mysqlEnum("status", ["rascunho", "publicado", "agendado"]).default("publicado"),
  dataPublicacao: timestamp("data_publicacao").defaultNow(),
  ativo: int("ativo").default(1),
  criadoEm: timestamp("criado_em").defaultNow(),
  atualizadoEm: timestamp("atualizado_em").defaultNow().onUpdateNow(),
});

/**
 * Biblioteca do usuário — Música (ADR-003: paralelas às tabelas de Podcast,
 * nunca reaproveitando user_favoritos/user_historico/user_playlist_items
 * como polimórficas)
 */
export const userFavoritosMusica = mysqlTable("user_favoritos_musica", {
  id: int("id").autoincrement().primaryKey(),
  userId: int("user_id").notNull(),
  faixaId: int("faixa_id").notNull(),
  criadoEm: timestamp("criado_em").defaultNow(),
});

export const userHistoricoMusica = mysqlTable("user_historico_musica", {
  id: int("id").autoincrement().primaryKey(),
  userId: int("user_id").notNull(),
  faixaId: int("faixa_id").notNull(),
  tocadoEm: timestamp("tocado_em").defaultNow(),
});

// user_playlists (o container) já é genérico — sem menção a tipo de mídia.
// Só os ITENS de playlist são hoje amarrados a episodioId (user_playlist_items).
// Esta tabela paralela permite que uma playlist tenha faixas de música,
// usando o mesmo playlistId — sem tornar user_playlist_items polimórfica.
export const userPlaylistItemsMusica = mysqlTable("user_playlist_items_musica", {
  id: int("id").autoincrement().primaryKey(),
  playlistId: int("playlist_id").notNull(),
  faixaId: int("faixa_id").notNull(),
  ordem: int("ordem").default(0),
  adicionadoEm: timestamp("adicionado_em").defaultNow(),
});

// Relations — Música
export const musicaAlbunsRelations = relations(musicaAlbuns, ({ one, many }) => ({
  artista: one(musicaArtistas, {
    fields: [musicaAlbuns.artistaId],
    references: [musicaArtistas.id],
  }),
  faixas: many(musicaFaixas),
}));

export const musicaFaixasRelations = relations(musicaFaixas, ({ one }) => ({
  album: one(musicaAlbuns, {
    fields: [musicaFaixas.albumId],
    references: [musicaAlbuns.id],
  }),
  artista: one(musicaArtistas, {
    fields: [musicaFaixas.artistaId],
    references: [musicaArtistas.id],
  }),
}));

export type MusicaArtista = typeof musicaArtistas.$inferSelect;
export type MusicaAlbum = typeof musicaAlbuns.$inferSelect;
export type MusicaFaixa = typeof musicaFaixas.$inferSelect;
export type UserFavoritoMusica = typeof userFavoritosMusica.$inferSelect;
export type UserHistoricoMusica = typeof userHistoricoMusica.$inferSelect;
export type UserPlaylistItemMusica = typeof userPlaylistItemsMusica.$inferSelect;