package migrations

import (
	"errors"
	"fmt"

	"github.com/pocketbase/pocketbase/core"
)

// up202608140003 запрещает пустого владельца у аудиозаписи и у её файла.
//
// Прежде пустое значение допускалось, и цену за это платили записи, принятые
// ботом: связи чата Telegram с учётной записью сервис не вёл, и владельца у них
// не было вовсе. Вход Telegram убран, заводить ничью запись стало некому, и
// обязательность переезжает из приёма в схему — туда, где её держит хранилище, а
// не договорённость. Разница не косметическая: пока обязательность жила в
// приёме, ничью запись заводили руками в панели, она уходила в конвейер, стоила
// денег на распознавание и не доставалась потом никому.
//
// Существующих строк шаг **не смотрит**, и это проверено прогоном: хранилище
// держит обязательность связи проверкой записи при сохранении, а не ограничением
// таблицы, поэтому смена признака на базе с ничьей записью проходит зелёным и
// такую запись оставляет. Искать ничьи строки надо до выкладки и запросом —
// `SELECT count(*) FROM audio_records WHERE owner = ”` и то же по `files`;
// прогон самого шага на копии этого не показывает.
//
// Оставленная ничья запись становится незакрываемой: захват идёт сырым запросом
// мимо проверки и выдаёт её воркеру, а всякое сохранение — включая то, которым
// ставится признак остановки, — отказывает. Порядок выкладки поэтому начинается
// с проверки данных, а не с прогона шага.
func up202608140003(app core.App) error {
	for _, name := range []string{RecordsCollection, FilesCollection} {
		if err := setOwnerRequired(app, name, true); err != nil {
			return err
		}
	}
	return nil
}

// down202608140003 возвращает колонке необязательность. Записей это не касается:
// пустых значений среди них нет, а появиться им теперь неоткуда.
func down202608140003(app core.App) error {
	for _, name := range []string{RecordsCollection, FilesCollection} {
		if err := setOwnerRequired(app, name, false); err != nil {
			return err
		}
	}
	return nil
}

// setOwnerRequired правит признак обязательности у колонки владельца одной
// коллекции. Колонка ищется по имени и приводится к типу связи: шаг, молча
// пропустивший чужой тип, оставил бы схему в состоянии, о котором никто не
// узнает.
func setOwnerRequired(app core.App, collectionName string, required bool) error {
	collection, err := app.FindCollectionByNameOrId(collectionName)
	if err != nil {
		return fmt.Errorf("failed to find collection %s: %w", collectionName, err)
	}

	field := collection.Fields.GetByName("owner")
	if field == nil {
		return errors.New("collection " + collectionName + " has no owner field")
	}

	relation, ok := field.(*core.RelationField)
	if !ok {
		return errors.New("owner field of collection " + collectionName + " is not a relation")
	}

	relation.Required = required

	if err := app.Save(collection); err != nil {
		return fmt.Errorf("failed to change owner requirement in %s: %w", collectionName, err)
	}
	return nil
}
