const chalk = require('chalk')
const ora = require('ora')
const { getConfig } = require('../lib/config')
const { getPage, updatePage } = require('../lib/api')
const {
  resolvePageIdByLookup,
  metaTagsFromCliOptions,
  mergePageMetaTags,
  pagePutPayloadFromExisting,
  coerceAuditTimestampToUnixMs,
} = require('../lib/pages-cli')
const {
  normalizeContentSlug,
  isValidContentSlug,
  mergePageScheduleWithPublishedAt,
  parsePublishedAtMs,
} = require('../lib/blog-csv')

async function pagesUpdateCommand(options) {
  try {
    const appId = options.appId || getConfig('defaultAppId')
    if (!appId) {
      console.error(chalk.red('Error: App ID is required. Use --app-id or set defaultAppId in bild.json.'))
      process.exit(1)
    }

    const pageIdOpt = options.pageId != null ? String(options.pageId).trim() : ''
    const slugOpt = options.slug != null ? String(options.slug).trim() : ''
    if (!pageIdOpt && !slugOpt) {
      console.error(chalk.red('Error: provide --page-id or --slug (page URL slug) to select the page.'))
      process.exit(1)
    }

    if (options.draft && options.publish) {
      console.error(chalk.red('Error: use either --draft or --publish, not both.'))
      process.exit(1)
    }

    const publishedAtOpt = options.publishedAt != null ? String(options.publishedAt).trim() : ''
    const clearPublishedAt = options.clearPublishedAt === true
    const createdAtOpt = options.createdAt != null ? String(options.createdAt).trim() : ''
    if (clearPublishedAt && publishedAtOpt) {
      console.error(chalk.red('Error: use either --clear-published-at or --published-at, not both.'))
      process.exit(1)
    }
    if (clearPublishedAt && createdAtOpt) {
      console.error(chalk.red('Error: use either --clear-published-at or --created-at, not both.'))
      process.exit(1)
    }

    const spinner = ora('Updating page…').start()
    try {
      const pid = await resolvePageIdByLookup({
        appId,
        pageId: pageIdOpt || undefined,
        slug: slugOpt || undefined,
      })

      const existing = await getPage(appId, pid)
      if (!existing || typeof existing !== 'object') {
        throw new Error('Could not load page from CMS')
      }

      /** @type {Record<string, unknown>} */
      const body = pagePutPayloadFromExisting(existing)

      if (options.newSlug != null && String(options.newSlug).trim() !== '') {
        const ns = normalizeContentSlug(options.newSlug)
        if (!isValidContentSlug(ns)) {
          throw new Error(`Invalid --new-slug "${options.newSlug}" → "${ns}"`)
        }
        body.slug = ns
      }

      if (options.name != null && String(options.name).trim() !== '') {
        body.name = String(options.name).trim()
      }

      if (options.contentId != null && String(options.contentId).trim() !== '') {
        body.contentId = String(options.contentId).trim()
      }

      if (options.draft) body.published = false
      else if (options.publish) body.published = true

      if (options.archived === true) body.archived = true
      if (options.unarchived === true) body.archived = false

      if (options.previewDescription !== undefined) {
        const p = String(options.previewDescription).trim()
        if (p) body.previewDescription = p
        else delete body.previewDescription
      }

      const patchMeta = metaTagsFromCliOptions(options)
      if (patchMeta) {
        body.metaTags = mergePageMetaTags(body.metaTags, patchMeta)
      }

      if (clearPublishedAt) {
        delete body.schedule
      } else if (publishedAtOpt) {
        body.schedule = mergePageScheduleWithPublishedAt(existing.schedule, publishedAtOpt)
      }

      if (createdAtOpt) {
        const updatedEcho = coerceAuditTimestampToUnixMs(existing, 'updatedAt', 'updated_at')
        if (updatedEcho != null) body.updatedAt = updatedEcho
        body.createdAt = parsePublishedAtMs(createdAtOpt)
      }

      await updatePage(appId, pid, body)
      spinner.succeed(chalk.green(`Updated page ${pid}${body.slug ? ` (${body.slug})` : ''}`))
    } catch (e) {
      spinner.fail(e.message || String(e))
      process.exit(1)
    }
  } catch (e) {
    console.error(chalk.red(e.message || String(e)))
    process.exit(1)
  }
}

module.exports = pagesUpdateCommand
