import ActivityKit
import WidgetKit
import SwiftUI

@main
struct Widgets: WidgetBundle {
  var body: some Widget {
      if #available(iOS 16.2, *) {
          LiveCardWidget()
    }
  }
}

// text contrast background
extension Text {
    func getContrastText(backgroundColor: Color) -> some View {
        var r, g, b, a: CGFloat
        (r, g, b, a) = (0, 0, 0, 0)
        UIColor(backgroundColor).getRed(&r, green: &g, blue: &b, alpha: &a)
        let luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
        return  luminance < 0.6 ? self.foregroundColor(.white) : self.foregroundColor(.black)
    }
}

// Color Converter
extension Color {
    init(hex: String, alpha: Double = 1.0) {
        var hexValue = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

        if hexValue.hasPrefix("#") {
            hexValue.remove(at: hexValue.startIndex)
        }

        var rgbValue: UInt64 = 0
        Scanner(string: hexValue).scanHexInt64(&rgbValue)

        let red = Double((rgbValue & 0xFF0000) >> 16) / 255.0
        let green = Double((rgbValue & 0x00FF00) >> 8) / 255.0
        let blue = Double(rgbValue & 0x0000FF) / 255.0

        self.init(
            .sRGB,
            red: red,
            green: green,
            blue: blue,
            opacity: alpha
        )
    }
}

struct LockScreenLiveActivityView: View {
    let context: ActivityViewContext<LiveActivitiesAppAttributes>

    var body: some View {
        HStack(alignment: .center) {
            // Ikon
            Image(systemName: context.state.icon)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: CGFloat(30), height: CGFloat(30))
                .padding(.leading, CGFloat(24))

            VStack(alignment: .center) {
                // Jelenlegi óra
                VStack {
                  if(context.state.title.contains("Az első órádig")) {
                    Text(context.state.title)
                      .font(.system(size: 15))
                      .bold()
                      .multilineTextAlignment(.center)
                  } else if(context.state.title == "Szünet") {
                    Text(context.state.title)
                      .font(.body)
                      .bold()
                      .padding(.trailing, 90)
                  } else {
                    MultilineTextView(text: "\(context.state.index) \(context.state.title) -  \(context.state.subtitle)", limit: 25)
                      .font(.body)
                      .bold()
                      .multilineTextAlignment(.center)
                  }
                }

                // Leírás
                if (context.state.description != "") {
                  Text(context.state.description)
                    .font(.subheadline)
                }

                // Következő óra
              if(context.state.nextSubject != "" && context.state.nextRoom != "") {
                HStack {
                    Image(systemName: "arrow.right")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: CGFloat(8), height: CGFloat(8))
                        .foregroundStyle(.secondary)
                  Text("\(context.state.nextSubject) -  \(context.state.nextRoom)")
                        .font(.caption)
                }
                .multilineTextAlignment(.center)
              } else {
                Spacer(minLength: 5)
                Text("Ez az utolsó óra! Kitartást!")
                  .font(.system(size: 15))
              }
                
            }
            .padding(15)

            Spacer()

            // Visszaszámláló
            Text(timerInterval: context.state.date, countsDown: true)
                .multilineTextAlignment(.center)
                .frame(width: 85)
                .font(.title2)
                .monospacedDigit()
                .padding(.trailing)
        }
//        .activityBackgroundTint(
//            context.state.color != "#676767"
//            ? Color(hex: context.state.color)
//            : Color.clear
//        )
        .activityBackgroundTint(
          Color.clear
        )
        .foregroundStyle(Color(hex: context.state.color))
    }
}

@available(iOSApplicationExtension 16.2, *)
struct LiveCardWidget: Widget {
    var body: some WidgetConfiguration {
        /// Live Activity Notification
        ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
            LockScreenLiveActivityView(context: context)
            /// Dynamic Island
        } dynamicIsland: { context in

            /// Expanded
            return DynamicIsland {
                DynamicIslandExpandedRegion(.leading) {
                    VStack {
                        Spacer()
                        ProgressView(
                            timerInterval: context.state.date,
                            countsDown: true,
                            label: {
                                Image(systemName: context.state.icon)
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: CGFloat(32), height: CGFloat(32))
                            },
                            currentValueLabel: {
                                Image(systemName: context.state.icon)
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: CGFloat(32), height: CGFloat(32))
                            }
                        ).progressViewStyle(.circular)
                    }
                }
              DynamicIslandExpandedRegion(.center) {
                VStack(alignment: .center) {
                  // Első óra előtti expanded DynamicIsland
                  if(context.state.title.contains("Az első órádig")) {
                    Text("Az első órád:")
                      .font(.body)
                      .bold()
                      .padding(.trailing, -15)
                    MultilineTextView(text: "\(context.state.nextSubject)", limit: 25)
                      .font(.body)
                      .padding(.trailing, -25)
                    
                    Text("Ebben a teremben:")
                      .font(.body)
                      .bold()
                      .padding(.leading, 15)
                    Text(context.state.nextRoom)
                      .font(.body)
                      .padding(.leading, 15)
                  } else if(context.state.title == "Szünet") {
                    // Amikor szünet van, expanded DynamicIsland
                    Text(context.state.title)
                      .lineLimit(1)
                      .font(.body)
                      .bold()
                      .padding(.leading, 15)
                    
                    Spacer(minLength: 5)
                    Text("Következő óra és terem:")
                      .font(.system(size: 13))
                      .padding(.leading, 25)
                    Text(context.state.nextSubject)
                      .font(.caption)
                      .padding(.leading, 15)
                    Text(context.state.nextRoom)
                      .font(.caption2)
                      .padding(.leading, 15)
                    
                  } else {
                    // Amikor óra van, expanded DynamicIsland
                    MultilineTextView(text: "\(context.state.index) \(context.state.title) - \(context.state.subtitle)", limit: 25)
                      .lineLimit(1)
                      .font(.body)
                      .bold()
                      .padding(.trailing, -35)
                    
                    Spacer(minLength: 2)
                    
                    if(context.state.nextRoom != "" && context.state.nextSubject != "") {
                      Text("Következő óra és terem:")
                        .font(.system(size: 14))
                        .padding(.trailing, -45)
                      Spacer(minLength: 2)
                      
                      Text("\(context.state.nextSubject) - \(context.state.nextRoom)")
                        .modifier(DynamicFontSizeModifier(text: "\(context.state.nextSubject) - \(context.state.nextRoom)"))
                        .padding(.trailing, 35)
                    } else {
                      Text("Ez az utolsó óra! Kitartást!")
                        .font(.system(size: 14))
                        .padding(.trailing, -30)
                    }
                  }
                  
                  
                }.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
                
              }

                /// Compact
            } compactLeading: {
                  Image(systemName: context.state.icon)
            }
        compactTrailing: {
            Text(timerInterval: context.state.date, countsDown: true)
                .multilineTextAlignment(.center)
                .frame(width: 40)
                .font(.caption2)

            /// Collapsed
        } minimal: {
            VStack(alignment: .center, content: {
                ProgressView(
                    timerInterval: context.state.date,
                    countsDown: true,
                    label: {
                        Image(systemName: context.state.icon)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: CGFloat(12), height: CGFloat(12))
                    },
                    currentValueLabel: {
                        Image(systemName: context.state.icon)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: CGFloat(12), height: CGFloat(12))
                    }
                ).progressViewStyle(.circular)
            })
        }
        .keylineTint(
            context.state.color != "#676767"
            ? Color(hex: context.state.color)
            : Color.clear
           )
        }
    }
}

struct MultilineTextView: View {
    var text: String
    var limit: Int = 20 // default is 20 character

    var body: some View {
        let words = text.split(separator: " ")
        var currentLine = ""
        var lines: [String] = []

        for word in words {
            if (currentLine.count + word.count + 1) > limit {
                lines.append(currentLine)
                currentLine = ""
            }
            if !currentLine.isEmpty {
                currentLine += " "
            }
            currentLine += word
        }
        if !currentLine.isEmpty {
            lines.append(currentLine)
        }

        return VStack(alignment: .center) {
            ForEach(lines, id: \.self) { line in
                Text(line)
            }
          Spacer(minLength: 1)
        }
    }
}

struct DynamicFontSizeModifier: ViewModifier {
    var text: String

    func body(content: Content) -> some View {
        content
            .font(.system(size: fontSize(for: text)))
    }

    private func fontSize(for text: String) -> CGFloat {
        let length = text.count
        if length < 10 {
            return 12
        } else if length < 20 {
            return 12
        } else {
            return 11
        }
    }
}

struct LiveCardWidget_Previews: PreviewProvider {

    static let attributes = LiveActivitiesAppAttributes()
    
    static let duringLessonExmaple = LiveActivitiesAppAttributes.ContentState(
      color: "#FF5733",
      icon: "bell",
      index: "1.",
      title: "Math Class",
      subtitle: "101",
      description: "Algebra lesson",
      startDate: Date(),
      endDate: Date().addingTimeInterval(3000),
      date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
      nextSubject: "Physics",
      nextRoom: "102"
    )
  
    static let inBreak = LiveActivitiesAppAttributes.ContentState(
      color: "#FF5733",
      icon: "house",
      index: "",
      title: "Szünet",
      subtitle: "Menj a(z) 122 terembe.",
      description: "",
      startDate: Date(),
      endDate: Date().addingTimeInterval(3000),
      date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
      nextSubject: "Physics",
      nextRoom: "122"
    )
  
    static let lastLesson = LiveActivitiesAppAttributes.ContentState(
      color: "#00ff00",
      icon: "bell",
      index: "6.",
      title: "Math Class",
      subtitle: "",
      description: "Lorem Ipsum",
      startDate: Date(),
      endDate: Date().addingTimeInterval(3000),
      date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
      nextSubject: "",
      nextRoom: ""
    )

    static var previews: some View {
      // Dynamic Island Compact
      Group {
        attributes
          .previewContext(duringLessonExmaple, viewKind: .dynamicIsland(.compact))
          .previewDisplayName("During Lesson")
        attributes
          .previewContext(inBreak, viewKind: .dynamicIsland(.compact))
          .previewDisplayName("In Break")
        attributes
          .previewContext(lastLesson, viewKind: .dynamicIsland(.compact))
          .previewDisplayName("During Last Lesson")
      }
    }
    
}