import SwiftUI

struct CalendarView: View {
    var validDates: [Date]
    @Binding var selectedDate: Date?
    
    private var weeks: [[Date]] {
        guard let firstDate = validDates.first,
                let lastDate = validDates.last else {
            return []
        }
        
        let firstWeekOfYear = Calendar.current.component(.weekOfYear, from: firstDate)
        let finalWeekOfYear = Calendar.current.component(.weekOfYear, from: lastDate)
        let firstYear = Calendar.current.component(.year, from: firstDate)
        let finalYear = Calendar.current.component(.year, from: lastDate)
        
        var weeks: [[Date]] = []
        
        var yearInQuestion = firstYear
        var weekInQuestion = firstWeekOfYear
        while yearInQuestion <= finalYear && weekInQuestion <= finalWeekOfYear {
            
            weeks.append( Array(1...7).compactMap { DateComponents(calendar: Calendar.current,
                                                                   timeZone: Calendar.current.timeZone,
                                                                   year: yearInQuestion,
                                                                   weekday: $0,
                                                                   weekOfYear: weekInQuestion).date })
            
            if weekInQuestion > 53 {
                weekInQuestion = 1
                yearInQuestion += 1
            } else {
                weekInQuestion += 1
            }
        }
        
        return weeks
    }
    
    func dateContainsEvent(_ date: Date) -> Bool {
        return validDates.first(where: { Calendar.current.isDate($0, inSameDayAs: date) }) != nil
    }
    
    var body: some View {
        TabView {
            ForEach(weeks, id: \.self) { week in
                LazyVGrid(columns: Array(repeating: GridItem(.adaptive(minimum: 45)), count: 7)) {
                    ForEach(week, id: \.self) { day in
                        Button {
                            if dateContainsEvent(day) {
                                selectedDate = day
                            }
                        } label: {
                            CalendarCell(date: day, hasEvent: dateContainsEvent(day))
                                .frame(maxWidth: .infinity)
                        }
                    }
                }
                .frame(maxWidth: .infinity)
            }
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
    }
}

struct CalendarCell: View {
    var date: Date
    var hasEvent: Bool
    
    var isToday: Bool {
        Calendar.current.isDateInToday(date)
    }
    
    var body: some View {
        HStack {
            Spacer()
        
            VStack(alignment: .center, spacing: 0) {
                Text(DateFormatter.shortDayName.string(from: date))
                    .textStyle(.caption1)
                
                Text(DateFormatter.dayNumber.string(from: date))
                    .textStyle(.headline, color: isToday ? ColorName.background.color : ColorName.text.color )
                    .padding(3)
                    .background(
                        Circle().fill(isToday ? ColorName.text.color : Color.clear)
                    )
            }
            
            Spacer()
        }
        .opacity(hasEvent ? 1 : 0.3)
    }
}
