import SwiftUI

enum AppTab: String, CaseIterable, Identifiable {
    case online, search, inbox, history, console, more
    var id: String { rawValue }
    var titleKey: String {
        switch self {
        case .online: return "tab_online"
        case .search: return "tab_search"
        case .inbox: return "tab_inbox"
        case .history: return "tab_history"
        case .console: return "tab_console"
        case .more: return "tab_more"
        }
    }
}

enum MoreSection: String, CaseIterable {
    case overview, feedback, partners, faq, rules, safety, imprint
}

/// Entspricht `YpChatRoot` / `ChatShell` (Android).
struct YpChatRoot: View {
    @EnvironmentObject private var services: AppServices

    private var repo: ChatRepository { services.repository }
    private var chat: ChatState { repo.state }

    var body: some View {
        Group {
            if !chat.isLoggedIn {
                LoginScreen()
            } else {
                ChatShellView()
            }
        }
        .task {
            await repo.restoreSession()
        }
    }
}

// MARK: - Login

struct LoginScreen: View {
    @EnvironmentObject private var services: AppServices
    private var repo: ChatRepository { services.repository }
    private var chat: ChatState { repo.state }

    @State private var name = ""
    @State private var gender = ""
    @State private var age = "18"
    @State private var country = "Germany"

    private var genderRows: [GenderOptionRow] {
        [
            GenderOptionRow(value: "F", label: L10n.tr("gender_female")),
            GenderOptionRow(value: "M", label: L10n.tr("gender_male")),
            GenderOptionRow(value: "P", label: L10n.tr("gender_pair")),
            GenderOptionRow(value: "TF", label: L10n.tr("gender_trans_mf")),
            GenderOptionRow(value: "TM", label: L10n.tr("gender_trans_fm")),
        ]
    }

    private var countryRows: [CountryOption] {
        if chat.countries.isEmpty {
            return [CountryOption(englishName: "Germany", displayName: "Germany", isoCode: "de")]
        }
        return chat.countries
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 16) {
                    landingIntroCard
                    profileCard
                }
                .padding(16)
            }
            .background(
                LinearGradient(colors: [YpChatTheme.bgApp, YpChatTheme.bgShell], startPoint: .top, endPoint: .bottom)
            )
            .navigationTitle(L10n.tr("app_name"))
            .navigationBarTitleDisplayMode(.inline)
        }
        .onChange(of: chat.savedProfile) { _, _ in syncProfile() }
        .onAppear { syncProfile() }
    }

    private func syncProfile() {
        name = chat.savedProfile.nickname
        gender = chat.savedProfile.gender
        age = "\(chat.savedProfile.age)"
        country = chat.savedProfile.country
    }

    private var landingIntroCard: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text(L10n.tr("landing_eyebrow"))
                .font(.caption.weight(.bold))
                .foregroundStyle(Color(red: 0.29, green: 0.38, blue: 0.33))
            Text(L10n.tr("landing_title"))
                .font(.title2.weight(.black))
                .foregroundStyle(YpChatTheme.textStrong)
            Text(L10n.tr("landing_copy"))
                .font(.body)
                .foregroundStyle(Color(red: 0.31, green: 0.36, blue: 0.33))
            HStack(spacing: 8) {
                featureChip(L10n.tr("feature_worldwide_chat"))
                featureChip(L10n.tr("feature_image_exchange"))
            }
            featureChip(L10n.tr("feature_compact_controls"))
        }
        .padding(24)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(Color(red: 0.96, green: 0.98, blue: 0.96))
                .shadow(color: .black.opacity(0.04), radius: 2, y: 1)
        )
        .overlay(
            RoundedRectangle(cornerRadius: 20)
                .stroke(Color(red: 0.81, green: 0.88, blue: 0.83), lineWidth: 1)
        )
    }

    private func featureChip(_ text: String) -> some View {
        Text(text)
            .font(.caption.weight(.bold))
            .foregroundStyle(YpChatTheme.primary700)
            .padding(.horizontal, 12)
            .padding(.vertical, 7)
            .background(Color(red: 0.89, green: 0.94, blue: 0.90), in: Capsule())
    }

    private var profileCard: some View {
        VStack(alignment: .leading, spacing: 14) {
            Text(L10n.tr("profile_title"))
                .font(.headline.weight(.bold))
                .foregroundStyle(YpChatTheme.textStrong)
            Text(L10n.tr("profile_copy"))
                .font(.subheadline)
                .foregroundStyle(YpChatTheme.textMuted)

            TextField(L10n.tr("label_nick"), text: $name)
                .textFieldStyle(.roundedBorder)

            Picker(L10n.tr("label_gender"), selection: $gender) {
                Text("").tag("")
                ForEach(genderRows) { row in
                    Text(row.label).tag(row.value)
                }
            }
            .pickerStyle(.menu)

            TextField(L10n.tr("label_age"), text: $age)
                .keyboardType(.numberPad)
                .textFieldStyle(.roundedBorder)

            Picker(L10n.tr("label_country"), selection: $country) {
                ForEach(countryRows, id: \.englishName) { c in
                    Text(c.displayName).tag(c.englishName)
                }
            }
            .pickerStyle(.menu)

            Button {
                let ageInt = Int(age) ?? 18
                Task {
                    await repo.login(userName: name, gender: gender, age: ageInt, country: country)
                }
            } label: {
                Text(L10n.tr("button_start_chat"))
                    .frame(maxWidth: .infinity)
            }
            .buttonStyle(.borderedProminent)
            .tint(YpChatTheme.primary600)
            .disabled(name.count < 3 || gender.isEmpty || country.isEmpty)

            if let err = chat.errorMessage {
                Text(localizeRuntimeMessage(err))
                    .font(.footnote)
                    .foregroundStyle(YpChatTheme.danger)
            }

            Text(chat.isConnected ? L10n.tr("socket_connected") : L10n.tr("socket_connecting"))
                .font(.footnote)
                .foregroundStyle(YpChatTheme.textMuted)
        }
        .padding(24)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(YpChatTheme.surface.opacity(0.99))
        )
        .overlay(
            RoundedRectangle(cornerRadius: 20)
                .stroke(Color(red: 0.83, green: 0.87, blue: 0.84), lineWidth: 1)
        )
    }
}

// MARK: - Shell

struct ChatShellView: View {
    @EnvironmentObject private var services: AppServices
    private var repo: ChatRepository { services.repository }
    private var chat: ChatState { repo.state }

    @State private var selectedTab: AppTab = .online
    @State private var moreSection: MoreSection = .overview

    var body: some View {
        VStack(spacing: 0) {
            topStatusBar
            Divider()
            Group {
                if chat.currentConversation != nil {
                    YpChatConversationView()
                } else {
                    tabContent
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            if chat.currentConversation == nil {
                bottomTabBar
            }
        }
        .background(YpChatTheme.bgShell)
        .onChange(of: selectedTab) { _, new in
            switch new {
            case .inbox: repo.requestInbox()
            case .history: repo.requestHistory()
            case .more:
                Task {
                    await repo.loadFeedback()
                    await repo.loadFeedbackAdminStatus()
                    await repo.loadPartners()
                }
            default: break
            }
        }
    }

    private var topStatusBar: some View {
        HStack(alignment: .top) {
            VStack(alignment: .leading, spacing: 4) {
                Text(L10n.tr("app_name"))
                    .font(.headline.weight(.bold))
                    .foregroundStyle(YpChatTheme.primary700)
                Text("\(chat.currentUser?.userName ?? "") – \(chat.isConnected ? L10n.tr("status_online") : L10n.tr("status_connecting"))")
                    .font(.subheadline)
                    .foregroundStyle(YpChatTheme.textMuted)
                Text(L10n.timeoutIn(formatTimeout(totalSeconds: chat.remainingSecondsToTimeout)))
                    .font(.caption)
                    .foregroundStyle(YpChatTheme.textMuted)
            }
            Spacer()
            Button(L10n.tr("logout")) {
                Task { await repo.logout() }
            }
            .foregroundStyle(YpChatTheme.primary700)
        }
        .padding(16)
        .background(
            LinearGradient(
                colors: [
                    Color(red: 0.82, green: 0.91, blue: 0.85),
                    Color(red: 0.92, green: 0.96, blue: 0.93),
                    Color(red: 0.97, green: 0.98, blue: 0.97),
                ],
                startPoint: .top,
                endPoint: .bottom
            )
        )
    }

    private var bottomTabBar: some View {
        HStack(spacing: 0) {
            ForEach(AppTab.allCases) { tab in
                Button {
                    selectedTab = tab
                    if tab != .more { moreSection = .overview }
                } label: {
                    VStack(spacing: 4) {
                        Image(systemName: icon(for: tab))
                            .font(.system(size: 18))
                        Text(tabLabel(tab))
                            .font(.caption2)
                            .lineLimit(1)
                            .minimumScaleFactor(0.7)
                    }
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 8)
                    .foregroundStyle(selectedTab == tab ? YpChatTheme.primary700 : YpChatTheme.textMuted)
                    .background(selectedTab == tab ? YpChatTheme.primary100.opacity(0.6) : Color.clear)
                }
                .buttonStyle(.plain)
            }
        }
        .background(YpChatTheme.surface)
        .overlay(Divider(), alignment: .top)
    }

    private func icon(for tab: AppTab) -> String {
        switch tab {
        case .online: return "person.2"
        case .search: return "magnifyingglass"
        case .inbox: return "tray"
        case .history: return "clock"
        case .console: return "terminal"
        case .more: return "ellipsis.circle"
        }
    }

    private func tabLabel(_ tab: AppTab) -> String {
        let base = L10n.tr(tab.titleKey)
        if tab == .inbox, chat.unreadChatsCount > 0 {
            return "\(base) (\(chat.unreadChatsCount))"
        }
        return base
    }

    @ViewBuilder
    private var tabContent: some View {
        switch selectedTab {
        case .online:
            UserListView()
        case .search:
            SearchTabView()
        case .inbox:
            InboxTabView()
        case .history:
            HistoryTabView()
        case .console:
            ConsoleTabView()
        case .more:
            MoreTabView(section: $moreSection)
        }
    }
}

// MARK: - Online / Search

struct UserListView: View {
    @EnvironmentObject private var services: AppServices
    private var repo: ChatRepository { services.repository }
    private var chat: ChatState { repo.state }

    var body: some View {
        ScrollView {
            LazyVStack(alignment: .leading, spacing: 10) {
                Text(L10n.tr("tab_online"))
                    .font(.title2.weight(.bold))
                    .padding(.horizontal, 16)
                if chat.users.isEmpty {
                    Text(L10n.tr("no_users_online"))
                        .foregroundStyle(YpChatTheme.textMuted)
                        .padding(.horizontal, 16)
                }
                ForEach(chat.users, id: \.userName) { user in
                    userRow(user)
                }
            }
            .padding(.vertical, 16)
        }
    }

    private func userRow(_ user: UserDto) -> some View {
        Button {
            repo.openConversation(userName: user.userName)
        } label: {
            HStack {
                Text(user.userName).fontWeight(.semibold)
                Spacer()
                Text("\(user.age) – \(displayCountryName(user: user, countries: chat.countries))")
                    .font(.subheadline)
                    .foregroundStyle(YpChatTheme.textMuted)
            }
            .padding(16)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(YpChatTheme.surface, in: RoundedRectangle(cornerRadius: 12))
        }
        .buttonStyle(.plain)
        .padding(.horizontal, 16)
    }
}

struct SearchTabView: View {
    @EnvironmentObject private var services: AppServices
    private var repo: ChatRepository { services.repository }
    private var chat: ChatState { repo.state }

    @State private var query = ""
    @State private var minAge = ""
    @State private var maxAge = ""
    @State private var country = ""
    @State private var gender = ""
    @State private var localError: String?
    @State private var hasSearched = false

    private var countryRows: [CountryOption] {
        if chat.countries.isEmpty {
            return [CountryOption(englishName: "Germany", displayName: "Germany", isoCode: "de")]
        }
        return chat.countries
    }

    private var genderRows: [GenderOptionRow] {
        [
            GenderOptionRow(value: "", label: L10n.tr("search_all")),
            GenderOptionRow(value: "F", label: L10n.tr("gender_female")),
            GenderOptionRow(value: "M", label: L10n.tr("gender_male")),
            GenderOptionRow(value: "P", label: L10n.tr("gender_pair")),
            GenderOptionRow(value: "TF", label: L10n.tr("gender_trans_mf")),
            GenderOptionRow(value: "TM", label: L10n.tr("gender_trans_fm")),
        ]
    }

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 12) {
                Text(L10n.tr("tab_search"))
                    .font(.title2.weight(.bold))

                TextField(L10n.tr("search_username_includes"), text: $query)
                    .textFieldStyle(.roundedBorder)

                HStack {
                    TextField(L10n.tr("search_from_age"), text: $minAge)
                        .keyboardType(.numberPad)
                        .textFieldStyle(.roundedBorder)
                    TextField(L10n.tr("search_to_age"), text: $maxAge)
                        .keyboardType(.numberPad)
                        .textFieldStyle(.roundedBorder)
                }

                Picker(L10n.tr("label_country"), selection: $country) {
                    Text(L10n.tr("search_all")).tag("")
                    ForEach(countryRows, id: \.englishName) { c in
                        Text(c.displayName).tag(c.englishName)
                    }
                }
                .pickerStyle(.menu)

                Picker(L10n.tr("label_gender"), selection: $gender) {
                    ForEach(genderRows) { row in
                        Text(row.label).tag(row.value)
                    }
                }
                .pickerStyle(.menu)

                if let localError {
                    Text(localError).foregroundStyle(YpChatTheme.danger)
                }

                Button(L10n.tr("search_button")) {
                    let min = Int(minAge)
                    let max = Int(maxAge)
                    if let min, let max, min > max {
                        localError = L10n.tr("search_min_age_error")
                        return
                    }
                    localError = nil
                    hasSearched = true
                    repo.search(
                        nameIncludes: query.isEmpty ? nil : query,
                        minAge: min,
                        maxAge: max,
                        countries: country.isEmpty ? [] : [country],
                        genders: gender.isEmpty ? [] : [gender]
                    )
                }
                .buttonStyle(.borderedProminent)
                .tint(YpChatTheme.primary600)

                if hasSearched, chat.searchResults.isEmpty {
                    Text(L10n.tr("search_no_results"))
                        .foregroundStyle(YpChatTheme.textMuted)
                }

                ForEach(chat.searchResults, id: \.userName) { user in
                    Button {
                        repo.openConversation(userName: user.userName)
                    } label: {
                        HStack {
                            Text(user.userName).fontWeight(.semibold)
                            Spacer()
                            Text("\(user.age) – \(displayCountryName(user: user, countries: chat.countries))")
                                .font(.subheadline)
                                .foregroundStyle(YpChatTheme.textMuted)
                        }
                        .padding(16)
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .background(YpChatTheme.surface, in: RoundedRectangle(cornerRadius: 12))
                    }
                    .buttonStyle(.plain)
                }
            }
            .padding(16)
        }
    }
}
