package de.trainingstagebuch.app.ui.screens

import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuAnchorType
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.trainingstagebuch.app.R
import de.trainingstagebuch.app.repository.MemberItem
import de.trainingstagebuch.app.repository.TrainingGroupItem
import de.trainingstagebuch.app.utils.MembersSortOrder
import de.trainingstagebuch.app.viewmodel.MembersStatus
import de.trainingstagebuch.app.viewmodel.MembersUiState
import de.trainingstagebuch.app.viewmodel.MembersViewModel
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults

@Composable
fun MembersScreen(
    membersViewModel: MembersViewModel = viewModel()
) {
    val state by membersViewModel.state.collectAsState()
    val context = LocalContext.current
    val imagePickerLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        if (uri == null) return@rememberLauncherForActivityResult
        val bytes = context.contentResolver.openInputStream(uri)?.use { it.readBytes() } ?: return@rememberLauncherForActivityResult
        val fileName = uri.lastPathSegment?.substringAfterLast('/')?.ifBlank { "member-image.jpg" } ?: "member-image.jpg"
        membersViewModel.uploadMemberImage(fileName = fileName, bytes = bytes)
    }

    when (state.status) {
        MembersStatus.Loading -> {
            Column(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                CircularProgressIndicator()
                Text(
                    text = stringResource(R.string.members_loading),
                    modifier = Modifier.padding(top = 12.dp)
                )
            }
        }

        MembersStatus.Error -> {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(24.dp),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = state.errorMessage?.resolve(context).orEmpty(),
                    color = MaterialTheme.colorScheme.error,
                    modifier = Modifier.padding(bottom = 12.dp)
                )
                Button(onClick = membersViewModel::load) {
                    Text(stringResource(R.string.home_retry))
                }
            }
        }

        MembersStatus.Success -> {
            MembersListContent(
                state = state,
                onSearchQueryChanged = membersViewModel::onSearchQueryChanged,
                onShowInactiveChanged = membersViewModel::onShowInactiveChanged,
                onCycleSortOrder = membersViewModel::cycleSortOrder,
                onStartCreate = membersViewModel::startCreate,
                onUpdateRatings = membersViewModel::updateRatings,
                onSelectMember = membersViewModel::selectMember,
                onEditorFirstNameChanged = membersViewModel::onEditorFirstNameChanged,
                onEditorLastNameChanged = membersViewModel::onEditorLastNameChanged,
                onEditorActiveChanged = membersViewModel::onEditorActiveChanged,
                onEditorTestMembershipChanged = membersViewModel::onEditorTestMembershipChanged,
                onSaveMember = membersViewModel::saveMember,
                onQuickDeactivate = membersViewModel::quickDeactivateMember,
                onQuickRemoveTestMembership = membersViewModel::quickRemoveTestMembership,
                onPickImage = { imagePickerLauncher.launch("image/*") },
                onSetPrimaryImage = membersViewModel::setPrimaryMemberImage,
                onDeleteImage = membersViewModel::deleteMemberImage,
                onPhoneContactChanged = membersViewModel::onPhoneContactChanged,
                onAddPhoneContact = membersViewModel::addPhoneContact,
                onRemovePhoneContact = membersViewModel::removePhoneContact,
                onEmailContactChanged = membersViewModel::onEmailContactChanged,
                onAddEmailContact = membersViewModel::addEmailContact,
                onRemoveEmailContact = membersViewModel::removeEmailContact,
                onAddMemberToTrainingGroup = membersViewModel::addMemberToTrainingGroup,
                onRemoveMemberFromTrainingGroup = membersViewModel::removeMemberFromTrainingGroup,
                onNewNoteContentChanged = membersViewModel::onNewNoteContentChanged,
                onAddNote = membersViewModel::addMemberNote,
                onDeleteNote = membersViewModel::deleteMemberNote
            )
        }

        MembersStatus.Idle -> {
            Column(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(text = stringResource(R.string.members_idle))
            }
        }
    }
}

@Composable
@OptIn(ExperimentalMaterial3Api::class)
private fun MembersListContent(
    state: MembersUiState,
    onSearchQueryChanged: (String) -> Unit,
    onShowInactiveChanged: (Boolean) -> Unit,
    onCycleSortOrder: () -> Unit,
    onStartCreate: () -> Unit,
    onUpdateRatings: () -> Unit,
    onSelectMember: (MemberItem) -> Unit,
    onEditorFirstNameChanged: (String) -> Unit,
    onEditorLastNameChanged: (String) -> Unit,
    onEditorActiveChanged: (Boolean) -> Unit,
    onEditorTestMembershipChanged: (Boolean) -> Unit,
    onSaveMember: () -> Unit,
    onQuickDeactivate: (String) -> Unit,
    onQuickRemoveTestMembership: (String) -> Unit,
    onPickImage: () -> Unit,
    onSetPrimaryImage: (String) -> Unit,
    onDeleteImage: (String) -> Unit,
    onPhoneContactChanged: (Int, String) -> Unit,
    onAddPhoneContact: () -> Unit,
    onRemovePhoneContact: (Int) -> Unit,
    onEmailContactChanged: (Int, String) -> Unit,
    onAddEmailContact: () -> Unit,
    onRemoveEmailContact: (Int) -> Unit,
    onAddMemberToTrainingGroup: (String) -> Unit,
    onRemoveMemberFromTrainingGroup: (String) -> Unit,
    onNewNoteContentChanged: (String) -> Unit,
    onAddNote: () -> Unit,
    onDeleteNote: (String) -> Unit
) {
    var groupsExpanded by remember { mutableStateOf(false) }
    var selectedGroupId by remember(state.availableTrainingGroups) {
        mutableStateOf(state.availableTrainingGroups.firstOrNull()?.id.orEmpty())
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        Text(
            text = stringResource(R.string.members_title),
            style = MaterialTheme.typography.headlineSmall,
            modifier = Modifier.padding(bottom = 12.dp)
        )

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp),
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            Text(
                text = stringResource(R.string.members_stats_active, state.activeMembersCount),
                style = MaterialTheme.typography.bodySmall
            )
            Text(
                text = stringResource(R.string.members_stats_test, state.testMembersCount),
                style = MaterialTheme.typography.bodySmall
            )
            Text(
                text = stringResource(R.string.members_stats_inactive, state.inactiveMembersCount),
                style = MaterialTheme.typography.bodySmall
            )
        }

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = if (state.selectedMemberId == null) {
                    stringResource(R.string.members_editor_create_title)
                } else {
                    stringResource(R.string.members_editor_edit_title)
                },
                style = MaterialTheme.typography.titleMedium,
                modifier = Modifier.weight(1f)
            )
            TextButton(onClick = onStartCreate) {
                Text(stringResource(R.string.members_new_button))
            }
            TextButton(onClick = onUpdateRatings) {
                Text(stringResource(R.string.members_update_ratings_button))
            }
        }

        OutlinedTextField(
            value = state.editorFirstName,
            onValueChange = onEditorFirstNameChanged,
            label = { Text(stringResource(R.string.members_first_name_label)) },
            singleLine = true,
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp)
        )
        OutlinedTextField(
            value = state.editorLastName,
            onValueChange = onEditorLastNameChanged,
            label = { Text(stringResource(R.string.members_last_name_label)) },
            singleLine = true,
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp)
        )
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Checkbox(
                checked = state.editorActive,
                onCheckedChange = onEditorActiveChanged
            )
            Text(
                text = stringResource(R.string.members_item_active),
                modifier = Modifier.padding(end = 8.dp)
            )
            Checkbox(
                checked = state.editorTestMembership,
                onCheckedChange = onEditorTestMembershipChanged
            )
            Text(text = stringResource(R.string.members_item_test))
        }

        Text(
            text = stringResource(R.string.members_contacts_title),
            style = MaterialTheme.typography.titleSmall,
            modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
        )
        state.editorPhoneContacts.forEachIndexed { index, phone ->
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                OutlinedTextField(
                    value = phone,
                    onValueChange = { onPhoneContactChanged(index, it) },
                    label = { Text(stringResource(R.string.members_phone_label)) },
                    singleLine = true,
                    modifier = Modifier.weight(1f)
                )
                TextButton(onClick = { onRemovePhoneContact(index) }) {
                    Text(stringResource(R.string.members_remove_contact_button))
                }
            }
        }
        TextButton(onClick = onAddPhoneContact) {
            Text(stringResource(R.string.members_add_phone_button))
        }

        state.editorEmailContacts.forEachIndexed { index, email ->
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                OutlinedTextField(
                    value = email,
                    onValueChange = { onEmailContactChanged(index, it) },
                    label = { Text(stringResource(R.string.members_email_label)) },
                    singleLine = true,
                    modifier = Modifier.weight(1f)
                )
                TextButton(onClick = { onRemoveEmailContact(index) }) {
                    Text(stringResource(R.string.members_remove_contact_button))
                }
            }
        }
        TextButton(onClick = onAddEmailContact) {
            Text(stringResource(R.string.members_add_email_button))
        }

        Button(
            onClick = onSaveMember,
            enabled = !state.isSaving,
            modifier = Modifier
                .fillMaxWidth()
                .padding(vertical = 8.dp)
        ) {
            if (state.isSaving) {
                CircularProgressIndicator(strokeWidth = 2.dp)
            } else {
                Text(
                    text = if (state.selectedMemberId == null) {
                        stringResource(R.string.members_save_create_button)
                    } else {
                        stringResource(R.string.members_save_update_button)
                    }
                )
            }
        }
        if (state.editorMessage != null) {
            Text(
                text = state.editorMessage.resolve(LocalContext.current),
                color = MaterialTheme.colorScheme.primary,
                modifier = Modifier.padding(bottom = 8.dp)
            )
        }

        if (state.selectedMemberId != null) {
            Text(
                text = stringResource(R.string.members_training_groups_title),
                style = MaterialTheme.typography.titleSmall,
                modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
            )
            if (state.memberTrainingGroups.isEmpty()) {
                Text(
                    text = stringResource(R.string.members_training_groups_none),
                    style = MaterialTheme.typography.bodySmall
                )
            } else {
                state.memberTrainingGroups.forEach { group ->
                    MemberGroupRow(group = group, onRemove = { onRemoveMemberFromTrainingGroup(group.id) })
                }
            }

            ExposedDropdownMenuBox(
                expanded = groupsExpanded,
                onExpandedChange = { groupsExpanded = !groupsExpanded }
            ) {
                TextField(
                    value = state.availableTrainingGroups.firstOrNull { it.id == selectedGroupId }?.name.orEmpty(),
                    onValueChange = {},
                    modifier = Modifier
                        .menuAnchor(
                            type = MenuAnchorType.PrimaryNotEditable,
                            enabled = true
                        )
                        .fillMaxWidth(),
                    readOnly = true,
                    label = { Text(stringResource(R.string.members_add_group_label)) },
                    trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = groupsExpanded) },
                    colors = TextFieldDefaults.colors()
                )
                ExposedDropdownMenu(
                    expanded = groupsExpanded,
                    onDismissRequest = { groupsExpanded = false }
                ) {
                    state.availableTrainingGroups.forEach { group ->
                        DropdownMenuItem(
                            text = { Text(group.name) },
                            onClick = {
                                selectedGroupId = group.id
                                groupsExpanded = false
                            }
                        )
                    }
                }
            }
            OutlinedButton(
                onClick = { if (selectedGroupId.isNotBlank()) onAddMemberToTrainingGroup(selectedGroupId) },
                enabled = !state.groupsLoading && state.availableTrainingGroups.isNotEmpty(),
                modifier = Modifier.padding(top = 6.dp, bottom = 8.dp)
            ) {
                Text(stringResource(R.string.members_add_group_button))
            }
        }

        if (state.selectedMemberId != null) {
            Text(
                text = stringResource(R.string.members_notes_title),
                style = MaterialTheme.typography.titleSmall,
                modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
            )
            OutlinedTextField(
                value = state.newNoteContent,
                onValueChange = onNewNoteContentChanged,
                label = { Text(stringResource(R.string.members_note_input_label)) },
                modifier = Modifier.fillMaxWidth()
            )
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.End
            ) {
                OutlinedButton(onClick = onAddNote, enabled = !state.notesLoading) {
                    Text(stringResource(R.string.members_add_note_button))
                }
            }
            if (state.memberNotes.isEmpty()) {
                Text(
                    text = stringResource(R.string.members_notes_empty),
                    style = MaterialTheme.typography.bodySmall,
                    modifier = Modifier.padding(bottom = 8.dp)
                )
            } else {
                state.memberNotes.forEach { note ->
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = note.content,
                            modifier = Modifier.weight(1f),
                            style = MaterialTheme.typography.bodySmall
                        )
                        TextButton(onClick = { onDeleteNote(note.id) }) {
                            Text(stringResource(R.string.members_delete_note_button))
                        }
                    }
                }
            }
        }

        if (state.selectedMemberId != null) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(bottom = 8.dp),
                horizontalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                Button(onClick = onPickImage, enabled = !state.imagesLoading) {
                    Text(stringResource(R.string.members_image_upload_button))
                }
            }
            if (state.imagesLoading) {
                CircularProgressIndicator(
                    strokeWidth = 2.dp,
                    modifier = Modifier.padding(bottom = 8.dp)
                )
            }
            if (state.memberImages.isEmpty()) {
                Text(
                    text = stringResource(R.string.members_images_empty),
                    style = MaterialTheme.typography.bodySmall,
                    modifier = Modifier.padding(bottom = 8.dp)
                )
            } else {
                LazyColumn(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 8.dp)
                ) {
                    items(state.memberImages) { image ->
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Text(
                                text = image.url ?: image.imageId,
                                modifier = Modifier.weight(1f),
                                style = MaterialTheme.typography.bodySmall
                            )
                            if (!image.isPrimary) {
                                TextButton(onClick = { onSetPrimaryImage(image.imageId) }) {
                                    Text(stringResource(R.string.members_image_set_primary_button))
                                }
                            } else {
                                Text(
                                    text = stringResource(R.string.members_image_primary_badge),
                                    style = MaterialTheme.typography.labelSmall,
                                    modifier = Modifier.padding(horizontal = 8.dp)
                                )
                            }
                            TextButton(onClick = { onDeleteImage(image.imageId) }) {
                                Text(stringResource(R.string.members_image_delete_button))
                            }
                        }
                    }
                }
            }
        }

        Spacer(modifier = Modifier.height(6.dp))

        OutlinedTextField(
            value = state.searchQuery,
            onValueChange = onSearchQueryChanged,
            label = { Text(stringResource(R.string.members_search_label)) },
            singleLine = true,
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp)
        )

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Checkbox(
                checked = state.showInactive,
                onCheckedChange = onShowInactiveChanged
            )
            Text(
                text = stringResource(R.string.members_show_inactive),
                modifier = Modifier.weight(1f)
            )
            Button(onClick = onCycleSortOrder) {
                Text(
                    text = stringResource(
                        R.string.members_sort_button,
                        stringResource(sortLabelRes(state.sortOrder))
                    )
                )
            }
        }

        if (state.filteredMembers.isEmpty()) {
            Text(text = stringResource(R.string.members_empty))
            return
        }

        LazyColumn(modifier = Modifier.fillMaxSize()) {
            items(state.filteredMembers) { member ->
                TextButton(
                    onClick = { onSelectMember(member) },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text(
                        text = stringResource(R.string.members_edit_button),
                        modifier = Modifier.fillMaxWidth()
                    )
                }
                Text(
                    text = member.displayName,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(vertical = 8.dp),
                    style = MaterialTheme.typography.bodyLarge
                )
                val subtitleRes = if (member.active) {
                    if (member.testMembership) R.string.members_item_test else R.string.members_item_active
                } else {
                    R.string.members_item_inactive
                }
                Text(
                    text = stringResource(subtitleRes),
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 8.dp),
                    horizontalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    if (member.active) {
                        TextButton(onClick = { onQuickDeactivate(member.id) }) {
                            Text(stringResource(R.string.members_action_deactivate))
                        }
                    }
                    if (member.testMembership) {
                        TextButton(onClick = { onQuickRemoveTestMembership(member.id) }) {
                            Text(stringResource(R.string.members_action_remove_test))
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun MemberGroupRow(group: TrainingGroupItem, onRemove: () -> Unit) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            text = group.name,
            modifier = Modifier.weight(1f),
            style = MaterialTheme.typography.bodySmall
        )
        TextButton(onClick = onRemove) {
            Text(stringResource(R.string.members_remove_group_button))
        }
    }
}

private fun sortLabelRes(sortOrder: MembersSortOrder): Int {
    return when (sortOrder) {
        MembersSortOrder.NameAsc -> R.string.members_sort_name_asc
        MembersSortOrder.NameDesc -> R.string.members_sort_name_desc
        MembersSortOrder.Status -> R.string.members_sort_status
    }
}
