PKDetailView.swift 9.29 KB
//
//  PKDetailView.swift
//  hippo-watch Watch App
//
//  Created by shihao on 2025/7/7.
//

import Foundation
import SwiftUI
import SDWebImageSwiftUI

struct PKDetailView: View {
    @Environment(\.presentationMode) var presentationMode
    @StateObject private var vm = PKDetailViewModel()
    @ObservedObject var userinfoManager = WatchUserinfoManager.share
    @ObservedObject var dataManager = WatchDataManager.share
    
    var body: some View {
        ScrollView {
            VStack(spacing: 4.x) {
                // 顶部用户头像
                HStack(spacing: 0) {
                    Spacer()
                    ZStack {
                        WebImage(url: userinfoManager.myUserinfo?.avatar?.url)
                            .resizable()
                            .frame(width: 36.x, height: 36.x)
                            .background(.clear)
                            .clipShape(Circle())
                            .overlay(Circle().stroke(Color(hex: "#FF896CDC"), lineWidth: 1.x))
                        
                        if isMeWinner {
                            // 皇冠图标
                            Image(.pkPageCrown)
                                .offset(x: 11.x, y: -20.x)
                        }
                    }
                    
                    Spacer()
                    
                    ZStack {
                        WebImage(url: userinfoManager.otherUserinfo?.avatar?.url)
                            .resizable()
                            .frame(width: 36.x, height: 36.x)
                            .background(.clear)
                            .clipShape(Circle())
                            .overlay(Circle().stroke(Color(hex: "#FFFFF45B"), lineWidth: 1.x))
                        
                        if !isMeWinner {
                            // 皇冠图标
                            Image(.pkPageCrown)
                                .offset(x: 11.x, y: -20.x)
                        }
                    }
                    Spacer()
                }
                
                Spacer()
                    .frame(height: 10.x)
                
                // 步数对比
                HealthComparisonCard(
                    icon: .todayDataStep,
                    title: "今日步数",
                    leftValue: myStep?.string ?? "-",
                    rightValue: otherStep?.string ?? "-",
                    progress: stepProgerss,
                    isLeftWinning: true
                )
                
                // 睡眠时间对比
                HealthComparisonCard(
                    icon: .pkPageSleepIcon,
                    title: "睡眠时间",
                    leftValue: toSleepTimeDesc(mySleep),
                    rightValue: toSleepTimeDesc(otherSleep),
                    progress: sleepProgress,
                    isLeftWinning: false
                )
                
                // 活动记录对比
                HealthComparisonCard(
                    icon: .todayDataActivity,
                    title: "活动记录",
                    leftValue: "\(myActivity?.string ?? "-")千卡",
                    rightValue: "\(otherActivity?.string ?? "-")千卡",
                    progress: activityProgress,
                    isLeftWinning: true
                )
            }
            .padding(.horizontal, 8.x)
            .padding(.bottom, 20)
        }
        .background(Color.black)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Text("PK")
                    .font(.system(size: 17))
                    .foregroundColor(.white)
            }
        }
        .onAppear {
            vm.refreshData()
            ThinkSDKUtil.track(eventName: "enter_doublefeel_watch_page",
                               properties: ["page_type": "PK"])
        }
    }
    
    private var isMeWinner: Bool {
        let step = stepProgerss > 0.5 ? 1 : 0
        let sleep = sleepProgress > 0.5 ? 1 : 0
        let activity = activityProgress > 0.5 ? 1 : 0
        
        let total = step + sleep + activity
        return total > 1
    }
    
    private var myStep: Int? {
        return dataManager.myTodayStepCount
    }
    
    private var otherStep: Int? {
        return dataManager.otherTodayHealthInfo?.recentData?.steps
    }
    
    private var stepProgerss: Double {
        let mine = (myStep ?? 0).double
        let other = (otherStep ?? 0).double
        if mine == 0 && other == 0 {
            return 0.5
        }
        return mine / (mine + other)
    }
    
    private var mySleep: TimeInterval? {
        return dataManager.myTodaySleepTime
    }
    
    private var otherSleep: TimeInterval? {
        return dataManager.otherTodayHealthInfo?.sleepDuration.double
    }
    
    private var sleepProgress: Double {
        let mine = mySleep ?? 0
        let other = otherSleep ?? 0
        if mine == 0 && other == 0 {
            return 0.5
        }
        return mine / (mine + other)
    }
    
    private var myActivity: Int? {
        return dataManager.myTodayActiveEnergy?.int
    }
    
    private var otherActivity: Int? {
        return dataManager.otherTodayHealthInfo?.recentData?.move
    }
    
    private var activityProgress: Double {
        let mine = (myActivity ?? 0).double
        let other = (otherActivity ?? 0).double
        if mine == 0 && other == 0 {
            return 0.5
        }
        return mine / (mine + other)
    }
    
    private func toSleepTimeDesc(_ duration: Double?) -> String {
        guard let duration else {
            return "-"
        }
        
        let totalMinutes = Int(duration / 60)
        let hours = totalMinutes / 60
        let minutes = totalMinutes % 60
        
        return "\(hours)小时\(minutes)分"
    }
}

struct HealthComparisonCard: View {
    let icon: ImageResource
    let title: String
    let leftValue: String
    let rightValue: String
    let progress: Double
    let isLeftWinning: Bool
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            // 标题行
            HStack {
                Image(icon)
                    .resizable()
                    .frame(width: 16.x, height: 16.x)
                
                Text(title)
                    .foregroundColor(.white)
                    .font(.system(size: 14))
                    .fontWeight(.regular)
            }
            
            // 数值对比
            HStack {
                Text(leftValue)
                    .foregroundColor(leftTextColor)
                    .font(.system(size: 12))
                    .fontWeight(.semibold)
                
                Spacer()
                
                Text(rightValue)
                    .foregroundColor(rightTextColor)
                    .font(.system(size: 12))
                    .fontWeight(.regular)
            }
            .padding(.top, 13.x)
            
            // 进度条
            ZStack(alignment: .leading) {
                
                // 进度条
                GeometryReader { geometry in
                    ZStack(alignment: .topLeading) {
                        HStack(spacing: 0) {
                            // 左侧进度(粉色)
                            Rectangle()
                                .fill(
                                    Color(hex: "#FFFFD3E5")
                                )
                                .frame(width: geometry.size.width * progress,
                                       height: 12.x)
                                .cornerRadius(6.x, corners: [.topLeft, .bottomLeft])
                            
                            // 右侧进度(蓝色)
                            Rectangle()
                                .fill(
                                    Color(hex: "#FFC5DFFF")
                                )
                                .frame(width: geometry.size.width * (1 - progress),
                                       height: 12.x)
                                .cornerRadius(6.x, corners: [.topRight, .bottomRight])
                        }
                        
                        // 中间分割点
                        Circle()
                            .fill(Color(hex: "#FFFFD2A1"))
                            .stroke(Color.black, lineWidth: 2.x)
                            .frame(width: 16.x, height: 16.x)
                            .offset(x: circleOffsetx(geometryWidth: geometry.size.width),
                                    y: -2.x)
                    }
                }
                
                
            }
            .padding(.top, 8.x)
            .padding(.bottom, 7.x)
        }
        .padding(6.x)
        .background(
            RoundedRectangle(cornerRadius: 16.x)
                .fill(Color.gray.opacity(0.31))
        )
    }
    
    private func circleOffsetx(geometryWidth: CGFloat) -> CGFloat {
        if progress == 0 {
            return -2.x
        }
        if progress == 1 {
            return progress * geometryWidth - 10.x
        }
        return progress * geometryWidth - 8.x
    }
    
    private var leftTextColor: Color {
        return progress > 0.5 ? .init(hex: "#FFFFA51B") : .white.opacity(0.31)
    }
    
    private var rightTextColor: Color {
        return progress < 0.5 ? .init(hex: "#FFFFA51B") : .white.opacity(0.31)
    }
}