package city

import (
	"cargo-erp-backend/internal/domain"
	"cargo-erp-backend/pkg/helpers"
	"cargo-erp-backend/pkg/importer"
	"fmt"
	"strings"
	"time"

	"gorm.io/gorm"
)

type CityImportHandler struct {
	UserData         domain.User
	Helper           helpers.HelperInterface
	lastProvinceName string
}

func NewCityImportHandler(user_data domain.User, helper helpers.HelperInterface) importer.ImportHandler {
	return &CityImportHandler{
		UserData: user_data,
		Helper:   helper,
	}
}

func (h *CityImportHandler) ValidateRow(row []string, rowNumber int) (importer.RowData, []error) {
	var errors []error

	if len(row) < 2 {
		errors = append(errors, fmt.Errorf("row must have at least 2 columns: name, province_name"))
		return nil, errors
	}

	name := strings.TrimSpace(row[0])
	if name == "" {
		errors = append(errors, fmt.Errorf("name is required"))
	} else if len(name) < 2 {
		errors = append(errors, fmt.Errorf("name must be at least 2 characters"))
	} else if len(name) > 255 {
		errors = append(errors, fmt.Errorf("name must be at most 255 characters"))
	}

	provinceName := strings.TrimSpace(row[1])
	if provinceName == "" {
		errors = append(errors, fmt.Errorf("province_name is required"))
	}

	var port string
	if len(row) >= 3 {
		port = strings.TrimSpace(row[2])
	}

	if len(errors) > 0 {
		return nil, errors
	}

	var province domain.Province
	db := h.Helper.GetDB("slave")
	if err := db.Where("UPPER(name) = ?", strings.ToUpper(provinceName)).First(&province).Error; err != nil {
		errors = append(errors, fmt.Errorf("province '%s' not found", provinceName))
		return nil, errors
	}

	h.lastProvinceName = provinceName

	now := time.Now()
	provinceID := province.ID
	city := &domain.City{
		Name:       &name,
		ProvinceID: &provinceID,
		Port:       &port,
		MerchantID: h.UserData.MerchantID,
		CreatedBy:  &h.UserData.ID,
		CreatedOn:  &now,
		UpdatedBy:  &h.UserData.ID,
		UpdatedOn:  &now,
	}

	return city, nil
}

func (h *CityImportHandler) GetDataString(data importer.RowData) string {
	city := data.(*domain.City)
	name := ""
	if city.Name != nil {
		name = *city.Name
	}
	return fmt.Sprintf("%s, %s", name, h.lastProvinceName)
}

func (h *CityImportHandler) IsDuplicate(db *gorm.DB, data importer.RowData) bool {
	city := data.(*domain.City)
	var count int64
	db.Model(&domain.City{}).
		Joins("JOIN province ON city.province_id = province.id").
		Where("UPPER(city.name) = ? AND UPPER(province.name) = ?",
			strings.ToUpper(*city.Name), strings.ToUpper(h.lastProvinceName)).
		Count(&count)
	return count > 0
}

func (h *CityImportHandler) GetTemplateHeaders() []string {
	return []string{"name", "province_name", "port"}
}

func (h *CityImportHandler) GetTemplateRows() [][]string {
	return [][]string{
		{"Jakarta Pusat", "DKI Jakarta", ""},
		{"Bandung", "Jawa Barat", ""},
		{"Surabaya", "Jawa Timur", ""},
		{"Semarang", "Jawa Tengah", ""},
	}
}
