const { DataTypes, Model } = require('sequelize')

/**
 * @typedef PodcastExpandedProperties
 * @property {import('./PodcastEpisode')[]} podcastEpisodes
 *
 * @typedef {Podcast & PodcastExpandedProperties} PodcastExpanded
 */

class Podcast extends Model {
  constructor(values, options) {
    super(values, options)

    /** @type {string} */
    this.id
    /** @type {string} */
    this.title
    /** @type {string} */
    this.titleIgnorePrefix
    /** @type {string} */
    this.author
    /** @type {string} */
    this.releaseDate
    /** @type {string} */
    this.feedURL
    /** @type {string} */
    this.imageURL
    /** @type {string} */
    this.description
    /** @type {string} */
    this.itunesPageURL
    /** @type {string} */
    this.itunesId
    /** @type {string} */
    this.itunesArtistId
    /** @type {string} */
    this.language
    /** @type {string} */
    this.podcastType
    /** @type {boolean} */
    this.explicit
    /** @type {boolean} */
    this.autoDownloadEpisodes
    /** @type {string} */
    this.autoDownloadSchedule
    /** @type {Date} */
    this.lastEpisodeCheck
    /** @type {number} */
    this.maxEpisodesToKeep
    /** @type {string} */
    this.coverPath
    /** @type {string[]} */
    this.tags
    /** @type {string[]} */
    this.genres
    /** @type {Date} */
    this.createdAt
    /** @type {Date} */
    this.updatedAt
  }

  static getOldPodcast(libraryItemExpanded) {
    const podcastExpanded = libraryItemExpanded.media
    const podcastEpisodes = podcastExpanded.podcastEpisodes?.map((ep) => ep.getOldPodcastEpisode(libraryItemExpanded.id).toJSON()).sort((a, b) => a.index - b.index)
    return {
      id: podcastExpanded.id,
      libraryItemId: libraryItemExpanded.id,
      metadata: {
        title: podcastExpanded.title,
        author: podcastExpanded.author,
        description: podcastExpanded.description,
        releaseDate: podcastExpanded.releaseDate,
        genres: podcastExpanded.genres,
        feedUrl: podcastExpanded.feedURL,
        imageUrl: podcastExpanded.imageURL,
        itunesPageUrl: podcastExpanded.itunesPageURL,
        itunesId: podcastExpanded.itunesId,
        itunesArtistId: podcastExpanded.itunesArtistId,
        explicit: podcastExpanded.explicit,
        language: podcastExpanded.language,
        type: podcastExpanded.podcastType
      },
      coverPath: podcastExpanded.coverPath,
      tags: podcastExpanded.tags,
      episodes: podcastEpisodes || [],
      autoDownloadEpisodes: podcastExpanded.autoDownloadEpisodes,
      autoDownloadSchedule: podcastExpanded.autoDownloadSchedule,
      lastEpisodeCheck: podcastExpanded.lastEpisodeCheck?.valueOf() || null,
      maxEpisodesToKeep: podcastExpanded.maxEpisodesToKeep,
      maxNewEpisodesToDownload: podcastExpanded.maxNewEpisodesToDownload
    }
  }

  static getFromOld(oldPodcast) {
    const oldPodcastMetadata = oldPodcast.metadata
    return {
      id: oldPodcast.id,
      title: oldPodcastMetadata.title,
      titleIgnorePrefix: oldPodcastMetadata.titleIgnorePrefix,
      author: oldPodcastMetadata.author,
      releaseDate: oldPodcastMetadata.releaseDate,
      feedURL: oldPodcastMetadata.feedUrl,
      imageURL: oldPodcastMetadata.imageUrl,
      description: oldPodcastMetadata.description,
      itunesPageURL: oldPodcastMetadata.itunesPageUrl,
      itunesId: oldPodcastMetadata.itunesId,
      itunesArtistId: oldPodcastMetadata.itunesArtistId,
      language: oldPodcastMetadata.language,
      podcastType: oldPodcastMetadata.type,
      explicit: !!oldPodcastMetadata.explicit,
      autoDownloadEpisodes: !!oldPodcast.autoDownloadEpisodes,
      autoDownloadSchedule: oldPodcast.autoDownloadSchedule,
      lastEpisodeCheck: oldPodcast.lastEpisodeCheck,
      maxEpisodesToKeep: oldPodcast.maxEpisodesToKeep,
      maxNewEpisodesToDownload: oldPodcast.maxNewEpisodesToDownload,
      coverPath: oldPodcast.coverPath,
      tags: oldPodcast.tags,
      genres: oldPodcastMetadata.genres
    }
  }

  getAbsMetadataJson() {
    return {
      tags: this.tags || [],
      title: this.title,
      author: this.author,
      description: this.description,
      releaseDate: this.releaseDate,
      genres: this.genres || [],
      feedURL: this.feedURL,
      imageURL: this.imageURL,
      itunesPageURL: this.itunesPageURL,
      itunesId: this.itunesId,
      itunesArtistId: this.itunesArtistId,
      language: this.language,
      explicit: !!this.explicit,
      podcastType: this.podcastType
    }
  }

  /**
   * Initialize model
   * @param {import('../Database').sequelize} sequelize
   */
  static init(sequelize) {
    super.init(
      {
        id: {
          type: DataTypes.UUID,
          defaultValue: DataTypes.UUIDV4,
          primaryKey: true
        },
        title: DataTypes.STRING,
        titleIgnorePrefix: DataTypes.STRING,
        author: DataTypes.STRING,
        releaseDate: DataTypes.STRING,
        feedURL: DataTypes.STRING,
        imageURL: DataTypes.STRING,
        description: DataTypes.TEXT,
        itunesPageURL: DataTypes.STRING,
        itunesId: DataTypes.STRING,
        itunesArtistId: DataTypes.STRING,
        language: DataTypes.STRING,
        podcastType: DataTypes.STRING,
        explicit: DataTypes.BOOLEAN,

        autoDownloadEpisodes: DataTypes.BOOLEAN,
        autoDownloadSchedule: DataTypes.STRING,
        lastEpisodeCheck: DataTypes.DATE,
        maxEpisodesToKeep: DataTypes.INTEGER,
        maxNewEpisodesToDownload: DataTypes.INTEGER,
        coverPath: DataTypes.STRING,
        tags: DataTypes.JSON,
        genres: DataTypes.JSON
      },
      {
        sequelize,
        modelName: 'podcast'
      }
    )
  }
}

module.exports = Podcast