import SwiftUI

struct ContactEditInfo {
    let userId: String
    let login: String?
    let fullName: String?
    let customName: String?
    let avatarFileId: String?

    init(userId: String, login: String?, fullName: String?, customName: String?, avatarFileId: String?) {
        self.userId = userId
        self.login = login
        self.fullName = fullName
        self.customName = customName
        self.avatarFileId = avatarFileId
    }

    init(userId: UUID, login: String?, fullName: String?, customName: String?, avatarFileId: String?) {
        self.init(userId: userId.uuidString, login: login, fullName: fullName, customName: customName, avatarFileId: avatarFileId)
    }

    init(profile: ChatProfile) {
        self.init(
            userId: profile.userId,
            login: profile.login,
            fullName: profile.fullName,
            customName: profile.customName,
            avatarFileId: profile.avatars?.current?.fileId
        )
    }

    init(payload: ContactPayload) {
        self.init(
            userId: payload.userId,
            login: payload.login,
            fullName: payload.fullName,
            customName: payload.customName,
            avatarFileId: nil
        )
    }

    var preferredName: String {
        if let full = fullName?.trimmedNonEmpty {
            return full
        }
        if let login, !login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return "@\(login)"
        }
        return NSLocalizedString("Неизвестный пользователь", comment: "Message profile fallback title")
    }
    
    var loadCustomName: String {
        if let custom = customName?.trimmedNonEmpty {
            return custom
        } else {
            return ""
        }
    }
}

struct ContactEditView: View {
    let contact: ContactEditInfo
    let onContactDeleted: (() -> Void)?
    let onContactUpdated: ((String) -> Void)?

    @Environment(\.dismiss) private var dismiss
    private let contactsService = ContactsService()
    private let initialName: String

    @State private var displayName: String
    @State private var activeAlert: ContactEditAlert?
    @State private var isSaving = false
    @State private var isDeleting = false
    @State private var showDeleteConfirmation = false

    init(
        contact: ContactEditInfo,
        onContactDeleted: (() -> Void)? = nil,
        onContactUpdated: ((String) -> Void)? = nil
    ) {
        self.contact = contact
        self.onContactDeleted = onContactDeleted
        self.onContactUpdated = onContactUpdated
        self.initialName = contact.preferredName
        let initialCustomName = contact.loadCustomName
        _displayName = State(initialValue: initialCustomName)
    }

    var body: some View {
        Form {
            avatarSection

            Section(header: Text(NSLocalizedString("Публичная информация", comment: "Profile info section title"))) {
//                TextField(NSLocalizedString("Отображаемое имя", comment: "Display name field placeholder"), text: $displayName)
                TextField(NSLocalizedString("\(self.initialName)", comment: "Display name field placeholder"), text: $displayName)
                    .disabled(isSaving || isDeleting)
            }

            Section {
                Button(role: .destructive) {
                    handleDeleteTap()
                } label: {
                    deleteButtonLabel
                }
                .disabled(isDeleting)
            }
        }
        .navigationTitle(NSLocalizedString("Контакт", comment: "Contact edit title"))
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .confirmationAction) {
                if isSaving {
                    ProgressView()
                } else {
                    Button(NSLocalizedString("Сохранить", comment: "Contact edit save button")) {
                        handleSaveTap()
                    }
                    .disabled(!hasChanges || isDeleting)
                }
            }
        }
        .alert(item: $activeAlert) { item in
            Alert(
                title: Text(item.title),
                message: Text(item.message),
                dismissButton: .default(Text(NSLocalizedString("Понятно", comment: "Placeholder alert dismiss")))
            )
        }
        .confirmationDialog(
            NSLocalizedString("Удалить контакт?", comment: "Contact delete confirmation title"),
            isPresented: $showDeleteConfirmation,
            titleVisibility: .visible
        ) {
            Button(NSLocalizedString("Удалить", comment: "Contact delete confirm action"), role: .destructive) {
                confirmDelete()
            }
            Button(NSLocalizedString("Отмена", comment: "Common cancel"), role: .cancel) {
                showDeleteConfirmation = false
            }
        } message: {
            Text(String(
                format: NSLocalizedString("Контакт \"%1$@\" будет удалён из списка.", comment: "Contact delete confirmation message"),
                contact.preferredName
            ))
        }
    }

    @ViewBuilder
    private var deleteButtonLabel: some View {
        if isDeleting {
            HStack(spacing: 8) {
                ProgressView()
                Text(NSLocalizedString("Удаляем...", comment: "Contact delete in progress"))
            }
            .frame(maxWidth: .infinity, alignment: .center)
        } else {
            Text(NSLocalizedString("Удалить контакт", comment: "Contact edit delete action"))
                .frame(maxWidth: .infinity, alignment: .center)
        }
    }

    private var avatarSection: some View {
        Section {
            HStack {
                Spacer()
                VStack(spacing: 8) {
                    avatarView
                        .frame(width: 120, height: 120)
                        .clipShape(Circle())

                    Button(NSLocalizedString("Изменить фото", comment: "Edit avatar button title")) {
                        showAvatarUnavailableAlert()
                    }
                }
                Spacer()
            }
        }
        .listRowBackground(Color(UIColor.systemGroupedBackground))
    }

    @ViewBuilder
    private var avatarView: some View {
        if let url = avatarURL,
           let fileId = contact.avatarFileId {
            CachedAvatarView(url: url, fileId: fileId, userId: contact.userId) {
                avatarPlaceholder
            }
            .aspectRatio(contentMode: .fill)
        } else {
            avatarPlaceholder
        }
    }

    private var avatarPlaceholder: some View {
        Circle()
            .fill(Color.accentColor.opacity(0.15))
            .overlay(
                Text(avatarInitial)
                    .font(.system(size: 48, weight: .semibold))
                    .foregroundColor(.accentColor)
            )
    }

    private var avatarInitial: String {
        let trimmedName = displayName.trimmedNonEmpty ?? contact.preferredName
        if let first = trimmedName.trimmingCharacters(in: .whitespacesAndNewlines).first {
            return String(first).uppercased()
        }
        if let login = contact.login?.trimmingCharacters(in: .whitespacesAndNewlines), !login.isEmpty {
            return String(login.prefix(1)).uppercased()
        }
        return "?"
    }

    private var avatarURL: URL? {
        guard let fileId = contact.avatarFileId else { return nil }
        return URL(string: "\(AppConfig.API_SERVER)/v1/storage/download/avatar/\(contact.userId)?file_id=\(fileId)")
    }

    private var hasChanges: Bool {
        let trimmed = displayName.trimmingCharacters(in: .whitespacesAndNewlines)
//        guard !trimmed.isEmpty else { return false }

        if let existing = contact.customName?.trimmedNonEmpty {
            return trimmed != existing
        }

        return true
    }

    private func showAvatarUnavailableAlert() {
        activeAlert = ContactEditAlert(
            title: NSLocalizedString("Изменение фото недоступно", comment: "Contact edit avatar unavailable title"),
            message: NSLocalizedString("Мы пока не можем обновить фото контакта.", comment: "Contact edit avatar unavailable message")
        )
    }

    private func handleSaveTap() {
        guard !isSaving, !isDeleting else { return }

        guard let userId = UUID(uuidString: contact.userId) else {
            activeAlert = ContactEditAlert(
                title: NSLocalizedString("Ошибка", comment: "Common error title"),
                message: NSLocalizedString("Не удалось определить контакт.", comment: "Contact edit invalid user id error")
            )
            return
        }

        let trimmed = displayName.trimmingCharacters(in: .whitespacesAndNewlines)
//        guard !trimmed.isEmpty else {
//            activeAlert = ContactEditAlert(
//                title: NSLocalizedString("Ошибка", comment: "Common error title"),
//                message: NSLocalizedString("Имя не может быть пустым.", comment: "Contact edit empty name error")
//            )
//            return
//        }

        if trimmed.count > 32 {
            activeAlert = ContactEditAlert(
                title: NSLocalizedString("Слишком длинное имя", comment: "Contact edit name too long title"),
                message: NSLocalizedString("Имя контакта должно быть короче 32 символов.", comment: "Contact edit name too long message")
            )
            return
        }

        isSaving = true

        Task {
            do {
                try await contactsService.updateContact(userId: userId, customName: trimmed)
                await MainActor.run {
                    isSaving = false
                    onContactUpdated?(trimmed)
                    dismiss()
                }
            } catch {
                await MainActor.run {
                    isSaving = false
                    activeAlert = ContactEditAlert(
                        title: NSLocalizedString("Ошибка", comment: "Common error title"),
                        message: error.localizedDescription
                    )
                }
            }
        }
    }

    private func handleDeleteTap() {
        guard !isDeleting else { return }
        showDeleteConfirmation = true
    }

    private func confirmDelete() {
        guard !isDeleting else { return }
        guard let userId = UUID(uuidString: contact.userId) else {
            activeAlert = ContactEditAlert(
                title: NSLocalizedString("Ошибка", comment: "Common error title"),
                message: NSLocalizedString("Не удалось определить контакт.", comment: "Contact delete invalid user id error")
            )
            return
        }

        isDeleting = true
        showDeleteConfirmation = false

        Task {
            do {
                try await contactsService.removeContact(userId: userId)
                await MainActor.run {
                    isDeleting = false
                    onContactDeleted?()
                    dismiss()
                }
            } catch {
                await MainActor.run {
                    isDeleting = false
                    activeAlert = ContactEditAlert(
                        title: NSLocalizedString("Ошибка", comment: "Common error title"),
                        message: error.localizedDescription
                    )
                }
            }
        }
    }
}

private struct ContactEditAlert: Identifiable {
    let id = UUID()
    let title: String
    let message: String
}

private extension String {
    var trimmedNonEmpty: String? {
        let value = trimmingCharacters(in: .whitespacesAndNewlines)
        return value.isEmpty ? nil : value
    }
}
