import workExperienceData from "@/src/portfolio/data/workExperienceData";
import { WorkExperienceArgs } from "@/src/portfolio/helpers/WorkExperience";

export interface ICityGroup {
	city: string;
	jobs: WorkExperienceArgs[];
	visibleJobs: WorkExperienceArgs[];
	hasMore: boolean;
	hiddenCount: number;
	imageUrl: string;
	offsetDirection: "left" | "right";
}

const CITY_IMAGES: Record<string, string> = {
	"Manchester": "/portfolio/cities/Manchester.png",
	"Edinburgh": "/portfolio/cities/Edinburgh.png",
	"Greater London": "/portfolio/cities/Greater%20London.png",
	"Warsaw": "/portfolio/cities/Warsaw.png"
};

const CITY_ALIASES: Record<string, string> = {
	"London": "Greater London",
	"Upminster": "Greater London"
};

const createCityGroup = (
	city: string,
	jobs: WorkExperienceArgs[],
	offset: "left" | "right"
): ICityGroup => {
	const importantJobs = jobs.filter(job => job.isImportant);
	const nonImportantJobs = jobs.filter(job => !job.isImportant);

	const needToFill = Math.max(0, 2 - importantJobs.length);
	const fillerJobs = nonImportantJobs.slice(0, needToFill);
	const remainingNonImportant = nonImportantJobs.slice(needToFill);

	return {
		city,
		jobs,
		visibleJobs: [...importantJobs, ...fillerJobs],
		hasMore: remainingNonImportant.length > 0,
		hiddenCount: remainingNonImportant.length,
		imageUrl: CITY_IMAGES[city] || "",
		offsetDirection: offset
	};
};

const normalizeCityName = (city: string): string => {
	return CITY_ALIASES[city] || city;
};

const parseDate = (dateString: string): Date => {
	return new Date(dateString);
};

const getEarliestJobDate = (jobs: WorkExperienceArgs[]): Date => {
	return jobs.reduce((earliest, job) => {
		const jobDate = parseDate(job.startDate);
		return jobDate < earliest ? jobDate : earliest;
	}, parseDate(jobs[0].startDate));
};

export const getCityGroups = (): ICityGroup[] => {
	const cityJobsMap = new Map<string, WorkExperienceArgs[]>();

	workExperienceData.forEach(job => {
		const normalizedCity = normalizeCityName(job.city);
		if (!cityJobsMap.has(normalizedCity)) {
			cityJobsMap.set(normalizedCity, []);
		}
		const cityJobs = cityJobsMap.get(normalizedCity);
		if (cityJobs) {
			cityJobs.push(job);
		}
	});

	const cityOrder = Array.from(cityJobsMap.entries())
		.map(([city, jobs]) => ({ city, earliestDate: getEarliestJobDate(jobs) }))
		.sort((a, b) => b.earliestDate.getTime() - a.earliestDate.getTime())
		.map(entry => entry.city);

	const offsetPattern: ("left" | "right")[] = ["right", "left", "right", "left"];

	return cityOrder
		.map((city, index) => {
			const jobs = cityJobsMap.get(city);
			if (!jobs) return null;
			return createCityGroup(
				city,
				jobs,
				offsetPattern[index % offsetPattern.length]
			);
		})
		.filter((group): group is ICityGroup => group !== null);
};
