package migrations

import (
	"context"
	"database/sql"
	"encoding/json"

	"github.com/navidrome/navidrome/model"
	"github.com/pressly/goose/v3"
)

func init() {
	goose.AddMigrationContext(upAlterLyricColumn, downAlterLyricColumn)
}

func upAlterLyricColumn(ctx context.Context, tx *sql.Tx) error {
	_, err := tx.ExecContext(ctx, `alter table media_file rename COLUMN lyrics TO lyrics_old`)
	if err != nil {
		return err
	}

	_, err = tx.ExecContext(ctx, `alter table media_file add lyrics JSONB default '[]';`)
	if err != nil {
		return err
	}

	stmt, err := tx.Prepare(`update media_file SET lyrics = ? where id = ?`)
	if err != nil {
		return err
	}

	rows, err := tx.QueryContext(ctx, `select id, lyrics_old FROM media_file WHERE lyrics_old <> '';`)
	if err != nil {
		return err
	}

	var id string
	var lyrics sql.NullString
	for rows.Next() {
		err = rows.Scan(&id, &lyrics)
		if err != nil {
			return err
		}

		if !lyrics.Valid {
			continue
		}

		parsed, err := model.ParseLyrics(ctx, ".lrc", "xxx", []byte(lyrics.String))
		if err != nil {
			return err
		}

		text, err := json.Marshal(parsed)
		if err != nil {
			return err
		}

		_, err = stmt.Exec(string(text), id)
		if err != nil {
			return err
		}
	}

	err = rows.Err()
	if err != nil {
		return err
	}

	_, err = tx.ExecContext(ctx, `ALTER TABLE media_file DROP COLUMN lyrics_old;`)
	if err != nil {
		return err
	}

	notice(ctx, tx, "A full rescan should be performed to pick up additional lyrics (existing lyrics have been preserved)")
	return nil
}

func downAlterLyricColumn(ctx context.Context, tx *sql.Tx) error {
	// This code is executed when the migration is rolled back.
	return nil
}
