package service

import (
	"context"
	"strings"

	reserveac "wucher/internal/domain/reserve_ac"
	"wucher/internal/shared/pkg/reserveacutil"
	shareddto "wucher/internal/transport/http/dto/shared"
)

type ReserveAcService struct {
	repo reserveac.ReserveAcRepository
}

func NewReserveAcService(repo reserveac.ReserveAcRepository) *ReserveAcService {
	return &ReserveAcService{repo: repo}
}

func (s *ReserveAcService) Create(ctx context.Context, row *reserveac.ReserveAc) error {
	row.Status = reserveacutil.NormalizeStatus(row.Status)
	return s.repo.Create(ctx, row)
}

func (s *ReserveAcService) Update(ctx context.Context, row *reserveac.ReserveAc) error {
	row.Status = reserveacutil.NormalizeStatus(row.Status)
	return s.repo.Update(ctx, row)
}

func (s *ReserveAcService) Delete(ctx context.Context, id []byte, deletedBy []byte) error {
	return s.repo.Delete(ctx, id, deletedBy)
}

func (s *ReserveAcService) GetByID(ctx context.Context, id []byte) (*reserveac.ReserveAc, error) {
	return s.repo.GetByID(ctx, id)
}

func (s *ReserveAcService) GetActiveByInspectionID(ctx context.Context, inspectionID []byte) (*reserveac.ReserveAc, error) {
	return s.repo.GetActiveByInspectionID(ctx, inspectionID)
}

func (s *ReserveAcService) List(ctx context.Context, filter string, sort string, limit, offset int) ([]reserveac.ReserveAc, int64, error) {
	return s.repo.List(ctx, filter, normalizeReserveAcSort(sort), limit, offset)
}

func (s *ReserveAcService) AircraftExists(ctx context.Context, helicopterID []byte) (bool, error) {
	return s.repo.AircraftExists(ctx, helicopterID)
}

func (s *ReserveAcService) FlightInspectionExists(ctx context.Context, inspectionID []byte) (bool, error) {
	return s.repo.FlightInspectionExists(ctx, inspectionID)
}

func (s *ReserveAcService) ExistsActiveByInspectionID(ctx context.Context, inspectionID []byte, excludeID []byte) (bool, error) {
	return s.repo.ExistsActiveByInspectionID(ctx, inspectionID, excludeID)
}

func (s *ReserveAcService) GetLastDailyInspectionByHelicopterID(ctx context.Context, helicopterID []byte) (*shareddto.LastDailyInspection, error) {
	return s.repo.GetLastDailyInspectionByHelicopterID(ctx, helicopterID)
}

func (s *ReserveAcService) GetLastDailyInspectionSummaryByHelicopterID(ctx context.Context, helicopterID []byte) (*shareddto.LastDailyInspectionSummary, error) {
	type lastDailyInspectionSummaryRepository interface {
		GetLastDailyInspectionSummaryByHelicopterID(ctx context.Context, helicopterID []byte) (*shareddto.LastDailyInspectionSummary, error)
	}

	if repo, ok := any(s.repo).(lastDailyInspectionSummaryRepository); ok {
		return repo.GetLastDailyInspectionSummaryByHelicopterID(ctx, helicopterID)
	}
	return nil, nil
}

func normalizeReserveAcSort(sort string) string {
	if normalized := normalizeSortByRules(strings.TrimSpace(sort),
		sortExpr("status ASC, created_at ASC", "status DESC, created_at DESC", "status"),
		sortField("created_at"),
		sortField("updated_at"),
	); normalized != "" {
		return normalized
	}
	return "created_at DESC"
}
