package mysql

import (
	"context"
	"errors"

	"gorm.io/gorm"

	easarelease "wucher/internal/domain/easa_release"
)

type EASAReleaseRepository struct{ db *gorm.DB }

func NewEASAReleaseRepository(db *gorm.DB) *EASAReleaseRepository {
	return &EASAReleaseRepository{db: db}
}

func (r *EASAReleaseRepository) Create(ctx context.Context, row *easarelease.EASARelease) error {
	return r.db.WithContext(ctx).Create(row).Error
}

func (r *EASAReleaseRepository) Update(ctx context.Context, row *easarelease.EASARelease) error {
	return r.db.WithContext(ctx).Save(row).Error
}

func (r *EASAReleaseRepository) Delete(ctx context.Context, id []byte, deletedBy []byte) error {
	return r.db.WithContext(ctx).Model(&easarelease.EASARelease{}).
		Where("id = ? AND deleted_at IS NULL", id).
		Updates(map[string]any{"deleted_at": gorm.Expr("NOW(3)"), "deleted_by": deletedBy, "updated_by": deletedBy}).Error
}

func (r *EASAReleaseRepository) GetByID(ctx context.Context, id []byte) (*easarelease.EASARelease, error) {
	var row easarelease.EASARelease
	err := r.db.WithContext(ctx).
		Where("id = ? AND deleted_at IS NULL", id).
		First(&row).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	return &row, err
}

func (r *EASAReleaseRepository) GetByFlightID(ctx context.Context, flightID []byte) (*easarelease.EASARelease, error) {
	var row easarelease.EASARelease
	err := r.db.WithContext(ctx).
		Where("flight_id = ? AND deleted_at IS NULL", flightID).
		Order("created_at DESC").
		First(&row).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	return &row, err
}

func (r *EASAReleaseRepository) GetByComplaintID(ctx context.Context, complaintID []byte) (*easarelease.EASARelease, error) {
	var row easarelease.EASARelease
	err := r.db.WithContext(ctx).
		Where("complaint_id = ? AND deleted_at IS NULL", complaintID).
		Order("created_at DESC").
		First(&row).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	return &row, err
}

func (r *EASAReleaseRepository) ListByHelicopter(ctx context.Context, helicopterID []byte) ([]easarelease.EASARelease, error) {
	rows := make([]easarelease.EASARelease, 0)
	err := r.db.WithContext(ctx).
		Where("helicopter_id = ? AND deleted_at IS NULL", helicopterID).
		Order("created_at DESC").
		Find(&rows).Error
	return rows, err
}

func (r *EASAReleaseRepository) GetLatestByHelicopter(ctx context.Context, helicopterID []byte) (*easarelease.EASARelease, error) {
	var row easarelease.EASARelease
	err := r.db.WithContext(ctx).
		Where("helicopter_id = ? AND deleted_at IS NULL", helicopterID).
		Order("created_at DESC").
		First(&row).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	return &row, err
}

func (r *EASAReleaseRepository) GetActiveByHelicopter(ctx context.Context, helicopterID []byte) (*easarelease.EASARelease, error) {
	var row easarelease.EASARelease
	err := r.db.WithContext(ctx).
		Where("helicopter_id = ? AND signed_at IS NOT NULL AND deleted_at IS NULL", helicopterID).
		Order("signed_at DESC").
		First(&row).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	return &row, err
}

func (r *EASAReleaseRepository) VoidByID(ctx context.Context, id []byte, reason string, actor []byte) error {
	return r.db.WithContext(ctx).Model(&easarelease.EASARelease{}).
		Where("id = ? AND deleted_at IS NULL", id).
		Updates(map[string]any{"deleted_at": gorm.Expr("NOW(3)"), "deleted_by": actor, "updated_by": actor}).Error
}
