import SwiftUI

// 设备间文本消息（#13）：聊天式列表 + 底部撰写栏。消息由引擎经桥推来（in-memory，关 app 即清，
// 对齐 web 语义），收发都经 POST /api/message（hub SendTo 实时转发；对端离线则后端发推送）。
// 可发给任意非本机设备（在线即时达、离线走推送），故目标取全部非本机设备而非仅在线。
struct MessagesView: View
{
    @Environment(EngineController.self) private var engine
    @State private var draft = ""
    @State private var target = ""
    @State private var showClearConfirm = false

    // 可发消息的目标：全部非本机设备（按 device_id 判本机，与设备名解耦）。
    private var targets: [DeviceItem]
    {
        let selfID = engine.selfDeviceID
        return engine.devices.filter
        { d in
            if !selfID.isEmpty, !d.deviceID.isEmpty { return d.deviceID != selfID }
            return d.name != engine.deviceName
        }
    }

    // store 是最新在前；聊天式从上到下需旧→新。
    private var ordered: [MessageItem] { engine.messages.reversed() }

    var body: some View
    {
        VStack(spacing: 0)
        {
            if engine.messages.isEmpty
            {
                ContentUnavailableView(t("ios.messages.empty"), systemImage: "message")
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            else
            {
                ScrollViewReader
                { proxy in
                    ScrollView
                    {
                        LazyVStack(alignment: .leading, spacing: 10)
                        {
                            ForEach(ordered)
                            { msg in
                                messageRow(msg)
                                    .id(msg.id)
                                    .contextMenu
                                    {
                                        Button(role: .destructive) { engine.deleteMessage(msg.id) }
                                        label: { Label(t("transfer.action.delete"), systemImage: "trash") }
                                    }
                            }
                        }
                        .padding()
                    }
                    .onChange(of: engine.messages.count) { scrollToLast(proxy) }
                    .onAppear { scrollToLast(proxy) }
                }
            }
            composeBar
        }
        .navigationTitle(t("ios.tab.messages"))
        .toolbar
        {
            if !engine.messages.isEmpty
            {
                ToolbarItem(placement: .topBarTrailing)
                {
                    Button(role: .destructive) { showClearConfirm = true }
                    label: { Label(t("ios.records.clear"), systemImage: "trash") }
                }
            }
        }
        .confirmationDialog(t("ios.records.clearConfirm"), isPresented: $showClearConfirm, titleVisibility: .visible)
        {
            Button(t("ios.records.clear"), role: .destructive) { engine.clearMessages() }
            Button(t("common.cancel"), role: .cancel) { }
        }
        .onAppear { if target.isEmpty { target = targets.first?.name ?? "" } }
    }

    private func scrollToLast(_ proxy: ScrollViewProxy)
    {
        guard let last = ordered.last else { return }
        withAnimation { proxy.scrollTo(last.id, anchor: .bottom) }
    }

    private func messageRow(_ msg: MessageItem) -> some View
    {
        let outgoing = msg.direction == "outgoing"
        return HStack
        {
            if outgoing { Spacer(minLength: 48) }
            VStack(alignment: outgoing ? .trailing : .leading, spacing: 2)
            {
                Text(msg.peerName)
                    .font(.caption2)
                    .foregroundStyle(.secondary)
                Text(msg.text)
                    .padding(.horizontal, 12)
                    .padding(.vertical, 8)
                    .background(outgoing ? Color.cdropAccent.opacity(0.18) : Color(.secondarySystemBackground),
                                in: RoundedRectangle(cornerRadius: 14))
                    .textSelection(.enabled)
            }
            if !outgoing { Spacer(minLength: 48) }
        }
        .frame(maxWidth: .infinity, alignment: outgoing ? .trailing : .leading)
    }

    @ViewBuilder
    private var composeBar: some View
    {
        VStack(spacing: 6)
        {
            if targets.isEmpty
            {
                Text(t("ios.messages.noPeers"))
                    .font(.caption)
                    .foregroundStyle(.secondary)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
            else
            {
                HStack(spacing: 10)
                {
                    Menu
                    {
                        ForEach(targets)
                        { dev in
                            Button(dev.name) { target = dev.name }
                        }
                    }
                    label:
                    {
                        Label(target.isEmpty ? t("ios.send.pickDevice") : target,
                              systemImage: "chevron.up.chevron.down")
                            .font(.caption)
                            .lineLimit(1)
                    }
                    TextField(t("ios.messages.placeholder"), text: $draft, axis: .vertical)
                        .textFieldStyle(.roundedBorder)
                        .lineLimit(1...4)
                        .submitLabel(.send)
                        .onSubmit { send() }
                    Button { send() }
                    label: { Image(systemName: "paperplane.fill").font(.title3) }
                        .disabled(draft.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || target.isEmpty)
                }
            }
        }
        .padding()
        .background(.bar)
    }

    private func send()
    {
        let text = draft.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !text.isEmpty, !target.isEmpty else { return }
        engine.sendMessage(to: target, text: text)
        draft = ""
    }
}
