package dailyreport

import (
	"errors"
	"system-altrak/internal/domain"
	"system-altrak/internal/repository"
	"time"

	"gorm.io/gorm"
)

type DailyReportRepository interface {
	ListHistoricalRecords(search, from, to string, branchID uint, role string) ([]domain.OperationalRecord, error)
	RevertVerification(id uint, branchID uint, role string) error
	MarkAsExported(ids []uint, branchID uint, exportedBy uint) error
	GetLastArchivedAt(branchID uint) (*time.Time, error)
}

type repositoryImpl struct {
	base *repository.Repository
}

func NewRepository(base *repository.Repository) DailyReportRepository {
	return &repositoryImpl{base: base}
}

func (r *repositoryImpl) ListHistoricalRecords(search, from, to string, branchID uint, role string) ([]domain.OperationalRecord, error) {
	var records []domain.OperationalRecord
	// Only show verified records that have NOT been exported yet
	query := r.base.GetDB().Where("is_verified = ? AND exported_at IS NULL", true)
	if role != "superadmin" && branchID > 0 {
		query = query.Where("branch_id = ?", branchID)
	}
	if search != "" {
		query = query.Where("pso_no LIKE ? OR po_no LIKE ? OR customer_name LIKE ?", "%"+search+"%", "%"+search+"%", "%"+search+"%")
	}
	if from != "" {
		query = query.Where("CAST(verified_at AS DATE) >= ?", from)
	}
	if to != "" {
		query = query.Where("CAST(verified_at AS DATE) <= ?", to)
	}
	err := query.Order("verified_at asc").Find(&records).Error
	return records, err
}

func (r *repositoryImpl) RevertVerification(id uint, branchID uint, role string) error {
	query := r.base.GetDB().Model(&domain.OperationalRecord{}).Where("id = ?", id)
	if role != "superadmin" && branchID > 0 {
		query = query.Where("branch_id = ?", branchID)
	}
	tx := query.Updates(map[string]interface{}{
		"is_verified": false,
		"verified_at": nil,
		"verified_by": nil,
	})
	if tx.Error != nil {
		return tx.Error
	}
	if tx.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}

	return nil
}

func (r *repositoryImpl) MarkAsExported(ids []uint, branchID uint, exportedBy uint) error {
	now := time.Now()
	query := r.base.GetDB().Model(&domain.OperationalRecord{}).Where("id IN ?", ids)
	if branchID > 0 {
		query = query.Where("branch_id = ?", branchID)
	}
	return query.Updates(map[string]interface{}{
		"exported_at": now,
		"exported_by": exportedBy,
		"updated_at":  now,
	}).Error
}
func (r *repositoryImpl) GetLastArchivedAt(branchID uint) (*time.Time, error) {
	var record domain.OperationalRecord
	query := r.base.GetDB().Where("exported_at IS NOT NULL")
	if branchID > 0 {
		query = query.Where("branch_id = ?", branchID)
	}
	err := query.Order("exported_at desc").First(&record).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, err
	}
	return record.ExportedAt, nil
}
