/**
 * Precomputed character pair and trio affinity.
 */
export interface Affinity {
	/**
	 * First character in the relation.
	 */
	chara_a: number;
	/**
	 * Second character in the relation.
	 * chara_a < chara_b is an invariant.
	 */
	chara_b: number;
	/**
	 * Third character in the relation, if it is a trio relation.
	 * If defined, chara_b < chara_c is an invariant.
	 */
	chara_c?: number;
	/**
	 * Total base compatibility between characters in the relation.
	 */
	affinity: number;
}

export async function affinity(): Promise<Affinity[]> {
	const resp = await fetch('/api/global/affinity');
	return resp.json();
}

export function lookup(aff: Affinity[], chara_a: number, chara_b: number, chara_c?: number): number {
	const [a, b, c] = [chara_a, chara_b, chara_c ?? Infinity].sort((a, b) => a - b);
	const r = aff.find((v) => v.chara_a === a && v.chara_b === b && (v.chara_c ?? Infinity) === c);
	return r?.affinity ?? 0;
}

/**
 * Individual affinity entry.
 */
export interface AffinityDetail {
	/** Character to which the entry applies. */
	chara_id: number;
	/** Succession relation that the character has. */
	relation: number;
	/** Value of the succession relation. */
	affinity: number;
}

export async function affinityDetail(): Promise<AffinityDetail[]> {
	const resp = await fetch('/api/global/affinity-detail');
	return resp.json();
}

export interface AffinityRelationDescription {
	name: string;
	note?: string;
}

export const AFFINITY_RELATION_DESCRIPTIONS = new Map<number, AffinityRelationDescription>([
	[2001, { name: 'Shared Parent', note: 'Sunday Silence' }],
	[2002, { name: 'Shared Parent', note: 'Tony Bin' }],
	[2003, { name: 'Shared Parent', note: 'Sakura Yutaka O' }],
	[2004, { name: 'Shared Parent', note: 'Mejiro Ryan' }],
	[2005, { name: 'Shared Parent' }],
	[2006, { name: 'Shared Parent' }],
	[2007, { name: 'Shared Parent', note: 'Symboli Rudolf' }],
	[2008, { name: 'Shared Parent', note: 'Tosho Boy' }],
	[2009, { name: 'Shared Parent', note: "Brian's Time" }],
	[2010, { name: 'Shared Parent', note: 'Gold Allure' }],
	[2011, { name: 'Shared Parent', note: 'Soccer Boy' }],
	[2101, { name: 'Shared Grandparent', note: 'Sunday Silence (grandsire)' }],
	[2102, { name: 'Shared Grandparent', note: 'Maruzensky (damsire)' }],
	[2103, { name: 'Shared Grandparent', note: 'Roberto (grandsire)' }],
	[2104, { name: 'Shared Grandparent', note: 'Blushing Groom (damsire)' }],
	[2105, { name: 'Shared Grandparent', note: 'Tesco Boy (damsire)' }],
	[2106, { name: 'Shared Grandparent', note: 'Northern Taste (damsire)' }],
	[2107, { name: 'Shared Grandparent', note: 'Royal Ski (damsire)' }],
	[2108, { name: 'Shared Grandparent', note: 'Never Beat (damsire)' }],
	[2109, { name: 'Shared Grandparent', note: 'Affirmed (damsire)' }],
	[2110, { name: 'Shared Grandparent', note: 'Sancy (damsire)' }],
	[2111, { name: 'Shared Grandparent', note: 'Last Tycoon (grandsire)' }],
	[2201, { name: 'Parent/Child' }],
	[2202, { name: 'Parent/Child' }],
	[2203, { name: 'Grandparent/Grandchild' }],
	[2204, { name: 'Parent/Child' }],
	[2205, { name: 'Grandparent/Grandchild' }],
	[2206, { name: 'Parent/Child' }],
	[2208, { name: 'Parent/Child' }],
	[2209, { name: 'Parent/Child' }],
	[2210, { name: 'Parent/Child' }],
	[2211, { name: 'Grandparent/Grandchild' }],
	[2212, { name: 'Parent/Child' }],
	[2213, { name: 'Parent/Child' }],
	[2214, { name: 'Grandparent/Grandchild' }],
	[2215, { name: 'Grandparent/Grandchild' }],
	[2216, { name: 'Grandparent/Grandchild' }],
	[2217, { name: 'Grandparent/Grandchild' }],
	[2218, { name: 'Parent/Child' }],
	[2301, { name: 'Grandparent/Grandchild' }],
	[2302, { name: 'Grandparent/Grandchild' }],
	[2303, { name: 'Grandparent/Grandchild' }],
	[2401, { name: 'Racing Generation', note: 'Pre-1980' }],
	[2402, { name: 'Racing Generation', note: '1983-86' }],
	[2403, { name: 'Racing Generation', note: '1987-90' }],
	[2404, { name: 'Racing Generation', note: '1990-93' }],
	[2405, { name: 'Racing Generation', note: '1995-97' }],
	[2406, { name: 'Racing Generation', note: '1997-99' }],
	[2407, { name: 'Racing Generation', note: '1998-2004' }],
	[2408, { name: 'Racing Generation', note: '2001-04' }],
	[2409, { name: 'Racing Generation', note: '2006-10' }],
	[2410, { name: 'Racing Generation' }],
	[2411, { name: 'Racing Generation' }],
	[2412, { name: 'Racing Generation' }],
	[2413, { name: 'Racing Generation' }],
	[2501, { name: 'G1 Winner', note: 'February Stakes' }],
	[2502, { name: 'G1 Winner', note: 'Takamatsunomiya Kinen' }],
	[2503, { name: 'G1 Winner', note: 'Osaka Hai' }],
	[2504, { name: 'G1 Winner', note: 'Oka Sho' }],
	[2505, { name: 'G1 Winner', note: 'Satsuki Sho' }],
	[2506, { name: 'G1 Winner', note: 'Tenno Sho (Spring)' }],
	[2507, { name: 'G1 Winner', note: 'NHK Mile Cup' }],
	[2508, { name: 'G1 Winner', note: 'Victoria Mile' }],
	[2509, { name: 'G1 Winner', note: 'Japanese Oaks' }],
	[2510, { name: 'G1 Winner', note: 'Tokyo Yushun (Japanese Derby)' }],
	[2511, { name: 'G1 Winner', note: 'Yasuda Kinen' }],
	[2512, { name: 'G1 Winner', note: 'Takarazuka Kinen' }],
	[2513, { name: 'G1 Winner', note: 'Sprinters Stakes' }],
	[2514, { name: 'G1 Winner', note: 'Shuka Sho' }],
	[2515, { name: 'G1 Winner', note: 'Kikuka Sho' }],
	[2516, { name: 'G1 Winner', note: 'Tenno Sho (Autumn)' }],
	[2517, { name: 'G1 Winner', note: 'Queen Elizabeth II Cup' }],
	[2518, { name: 'G1 Winner', note: 'Mile Championship' }],
	[2519, { name: 'G1 Winner', note: 'Japan Cup' }],
	[2520, { name: 'G1 Winner', note: 'Champions Cup' }],
	[2521, { name: 'G1 Winner', note: 'Hanshin Juvenile Fillies' }],
	[2522, { name: 'G1 Winner', note: 'Asahi Hai Futurity Stakes' }],
	[2523, { name: 'G1 Winner', note: 'Arima Kinen' }],
	[2524, { name: 'G1 Winner', note: 'Hopeful Stakes' }],
	[2525, { name: 'G1 Winner', note: 'Teio Sho' }],
	[2526, { name: 'G1 Winner', note: 'Japan Dirt Derby' }],
	[2527, { name: 'G1 Winner', note: 'JBC Ladies’ Classic' }],
	[2528, { name: 'G1 Winner', note: 'JBC Sprint' }],
	[2529, { name: 'G1 Winner', note: 'JBC Classic' }],
	[2530, { name: 'G1 Winner', note: 'Tokyo Daishoten' }],
	[2531, { name: 'G1 Winner', note: 'Kawasaki Kinen' }],
	[2532, { name: 'G1 Winner', note: 'Mile Championship Nambu Hai' }],
	[2533, { name: 'G1 Winner', note: 'Kashiwa Kinen' }],
	[2534, { name: 'G1 Winner', note: 'Zen-Nippon Junior Yushun' }],
	[2601, { name: 'Stallion' }],
	[2602, { name: 'Mare' }],
	[2702, { name: '7 G1 + Triple Crown winner' }],
	[2801, { name: 'Classic Year', note: '1986' }],
	[2802, { name: 'Classic Year', note: '1987' }],
	[2803, { name: 'Classic Year', note: '1990' }],
	[2804, { name: 'Classic Year', note: '1991' }],
	[2805, { name: 'Classic Year', note: '1992' }],
	[2806, { name: 'Classic Year', note: '1993' }],
	[2807, { name: 'Classic Year', note: '1994' }],
	[2808, { name: 'Classic Year', note: '1995' }],
	[2809, { name: 'Classic Year', note: '1996' }],
	[2810, { name: 'Classic Year', note: '1997' }],
	[2811, { name: 'Classic Year', note: '1998' }],
	[2812, { name: 'Classic Year', note: '1999' }],
	[2813, { name: 'Classic Year', note: '2000' }],
	[2814, { name: 'Classic Year', note: '2001' }],
	[2815, { name: 'Classic Year', note: '2007' }],
	[2816, { name: 'Classic Year', note: '2009' }],
	[2817, { name: 'Classic Year', note: '2010' }],
	[2818, { name: 'Classic Year' }],
	[2819, { name: 'Classic Year' }],
	[2820, { name: 'Classic Year' }],
	[2821, { name: 'Classic Year' }],
	[2822, { name: 'Classic Year', note: '2002' }],
	[2823, { name: 'Classic Year' }],
	[2824, { name: 'Classic Year' }],
	[2825, { name: 'Classic Year' }],
	[2826, { name: 'Classic Year' }],
	[2827, { name: 'Classic Year' }],
	[2828, { name: 'Classic Year' }],
	[2829, { name: 'Classic Year' }],
	[2830, { name: 'Classic Year' }],
	[2831, { name: 'Classic Year' }],
	[2832, { name: 'Classic Year' }],
	[2833, { name: 'Classic Year' }],
	[3201, { name: 'Birth Month', note: 'January' }],
	[3202, { name: 'Birth Month', note: 'February' }],
	[3203, { name: 'Birth Month', note: 'March' }],
	[3204, { name: 'Birth Month', note: 'April' }],
	[3205, { name: 'Birth Month', note: 'May' }],
	[3206, { name: 'Birth Month', note: 'June' }],
	[3301, { name: 'No G1 Wins' }],
	[3501, { name: 'Classic Triple Crown Runner' }],
	[3502, { name: 'Triple Tiara Runner' }],
	[3503, { name: 'Spring Triple Crown Runner' }],
	[3504, { name: 'Autumn Triple Crown Runner' }],
	[101, { name: 'Tracen Class' }],
	[102, { name: 'Tracen Class' }],
	[103, { name: 'Tracen Class' }],
	[104, { name: 'Tracen Class' }],
	[105, { name: 'Tracen Class' }],
	[106, { name: 'Tracen Class' }],
	[107, { name: 'Tracen Class' }],
	[201, { name: 'Residence', note: 'Miho Dorm' }],
	[202, { name: 'Residence', note: 'Ritto Dorm' }],
	[203, { name: 'Residence', note: 'Lives Alone' }],
	[204, { name: 'Residence' }],
	[205, { name: 'Residence', note: 'Not In Dorm' }],
	[301, { name: 'Roommate' }],
	[302, { name: 'Roommate' }],
	[303, { name: 'Roommate' }],
	[304, { name: 'Roommate' }],
	[305, { name: 'Roommate' }],
	[306, { name: 'Roommate' }],
	[307, { name: 'Roommate' }],
	[308, { name: 'Roommate' }],
	[309, { name: 'Roommate' }],
	[310, { name: 'Roommate' }],
	[311, { name: 'Roommate' }],
	[312, { name: 'Roommate' }],
	[313, { name: 'Roommate' }],
	[314, { name: 'Roommate' }],
	[315, { name: 'Roommate' }],
	[316, { name: 'Roommate' }],
	[317, { name: 'Roommate' }],
	[318, { name: 'Roommate' }],
	[319, { name: 'Roommate' }],
	[320, { name: 'Roommate' }],
	[321, { name: 'Roommate' }],
	[322, { name: 'Roommate' }],
	[323, { name: 'Roommate' }],
	[324, { name: 'Roommate' }],
	[325, { name: 'Roommate' }],
	[326, { name: 'Roommate' }],
	[327, { name: 'Roommate' }],
	[328, { name: 'Roommate' }],
	[329, { name: 'Roommate' }],
	[330, { name: 'Roommate' }],
	[331, { name: 'Roommate' }],
	[332, { name: 'Roommate' }],
	[333, { name: 'Roommate' }],
	[334, { name: 'Roommate' }],
	[335, { name: 'Roommate' }],
	[336, { name: 'Roommate' }],
	[337, { name: 'Roommate' }],
	[338, { name: 'Roommate' }],
	[339, { name: 'Roommate' }],
	[340, { name: 'Roommate' }],
	[341, { name: 'Roommate' }],
	[342, { name: 'Roommate' }],
	[343, { name: 'Roommate' }],
	[344, { name: 'Roommate' }],
	[345, { name: 'Roommate' }],
	[346, { name: 'Roommate' }],
	[347, { name: 'Roommate' }],
	[348, { name: 'Roommate' }],
	[349, { name: 'Roommate' }],
	[350, { name: 'Roommate' }],
	[351, { name: 'Roommate' }],
	[352, { name: 'Roommate' }],
	[353, { name: 'Roommate' }],
	[354, { name: 'Roommate' }],
	[355, { name: 'Roommate' }],
	[356, { name: 'Roommate' }],
	[357, { name: 'Roommate' }],
	[358, { name: 'Roommate' }],
	[359, { name: 'Roommate' }],
	[360, { name: 'Roommate' }],
	[361, { name: 'Roommate' }],
	[362, { name: 'Roommate' }],
	[363, { name: 'Roommate' }],
	[364, { name: 'Roommate' }],
	[365, { name: 'Roommate' }],
	[366, { name: 'Roommate' }],
	[367, { name: 'Roommate' }],
	[368, { name: 'Roommate' }],
	[369, { name: 'Roommate' }],
	[370, { name: 'Roommate' }],
	[371, { name: 'Roommate' }],
	[372, { name: 'Roommate' }],
	[373, { name: 'Roommate' }],
	[374, { name: 'Roommate' }],
	[375, { name: 'Roommate' }],
	[376, { name: 'Roommate' }],
	[377, { name: 'Roommate' }],
	[378, { name: 'Roommate' }],
	[379, { name: 'Roommate' }],
	[380, { name: 'Roommate' }],
	[381, { name: 'Roommate' }],
	[382, { name: 'Roommate' }],
	[383, { name: 'Roommate' }],
	[384, { name: 'Roommate' }],
	[385, { name: 'Roommate' }],
	[386, { name: 'Roommate' }],
	[387, { name: 'Roommate' }],
	[388, { name: 'Roommate' }],
	[401, { name: 'Clique', note: 'Golden Generation' }],
	[402, { name: 'Clique' }],
	[403, { name: 'Clique' }],
	[404, { name: 'Clique' }],
	[405, { name: 'Clique' }],
	[406, { name: 'Clique', note: 'Old People' }],
	[407, { name: 'Clique' }],
	[408, { name: 'Clique' }],
	[409, { name: 'Clique' }],
	[410, { name: 'Clique' }],
	[411, { name: 'Clique' }],
	[412, { name: 'Clique' }],
	[413, { name: 'Clique' }],
	[414, { name: 'Clique' }],
	[415, { name: 'Clique' }],
	[416, { name: 'Clique' }],
	[417, { name: 'Clique' }],
	[418, { name: 'Clique' }],
	[419, { name: 'Clique' }],
	[420, { name: 'Clique' }],
	[421, { name: 'Clique' }],
	[422, { name: 'Clique' }],
	[423, { name: 'Clique' }],
	[424, { name: 'Clique' }],
	[501, { name: 'Story Group', note: 'Student Council' }],
	[502, { name: 'Story Group', note: 'Golden Generation' }],
	[503, { name: 'Story Group', note: 'Mejiro Family' }],
	[504, { name: 'Story Group', note: 'Rich People' }],
	[505, { name: 'Story Group', note: 'Dorm Leaders' }],
	[506, { name: 'Story Group', note: 'Heisei Big Three' }],
	[507, { name: 'Story Group', note: 'BNW' }],
	[511, { name: 'Story Group', note: '"Sakura"' }],
	[512, { name: 'Story Group' }],
	[513, { name: 'Story Group', note: 'Team Canopus' }],
	[514, { name: 'Story Group', note: 'Runaway Bakas' }],
	[515, { name: 'Story Group', note: 'Kita and Dia' }],
	[516, { name: 'Story Group', note: 'McQueen and Dia' }],
	[517, { name: 'Story Group', note: 'Teio and Kitasan' }],
	[518, { name: 'Story Group', note: 'Notable Front Runners' }],
	[519, { name: 'Story Group' }],
	[520, { name: 'Story Group', note: 'Notable Dirt Runners' }],
	[521, { name: 'Story Group' }],
	[522, { name: 'Story Group', note: 'Satono Family' }],
	[523, { name: 'Story Group', note: 'Team Sirius' }],
	[524, { name: 'Story Group', note: 'Team Rigil' }],
	[525, { name: 'Story Group', note: 'Team Spica' }],
	[526, { name: 'Story Group', note: 'Notable Runaways' }],
	[3505, { name: 'Ran on Dirt' }],
	[3506, { name: 'Overseas' }],
	[3508, { name: 'Ran a Sprint' }],
	[2901, { name: 'Strategy', note: 'Front Runner' }],
	[2902, { name: 'Strategy', note: 'Pace Chaser' }],
	[2903, { name: 'Strategy', note: 'Late Surger' }],
	[2904, { name: 'Strategy', note: 'End Closer' }],
	[3001, { name: 'Distance', note: 'Sprint' }],
	[3002, { name: 'Distance', note: 'Mile' }],
	[3003, { name: 'Distance', note: 'Medium' }],
	[3004, { name: 'Distance', note: 'Long' }],
	[3101, { name: 'Surface', note: 'Turf' }],
	[3102, { name: 'Surface', note: 'Dirt' }],
	[508, { name: 'Haru Urara', note: 'Haru Urara' }],
	[509, { name: 'Haru Urara', note: 'Haru Urara' }],
	[510, { name: 'Haru Urara', note: 'Haru Urara' }],
	[527, { name: 'Haru Urara', note: 'Haru Urara' }],
	[528, { name: 'Haru Urara', note: 'Haru Urara' }],
	[529, { name: 'Haru Urara', note: 'Haru Urara' }],
	[530, { name: 'Haru Urara', note: 'Haru Urara' }],
	[531, { name: 'Haru Urara', note: 'Haru Urara' }],
	[532, { name: 'Haru Urara', note: 'Haru Urara' }],
	[533, { name: 'Haru Urara', note: 'Haru Urara' }],
	[534, { name: 'Haru Urara', note: 'Haru Urara' }],
	[535, { name: 'Haru Urara', note: 'Haru Urara' }],
	[536, { name: 'Haru Urara', note: 'Haru Urara' }],
	[537, { name: 'Haru Urara', note: 'Haru Urara' }],
	[538, { name: 'Haru Urara', note: 'Haru Urara' }],
	[539, { name: 'Haru Urara', note: 'Haru Urara' }],
	[540, { name: 'Haru Urara', note: 'Haru Urara' }],
	[541, { name: 'Haru Urara', note: 'Haru Urara' }],
	[542, { name: 'Haru Urara', note: 'Haru Urara' }],
	[543, { name: 'Haru Urara', note: 'Haru Urara' }],
	[544, { name: 'Haru Urara', note: 'Haru Urara' }],
	[545, { name: 'Haru Urara', note: 'Haru Urara' }],
	[546, { name: 'Haru Urara', note: 'Haru Urara' }],
	[547, { name: 'Haru Urara', note: 'Haru Urara' }],
	[548, { name: 'Haru Urara', note: 'Haru Urara' }],
	[549, { name: 'Haru Urara', note: 'Haru Urara' }],
	[550, { name: 'Haru Urara', note: 'Haru Urara' }],
	[551, { name: 'Haru Urara', note: 'Haru Urara' }],
]);
