package services

import (
	"strconv"
	"strings"
)

// StateToClimateRegion maps US state abbreviations to IECC climate zone IDs.
// Some states span multiple zones — this uses the dominant zone for the most populated areas.
var StateToClimateRegion = map[string]uint{
	// Zone 1: Hot-Humid
	"HI": 1, "FL": 1, "LA": 1,
	// Zone 2: Hot-Dry / Hot-Humid mix
	"TX": 2, "AZ": 2, "NV": 2, "NM": 2,
	// Zone 3: Mixed-Humid
	"GA": 3, "SC": 3, "AL": 3, "MS": 3, "AR": 3, "NC": 3, "TN": 3, "OK": 3, "CA": 3,
	// Zone 4: Mixed
	"VA": 4, "KY": 4, "MO": 4, "KS": 4, "DE": 4, "MD": 4, "DC": 4, "WV": 4, "OR": 4,
	// Zone 5: Cold
	"NJ": 5, "PA": 5, "CT": 5, "RI": 5, "MA": 5, "OH": 5, "IN": 5, "IL": 5,
	"IA": 5, "NE": 5, "CO": 5, "UT": 5, "WA": 5, "ID": 5, "NY": 5, "MI": 5,
	// Zone 6: Very Cold
	"WI": 6, "MN": 6, "ND": 6, "SD": 6, "MT": 6, "WY": 6, "VT": 6, "NH": 6, "ME": 6,
	// Zone 8: Arctic
	"AK": 8,
}

// GetClimateRegionIDByState returns the climate region ID for a US state abbreviation.
// Returns 0 if the state is not found.
func GetClimateRegionIDByState(state string) uint {
	regionID, ok := StateToClimateRegion[strings.ToUpper(strings.TrimSpace(state))]
	if !ok {
		return 0
	}
	return regionID
}

// ZipToState maps a US ZIP code to a state abbreviation using the 3-digit ZIP prefix.
// Returns empty string if the ZIP is invalid or unrecognized.
func ZipToState(zip string) string {
	zip = strings.TrimSpace(zip)
	if len(zip) < 3 {
		return ""
	}
	prefix, err := strconv.Atoi(zip[:3])
	if err != nil {
		return ""
	}

	// ZIP prefix → state mapping (USPS ranges)
	switch {
	case prefix >= 10 && prefix <= 27:
		return "MA"
	case prefix >= 28 && prefix <= 29:
		return "RI"
	case prefix >= 30 && prefix <= 38:
		return "NH"
	case prefix >= 39 && prefix <= 49:
		return "ME"
	case prefix >= 50 && prefix <= 59:
		return "VT"
	case prefix >= 60 && prefix <= 69:
		return "CT"
	case prefix >= 70 && prefix <= 89:
		return "NJ"
	case prefix >= 100 && prefix <= 149:
		return "NY"
	case prefix >= 150 && prefix <= 196:
		return "PA"
	case prefix >= 197 && prefix <= 199:
		return "DE"
	case prefix >= 200 && prefix <= 205:
		return "DC"
	case prefix >= 206 && prefix <= 219:
		return "MD"
	case prefix >= 220 && prefix <= 246:
		return "VA"
	case prefix >= 247 && prefix <= 268:
		return "WV"
	case prefix >= 270 && prefix <= 289:
		return "NC"
	case prefix >= 290 && prefix <= 299:
		return "SC"
	case prefix >= 300 && prefix <= 319:
		return "GA"
	case prefix >= 320 && prefix <= 349:
		return "FL"
	case prefix >= 350 && prefix <= 369:
		return "AL"
	case prefix >= 370 && prefix <= 385:
		return "TN"
	case prefix >= 386 && prefix <= 397:
		return "MS"
	case prefix >= 400 && prefix <= 427:
		return "KY"
	case prefix >= 430 && prefix <= 458:
		return "OH"
	case prefix >= 460 && prefix <= 479:
		return "IN"
	case prefix >= 480 && prefix <= 499:
		return "MI"
	case prefix >= 500 && prefix <= 528:
		return "IA"
	case prefix >= 530 && prefix <= 549:
		return "WI"
	case prefix >= 550 && prefix <= 567:
		return "MN"
	case prefix >= 570 && prefix <= 577:
		return "SD"
	case prefix >= 580 && prefix <= 588:
		return "ND"
	case prefix >= 590 && prefix <= 599:
		return "MT"
	case prefix >= 600 && prefix <= 629:
		return "IL"
	case prefix >= 630 && prefix <= 658:
		return "MO"
	case prefix >= 660 && prefix <= 679:
		return "KS"
	case prefix >= 680 && prefix <= 693:
		return "NE"
	case prefix >= 700 && prefix <= 714:
		return "LA"
	case prefix >= 716 && prefix <= 729:
		return "AR"
	case prefix >= 730 && prefix <= 749:
		return "OK"
	case prefix >= 750 && prefix <= 799:
		return "TX"
	case prefix >= 800 && prefix <= 816:
		return "CO"
	case prefix >= 820 && prefix <= 831:
		return "WY"
	case prefix >= 832 && prefix <= 838:
		return "ID"
	case prefix >= 840 && prefix <= 847:
		return "UT"
	case prefix >= 850 && prefix <= 865:
		return "AZ"
	case prefix >= 870 && prefix <= 884:
		return "NM"
	case prefix >= 889 && prefix <= 898:
		return "NV"
	case prefix >= 900 && prefix <= 966:
		return "CA"
	case prefix >= 967 && prefix <= 968:
		return "HI"
	case prefix >= 970 && prefix <= 979:
		return "OR"
	case prefix >= 980 && prefix <= 994:
		return "WA"
	case prefix >= 995 && prefix <= 999:
		return "AK"
	default:
		return ""
	}
}
