package com.prodhack.moscow2025.presentation.screens.diffScreen

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavBackStackEntry
import com.google.gson.Gson
import com.prodhack.moscow2025.R
import com.prodhack.moscow2025.domain.models.Education
import com.prodhack.moscow2025.domain.models.Project
import com.prodhack.moscow2025.domain.models.ResumeModel
import com.prodhack.moscow2025.domain.models.WorkExperience
import com.prodhack.moscow2025.presentation.components.standart.TBubble
import com.prodhack.moscow2025.presentation.navigation.AppDestination
import com.prodhack.moscow2025.presentation.theme.Paddings
import com.prodhack.moscow2025.presentation.utils.ErrorCollectorScope
import com.prodhack.moscow2025.presentation.utils.toReadableText
import com.prodhack.moscow2025.presentation.utils.toSalaryRangeString
import com.prodhack.moscow2025.presentation.utils.ui.noRippleClickable

@Composable
fun ErrorCollectorScope.ResumeDiffScreen(
	navBackStackEntry: NavBackStackEntry,
	onBack: () -> Unit = { navController.popBackStack() }
) {
	val gson = remember { Gson() }
	val firstJson = navBackStackEntry.arguments?.getString(AppDestination.ResumeDiff.ARG_FIRST)
	val secondJson = navBackStackEntry.arguments?.getString(AppDestination.ResumeDiff.ARG_SECOND)
	val first =
		remember(firstJson) { firstJson?.let { gson.fromJson(it, ResumeModel::class.java) } }
	val second =
		remember(secondJson) { secondJson?.let { gson.fromJson(it, ResumeModel::class.java) } }

	if (first == null || second == null) {
		Column(
			modifier = Modifier
				.fillMaxSize()
				.padding(Paddings.large),
			horizontalAlignment = Alignment.CenterHorizontally,
			verticalArrangement = Arrangement.Center
		) {
			Text("Не удалось загрузить данные для сравнения")
		}
		return
	}

	val scrollState = rememberScrollState()
	val salaryDiff =
		remember(first, second) { calculateSalaryDiff(first.prediction, second.prediction) }
	val addedSkills = remember(first, second) { second.skills.toSet() - first.skills.toSet() }
	val removedSkills = remember(first, second) { first.skills.toSet() - second.skills.toSet() }
	val addedExperience = remember(first, second) { second.experience - first.experience }
	val removedExperience = remember(first, second) { first.experience - second.experience }
	val addedEducation = remember(first, second) { second.education - first.education }
	val removedEducation = remember(first, second) { first.education - second.education }
	val addedProjects = remember(first, second) { second.projects - first.projects }
	val removedProjects = remember(first, second) { first.projects - second.projects }

	Column(
		modifier = Modifier
			.fillMaxSize()
			.padding(horizontal = Paddings.large)
	) {
		Spacer(modifier = Modifier.height(Paddings.large))
		Row(
			modifier = Modifier.fillMaxWidth(),
			horizontalArrangement = Arrangement.SpaceBetween,
			verticalAlignment = Alignment.CenterVertically
		) {
			Icon(
				modifier = Modifier
					.size(24.dp)
					.rotate(180f)
					.noRippleClickable(onBack),
				painter = painterResource(R.drawable.ic_arr_details),
				tint = MaterialTheme.colorScheme.onBackground,
				contentDescription = "go back"
			)
			Text(
				text = "Сравнение версий",
				style = MaterialTheme.typography.titleLarge,
				fontSize = 22.sp
			)
			Spacer(modifier = Modifier.size(24.dp))
		}



		Column(
			modifier = Modifier
				.fillMaxSize()
				.verticalScroll(scrollState)
		) {
			Spacer(modifier = Modifier.height(Paddings.medium))
			Card(
				modifier = Modifier.fillMaxWidth(),
				colors = CardDefaults.cardColors(
					containerColor = MaterialTheme.colorScheme.primaryContainer,
					contentColor = MaterialTheme.colorScheme.onPrimaryContainer
				),
				shape = MaterialTheme.shapes.medium
			) {
				Column(
					modifier = Modifier
						.fillMaxWidth()
						.padding(Paddings.medium),
					verticalArrangement = Arrangement.spacedBy(Paddings.small)
				) {
					Text(
						text = "Разница в зарплате",
						style = MaterialTheme.typography.labelLarge,
						fontWeight = FontWeight.Medium
					)
					Text(
						text = salaryDiff,
						style = MaterialTheme.typography.titleLarge,
						fontWeight = FontWeight.Bold,
						fontSize = 22.sp
					)
				}
			}
			Spacer(modifier = Modifier.height(Paddings.large))

			SectionContainer {
				DiffValueRow(
					title = "Должность",
					previous = first.position,
					current = second.position
				)
				DiffValueRow(
					title = "Город",
					previous = first.city,
					current = second.city
				)
				DiffValueRow(
					title = "Опыт",
					previous = first.experienceType.toReadableText(),
					current = second.experienceType.toReadableText()
				)
				DiffValueRow(
					title = "Прогноз зарплаты",
					previous = first.prediction.toSalaryRangeString(),
					current = second.prediction.toSalaryRangeString()
				)
			}

			Spacer(modifier = Modifier.height(Paddings.medium))

			SectionContainer(title = "О себе") {
				DiffTextBlock(
					previous = first.about.ifBlank { "Описание отсутствует" },
					current = second.about.ifBlank { "Описание отсутствует" }
				)
			}

			Spacer(modifier = Modifier.height(Paddings.medium))

			SectionContainer(title = "Ключевые навыки") {
				SkillsDiffBlock(addedSkills = addedSkills, removedSkills = removedSkills)
			}

			Spacer(modifier = Modifier.height(Paddings.medium))

			SectionContainer(title = "Опыт работы") {
				WorkExperienceDiffBlock(
					added = addedExperience,
					removed = removedExperience
				)
			}

			Spacer(modifier = Modifier.height(Paddings.medium))

			SectionContainer(title = "Образование") {
				EducationDiffBlock(
					added = addedEducation,
					removed = removedEducation
				)
			}

			Spacer(modifier = Modifier.height(Paddings.medium))

			SectionContainer(title = "Проекты") {
				ProjectDiffBlock(
					added = addedProjects,
					removed = removedProjects
				)
			}

			Spacer(modifier = Modifier.height(Paddings.large * 3))
		}
	}
}

@Composable
private fun SectionContainer(
	modifier: Modifier = Modifier,
	title: String = "",
	colors: CardColors = CardDefaults.cardColors(),
	content: @Composable ColumnScope.() -> Unit
) {
	val typography = MaterialTheme.typography
	Card(
		modifier = modifier.fillMaxWidth(),
		colors = colors,
		shape = MaterialTheme.shapes.medium
	) {
		Column(
			modifier = Modifier
				.fillMaxWidth()
				.padding(Paddings.medium),
			verticalArrangement = Arrangement.spacedBy(Paddings.small)
		) {
			if (title.isNotBlank()) {
				Text(
					text = title,
					style = typography.titleMedium,
					fontWeight = FontWeight.Bold,
					fontSize = 18.sp
				)
			}
			content()
		}
	}
}

@Composable
private fun DiffValueRow(
	title: String,
	previous: String,
	current: String
) {
	val typography = MaterialTheme.typography
	val colorScheme = MaterialTheme.colorScheme
	val changed = previous != current

	Column(
		verticalArrangement = Arrangement.spacedBy(2.dp)
	) {
		Text(
			text = title,
			style = typography.labelLarge,
			color = colorScheme.primary
		)
		if (changed) {
			Text(
				text = previous,
				style = typography.bodyMedium.copy(textDecoration = TextDecoration.LineThrough),
				color = colorScheme.onSurfaceVariant
			)
		}
		Text(
			text = current,
			style = typography.bodyLarge,
			fontWeight = if (changed) FontWeight.Bold else FontWeight.Medium
		)
	}
}

@Composable
private fun DiffTextBlock(
	previous: String,
	current: String
) {
	val typography = MaterialTheme.typography
	val colorScheme = MaterialTheme.colorScheme
	val changed = previous != current

	if (changed) {
		Text(
			text = previous,
			style = typography.bodyMedium.copy(textDecoration = TextDecoration.LineThrough),
			color = colorScheme.onSurfaceVariant
		)
		Spacer(modifier = Modifier.height(2.dp))
		Text(
			text = current,
			style = typography.bodyLarge,
			fontSize = 16.sp,
			fontWeight = FontWeight.Bold
		)
	} else {
		Text("Без изменений", style = typography.bodyMedium)
	}
}

@Composable
private fun SkillsDiffBlock(
	addedSkills: Set<String>,
	removedSkills: Set<String>
) {
	val typography = MaterialTheme.typography

	if (addedSkills.isEmpty() && removedSkills.isEmpty()) {
		Text("Без изменений", style = typography.bodyMedium)
		return
	}

	if (addedSkills.isNotEmpty()) {
		Text("Добавлено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		FlowRow(
			horizontalArrangement = Arrangement.spacedBy(Paddings.small),
			verticalArrangement = Arrangement.spacedBy(Paddings.small)
		) {
			addedSkills.forEach { skill ->
				TBubble(text = skill)
			}
		}
	}

	if (removedSkills.isNotEmpty()) {
		Spacer(modifier = Modifier.height(Paddings.small))
		Text("Удалено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		FlowRow(
			horizontalArrangement = Arrangement.spacedBy(Paddings.small),
			verticalArrangement = Arrangement.spacedBy(Paddings.small)
		) {
			removedSkills.forEach { skill ->
				TBubble(text = skill)
			}
		}
	}
}

@Composable
private fun WorkExperienceDiffBlock(
	added: List<WorkExperience>,
	removed: List<WorkExperience>
) {
	val typography = MaterialTheme.typography

	if (added.isEmpty() && removed.isEmpty()) {
		Text("Изменений нет", style = typography.bodyMedium)
		return
	}

	if (added.isNotEmpty()) {
		Text("Добавлено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		added.forEachIndexed { index, work ->
			WorkExperienceCard(index = index, workExperience = work)
			if (index != added.lastIndex || removed.isNotEmpty()) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}

	if (removed.isNotEmpty()) {
		Text("Удалено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		removed.forEachIndexed { index, work ->
			WorkExperienceCard(index = index, workExperience = work, isRemoved = true)
			if (index != removed.lastIndex) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}
}

@Composable
private fun EducationDiffBlock(
	added: List<Education>,
	removed: List<Education>
) {
	val typography = MaterialTheme.typography

	if (added.isEmpty() && removed.isEmpty()) {
		Text("Изменений нет", style = typography.bodyMedium)
		return
	}

	if (added.isNotEmpty()) {
		Text("Добавлено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		added.forEachIndexed { index, education ->
			EducationCard(index = index, education = education)
			if (index != added.lastIndex || removed.isNotEmpty()) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}

	if (removed.isNotEmpty()) {
		Text("Удалено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		removed.forEachIndexed { index, education ->
			EducationCard(index = index, education = education, isRemoved = true)
			if (index != removed.lastIndex) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}
}

@Composable
private fun ProjectDiffBlock(
	added: List<Project>,
	removed: List<Project>
) {
	val typography = MaterialTheme.typography

	if (added.isEmpty() && removed.isEmpty()) {
		Text("Изменений нет", style = typography.bodyMedium)
		return
	}

	if (added.isNotEmpty()) {
		Text("Добавлено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		added.forEachIndexed { index, project ->
			ProjectCard(index = index, project = project)
			if (index != added.lastIndex || removed.isNotEmpty()) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}

	if (removed.isNotEmpty()) {
		Text("Удалено", style = typography.labelLarge, fontWeight = FontWeight.Bold)
		Spacer(modifier = Modifier.height(Paddings.small))
		removed.forEachIndexed { index, project ->
			ProjectCard(index = index, project = project, isRemoved = true)
			if (index != removed.lastIndex) {
				Spacer(modifier = Modifier.height(Paddings.small))
			}
		}
	}
}

@Composable
private fun WorkExperienceCard(
	index: Int,
	workExperience: WorkExperience,
	isRemoved: Boolean = false
) {
	val typography = MaterialTheme.typography
	val colorScheme = MaterialTheme.colorScheme
	val textDecoration = if (isRemoved) TextDecoration.LineThrough else TextDecoration.None
	val valueColor = if (isRemoved) colorScheme.onSurfaceVariant else colorScheme.onSurface

	Column(
		verticalArrangement = Arrangement.spacedBy(Paddings.small)
	) {
		Text(
			text = "Место №${index + 1}",
			style = typography.labelLarge,
			color = if (isRemoved) colorScheme.error else colorScheme.primary
		)
		Text(
			workExperience.place,
			style = typography.titleMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			text = workExperience.description,
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			text = "Длительность: ${workExperience.monthDuration.toMonthText()}",
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
	}
}

@Composable
private fun EducationCard(index: Int, education: Education, isRemoved: Boolean = false) {
	val typography = MaterialTheme.typography
	val colorScheme = MaterialTheme.colorScheme
	val textDecoration = if (isRemoved) TextDecoration.LineThrough else TextDecoration.None
	val valueColor = if (isRemoved) colorScheme.onSurfaceVariant else colorScheme.onSurface

	Column(
		verticalArrangement = Arrangement.spacedBy(Paddings.small)
	) {
		Text(
			text = "Учебное место №${index + 1}",
			style = typography.labelLarge,
			color = if (isRemoved) colorScheme.error else colorScheme.primary
		)
		Text(
			education.place,
			style = typography.titleMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			text = "Ступень: ${education.grade.toReadableText()}",
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			text = "Специализация: ${education.specialization}",
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			text = education.description,
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
	}
}

@Composable
private fun ProjectCard(index: Int, project: Project, isRemoved: Boolean = false) {
	val typography = MaterialTheme.typography
	val colorScheme = MaterialTheme.colorScheme
	val textDecoration = if (isRemoved) TextDecoration.LineThrough else TextDecoration.None
	val valueColor = if (isRemoved) colorScheme.onSurfaceVariant else colorScheme.onSurface

	Column(
		verticalArrangement = Arrangement.spacedBy(Paddings.small)
	) {
		Text(
			text = "Проект №${index + 1}",
			style = typography.labelLarge,
			color = if (isRemoved) colorScheme.error else colorScheme.primary
		)
		Text(
			project.name,
			style = typography.titleMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
		Text(
			project.description,
			style = typography.bodyMedium.copy(textDecoration = textDecoration),
			color = valueColor
		)
	}
}

private fun Int?.toMonthText(): String = when {
	this == null -> "Не указано"
	this < 12 -> "$this мес."
	else -> {
		val years = this / 12
		val months = this % 12
		if (months == 0) "$years г." else "$years г. $months мес."
	}
}

private fun calculateSalaryDiff(
	prev: Pair<Float?, Float?>?,
	current: Pair<Float?, Float?>?
): String {
	val prevAvg = prev?.let { listOfNotNull(it.first, it.second).averageOrNull() }
	val currAvg = current?.let { listOfNotNull(it.first, it.second).averageOrNull() }
	return if (prevAvg != null && currAvg != null) {
		val diff = currAvg - prevAvg
		val sign = if (diff >= 0) "+" else "-"
		"${sign}${(kotlin.math.abs(diff).toInt() / 1000) * 1000}₽"
	} else {
		"н/д"
	}
}

private fun List<Float>.averageOrNull(): Double? = if (isEmpty()) null else average()
