#import "Address.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import "RandomUtils.h"
#import <BlocksKit/BlocksKit.h>
#import <LoremIpsum/LoremIpsum.h>
#import "Utility.h"
#import "Vars.h"

@implementation Address

- (BOOL)isEqual:(id)object {
	if (self == object) {
		return YES;
	}
	if (![object isKindOfClass:self.class]) {
		return NO;
	}
	return self.hash == [object hash];
}

- (NSUInteger)hash {
    return self.aid != 0 ? self.aid : [super hash];
}

- (id)copyWithZone:(NSZone *)zone {
	return [BeanUtils copyWithZone:zone origin:self];
}

#pragma mark - Property

- (NSString *)fullName {
	NSMutableArray *array = [NSMutableArray array];
	if (![StringUtils isEmpty:self.first_name]) {
		[array addObject:self.first_name];
	}
	if (![StringUtils isEmpty:self.last_name]) {
		[array addObject:self.last_name];
	}
	return [array componentsJoinedByString:@" "];
}

- (NSAttributedString *)attributedEmailIfDefaultAppending {
	if (self.isDefault) {
		return [Utility attributedDefaultAppendingWithString:self.email];
	} else {
		return [[NSAttributedString alloc] im_initWithString:self.email];
	}
}

#pragma mark - Public

- (instancetype)initWithType:(AddressType)type {
	if (self = [self init]) {
		if (type == AddressTypeContactInfo) {
			self.email = [Vars appDelegate].loginUser.email;
		}
	}
	return self;
}

- (NSString *)innerXML {
	return [CocoaUtils xmlStringWithNonZeroProperties:[BeanUtils describe:self keys:[ArrayUtils remove:[BeanUtils keysForAccessibleSimplePropertyWithClass:self.class] element:@"transient"]]];
}

+ (NSArray *)availableCountryCodes {
	return @[@"af", @"ax", @"al", @"dz", @"as", @"ad", @"ao", @"ai", @"aq", @"ag", @"ar", @"am", @"aw", @"au", @"at", @"az", @"bs", @"bh", @"bd", @"bb", @"by", @"be", @"bz", @"bj", @"bm", @"bt", @"bo", @"bq", @"ba", @"bw", @"bv", @"br", @"io", @"bn", @"bg", @"bf", @"bi", @"cv", @"kh", @"cm", @"ca", @"ky", @"cf", @"td", @"cl", @"cn", @"cx", @"cc", @"co", @"km", @"cg", @"cd", @"ck", @"cr", @"ci", @"hr", @"cu", @"cw", @"cy", @"cz", @"dk", @"dj", @"dm", @"do", @"ec", @"eg", @"sv", @"gq", @"er", @"ee", @"et", @"fk", @"fo", @"fj", @"fi", @"fr", @"gf", @"pf", @"tf", @"ga", @"gm", @"ge", @"de", @"gh", @"gi", @"gr", @"gl", @"gd", @"gp", @"gu", @"gt", @"gg", @"gn", @"gw", @"gy", @"ht", @"hm", @"va", @"hn", @"hk", @"hu", @"is", @"in", @"id", @"ir", @"iq", @"ie", @"im", @"il", @"it", @"jm", @"jp", @"je", @"jo", @"kz", @"ke", @"ki", @"kp", @"kr", @"kw", @"kg", @"la", @"lv", @"lb", @"ls", @"lr", @"ly", @"li", @"lt", @"lu", @"mo", @"mk", @"mg", @"mw", @"my", @"mv", @"ml", @"mt", @"mh", @"mq", @"mr", @"mu", @"yt", @"mx", @"fm", @"md", @"mc", @"mn", @"me", @"ms", @"ma", @"mz", @"mm", @"na", @"nr", @"np", @"nl", @"nc", @"nz", @"ni", @"ne", @"ng", @"nu", @"nf", @"mp", @"no", @"om", @"pk", @"pw", @"ps", @"pa", @"pg", @"py", @"pe", @"ph", @"pn", @"pl", @"pt", @"pr", @"qa", @"re", @"ro", @"ru", @"rw", @"bl", @"sh", @"kn", @"lc", @"mf", @"pm", @"vc", @"ws", @"sm", @"st", @"sa", @"sn", @"rs", @"sc", @"sl", @"sg", @"sx", @"sk", @"si", @"sb", @"so", @"za", @"gs", @"ss", @"es", @"lk", @"sd", @"sr", @"sj", @"sz", @"se", @"ch", @"sy", @"tw", @"tj", @"tz", @"th", @"tl", @"tg", @"tk", @"to", @"tt", @"tn", @"tr", @"tm", @"tc", @"tv", @"ug", @"ua", @"ae", @"gb", @"us", @"um", @"uy", @"uz", @"vu", @"ve", @"vn", @"vg", @"vi", @"wf", @"eh", @"ye", @"zm", @"zw"];
}

+ (NSArray *)availableCountryNames {
	return @[@"Afghanistan",
		   @"Aland Islands",
		   @"Albania",
		   @"Algeria",
		   @"American Samoa",
		   @"Andorra",
		   @"Angola",
		   @"Anguilla",
		   @"Antarctica",
		   @"Antigua and Barbuda",
		   @"Argentina",
		   @"Armenia",
		   @"Aruba",
		   @"Australia",
		   @"Austria",
		   @"Azerbaijan",
		   @"Bahamas",
		   @"Bahrain",
		   @"Bangladesh",
		   @"Barbados",
		   @"Belarus",
		   @"Belgium",
		   @"Belize",
		   @"Benin",
		   @"Bermuda",
		   @"Bhutan",
		   @"Bolivia, Plurinational State of",
		   @"Bonaire, Sint Eustatius and Saba",
		   @"Bosnia and Herzegovina",
		   @"Botswana",
		   @"Bouvet Island",
		   @"Brazil",
		   @"British Indian Ocean Territory",
		   @"Brunei Darussalam",
		   @"Bulgaria",
		   @"Burkina Faso",
		   @"Burundi",
		   @"Cabo Verde",
		   @"Cambodia",
		   @"Cameroon",
		   @"Canada",
		   @"Cayman Islands",
		   @"Central African Republic",
		   @"Chad",
		   @"Chile",
		   @"China",
		   @"Christmas Island",
		   @"Cocos (Keeling) Islands",
		   @"Colombia",
		   @"Comoros",
		   @"Congo",
		   @"Congo (The Democratic Republic of the)",
		   @"Cook Islands",
		   @"Costa Rica",
		   @"Cote d'Ivoire",
		   @"Croatia",
		   @"Cuba",
		   @"Curacao",
		   @"Cyprus",
		   @"Czech Republic",
		   @"Denmark",
		   @"Djibouti",
		   @"Dominica",
		   @"Dominican Republic",
		   @"Ecuador",
		   @"Egypt",
		   @"El Salvador",
		   @"Equatorial Guinea",
		   @"Eritrea",
		   @"Estonia",
		   @"Ethiopia",
		   @"Falkland Islands (The) [Malvinas]",
		   @"Faroe Islands",
		   @"Fiji",
		   @"Finland",
		   @"France",
		   @"French Guiana",
		   @"French Polynesia",
		   @"French Southern Territories",
		   @"Gabon",
		   @"Gambia",
		   @"Georgia",
		   @"Germany",
		   @"Ghana",
		   @"Gibraltar",
		   @"Greece",
		   @"Greenland",
		   @"Grenada",
		   @"Guadeloupe",
		   @"Guam",
		   @"Guatemala",
		   @"Guernsey",
		   @"Guinea",
		   @"Guinea-Bissau",
		   @"Guyana",
		   @"Haiti",
		   @"Heard Island and McDonald Islands",
		   @"Holy See (The) [Vatican City State]",
		   @"Honduras",
		   @"Hong Kong",
		   @"Hungary",
		   @"Iceland",
		   @"India",
		   @"Indonesia",
		   @"Iran, The Islamic Republic of",
		   @"Iraq",
		   @"Ireland",
		   @"Isle of Man",
		   @"Israel",
		   @"Italy",
		   @"Jamaica",
		   @"Japan",
		   @"Jersey",
		   @"Jordan",
		   @"Kazakhstan",
		   @"Kenya",
		   @"Kiribati",
		   @"Korea, The Democratic People's Republic of",
		   @"Korea, The Republic of",
		   @"Kuwait",
		   @"Kyrgyzstan",
		   @"Lao People's Democratic Republic",
		   @"Latvia",
		   @"Lebanon",
		   @"Lesotho",
		   @"Liberia",
		   @"Libya",
		   @"Liechtenstein",
		   @"Lithuania",
		   @"Luxembourg",
		   @"Macao",
		   @"Macedonia, The former Yugoslav Republic of",
		   @"Madagascar",
		   @"Malawi",
		   @"Malaysia",
		   @"Maldives",
		   @"Mali",
		   @"Malta",
		   @"Marshall Islands",
		   @"Martinique",
		   @"Mauritania",
		   @"Mauritius",
		   @"Mayotte",
		   @"Mexico",
		   @"Micronesia, The Federated States of",
		   @"Moldova, The Republic of",
		   @"Monaco",
		   @"Mongolia",
		   @"Montenegro",
		   @"Montserrat",
		   @"Morocco",
		   @"Mozambique",
		   @"Myanmar",
		   @"Namibia",
		   @"Nauru",
		   @"Nepal",
		   @"Netherlands",
		   @"New Caledonia",
		   @"New Zealand",
		   @"Nicaragua",
		   @"Niger",
		   @"Nigeria",
		   @"Niue",
		   @"Norfolk Island",
		   @"Northern Mariana Islands",
		   @"Norway",
		   @"Oman",
		   @"Pakistan",
		   @"Palau",
		   @"Palestine, State of",
		   @"Panama",
		   @"Papua New Guinea",
		   @"Paraguay",
		   @"Peru",
		   @"Philippines",
		   @"Pitcairn",
		   @"Poland",
		   @"Portugal",
		   @"Puerto Rico",
		   @"Qatar",
		   @"Reunion",
		   @"Romania",
		   @"Russian Federation",
		   @"Rwanda",
		   @"Saint Barthelemy",
		   @"Saint Helena, Ascension and Tristan da Cunha",
		   @"Saint Kitts and Nevis",
		   @"Saint Lucia",
		   @"Saint Martin (French part)",
		   @"Saint Pierre and Miquelon",
		   @"Saint Vincent and the Grenadines",
		   @"Samoa",
		   @"San Marino",
		   @"Sao Tome and Principe",
		   @"Saudi Arabia",
		   @"Senegal",
		   @"Serbia",
		   @"Seychelles",
		   @"Sierra Leone",
		   @"Singapore",
		   @"Sint Maarten (Dutch part)",
		   @"Slovakia",
		   @"Slovenia",
		   @"Solomon Islands",
		   @"Somalia",
		   @"South Africa",
		   @"South Georgia and the South Sandwich Islands",
		   @"South Sudan",
		   @"Spain",
		   @"Sri Lanka",
		   @"Sudan",
		   @"Suriname",
		   @"Svalbard and Jan Mayen",
		   @"Swaziland",
		   @"Sweden",
		   @"Switzerland",
		   @"Syrian Arab Republic",
		   @"Taiwan (Province of China)",
		   @"Tajikistan",
		   @"Tanzania, United Republic of",
		   @"Thailand",
		   @"Timor-Leste",
		   @"Togo",
		   @"Tokelau",
		   @"Tonga",
		   @"Trinidad and Tobago",
		   @"Tunisia",
		   @"Turkey",
		   @"Turkmenistan",
		   @"Turks and Caicos Islands",
		   @"Tuvalu",
		   @"Uganda",
		   @"Ukraine",
		   @"United Arab Emirates",
		   @"United Kingdom",
		   @"United States",
		   @"United States Minor Outlying Islands",
		   @"Uruguay",
		   @"Uzbekistan",
		   @"Vanuatu",
		   @"Venezuela, Bolivarian Republic of ",
		   @"Viet Nam",
		   @"Virgin Islands (British)",
		   @"Virgin Islands (U.S.)",
		   @"Wallis and Futuna",
		   @"Western Sahara",
		   @"Yemen",
		   @"Zambia",
		   @"Zimbabwe"];
}

+ (NSArray *)knownStates {
	return @[@"AK", @"AL", @"AR", @"AZ", @"CA", @"CO", @"CT", @"DC", @"DE", @"FL", @"GA", @"HI", @"IA", @"ID",
		   @"IL", @"IN", @"KS", @"KY", @"LA", @"MA", @"MD", @"ME", @"MI", @"MN", @"MO", @"MS", @"MT", @"NC",
		   @"ND", @"NE", @"NH", @"NJ", @"NM", @"NV", @"NY", @"OH", @"OK", @"OR", @"PA", @"RI", @"SC", @"SD",
		   @"TN", @"TX", @"UT", @"VA", @"VT", @"WA", @"WI", @"WV", @"WY", @"AA", @"AE", @"AP", @"AS", @"PR",
		   @"FM", @"GU", @"MH", @"MP", @"PW", @"VI"];
}

+ (NSString *)preferredCountryCode {
	return @"us";
}

+ (Address *)primaryOfAddresses:(NSArray *)addresses {
	Address *address = [self defaultOfAddresses:addresses];
	return address ? address : addresses.firstObject;
}

+ (Address *)defaultOfAddresses:(NSArray *)addresses {
	return [addresses bk_match:^BOOL (Address *obj) {
		return obj.isDefault;
	}];
}

+ (Address *)randomAddressWithType:(AddressType)type {
	Address *address = [[Address alloc] init];
	if (type == AddressTypeContactInfo) {
		address.first_name = [LoremIpsum word].capitalizedString;
		address.last_name = [LoremIpsum word].capitalizedString;
		address.email = [Vars appDelegate].loginUser ? [Vars appDelegate].loginUser.email : [NSString stringWithFormat:@"%@@%@", [LoremIpsum word], [Vars site_title].lowercaseString];
		address.phone = [RandomStringUtils randomNumeric:10];
		address.isDefault = [RandomUtils nextBoolean];
	}
	return address;
}

@end
