//
//  PinnedTimelinesView.swift
//  Tusker
//
//  Created by Shadowfacts on 12/20/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import SwiftUI
import Pachyderm

struct PinnedTimelinesView: View {
    @EnvironmentObject private var mastodonController: MastodonController
    @ObservedObject private var accountPreferences: AccountPreferences
    
    @State private var isShowingAddHashtagSheet = false
    @State private var isShowingAddInstanceSheet = false
    // store this separately from AccountPreferences in the view, b/c the @LazilyDecoding wrapper breaks animations
    @State private var pinnedTimelines: [PinnedTimeline]
    
    init(accountPreferences: AccountPreferences) {
        self.accountPreferences = accountPreferences
        self.pinnedTimelines = accountPreferences.pinnedTimelines
    }
    
    var body: some View {
        Section {
            ForEach(pinnedTimelines, id: \.id) { timeline in
                HStack {
                    Label {
                        if case .list(id: let id) = timeline,
                           let list = mastodonController.lists.first(where: { $0.id == id }) {
                            Text(list.title)
                        } else if case .tag(hashtag: let tag) = timeline {
                            Text(tag)
                        } else {
                            Text(timeline.title)
                        }
                    } icon: {
                        Image(uiImage: timeline.image.withRenderingMode(.alwaysTemplate))
                    }
                    
                    Spacer()
                    
                    Image(systemName: "line.3.horizontal")
                        .foregroundColor(Color(.lightGray))
                        .accessibilityHidden(true)
                }
                .contextMenu {
                    Button(role: .destructive) {
                        pinnedTimelines.removeAll(where: { $0.id == timeline.id })
                    } label: {
                        Label("Remove Pinned Timeline", systemImage: "trash")
                    }
                }
            }
            .onMove { indices, newOffset in
                pinnedTimelines.move(fromOffsets: indices, toOffset: newOffset)
            }
            .onDelete(perform: pinnedTimelines.count == 1 ? nil : { indices in
                pinnedTimelines.remove(atOffsets: indices)
            })
            
            Menu {
                ForEach([PinnedTimeline.home, .public(local: true), .public(local: false)], id: \.id) { timeline in
                    Button {
                        withAnimation {
                            pinnedTimelines.append(timeline)
                        }
                    } label: {
                        Label {
                            Text(timeline.title)
                        } icon: {
                            Image(uiImage: timeline.image)
                        }
                    }
                    .disabled(pinnedTimelines.contains(timeline))
                }
                
                Menu("List…") {
                    ForEach(mastodonController.lists, id: \.id) { list in
                        Button {
                            withAnimation {
                                pinnedTimelines.append(.list(id: list.id))
                            }
                        } label: {
                            Text(list.title)
                        }
                        .disabled(pinnedTimelines.contains(.list(id: list.id)))
                    }
                }
                
                Button {
                    isShowingAddHashtagSheet = true
                } label: {
                    Label("Hashtag…", systemImage: "number")
                }
                
                Button {
                    isShowingAddInstanceSheet = true
                } label: {
                    Label("Instance…", systemImage: "globe")
                }
            } label: {
                Label("Add…", systemImage: "plus")
                    .padding(.horizontal, 20)
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            }
            .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
        } header: {
            Text("Pinned Timelines")
        }
        .sheet(isPresented: $isShowingAddHashtagSheet, content: {
            if #available(iOS 16.0, *) {
                AddHashtagPinnedTimelineView(pinnedTimelines: $pinnedTimelines)
                    .edgesIgnoringSafeArea(.bottom)
            } else {
                AddHashtagPinnedTimelineRepresentable(pinnedTimelines: $pinnedTimelines)
                    .edgesIgnoringSafeArea(.bottom)
            }
        })
        .sheet(isPresented: $isShowingAddInstanceSheet, content: {
            AddInstancePinnedTimelineView(pinnedTimelines: $pinnedTimelines)
                .edgesIgnoringSafeArea(.bottom)
        })
        .onReceive(accountPreferences.publisher(for: \.pinnedTimelinesData)) { _ in
            if pinnedTimelines != accountPreferences.pinnedTimelines {
                pinnedTimelines = accountPreferences.pinnedTimelines
            }
        }
        .onChange(of: pinnedTimelines) { newValue in
            if accountPreferences.pinnedTimelines != newValue {
                accountPreferences.pinnedTimelines = newValue
            }
        }
    }
}

fileprivate extension PinnedTimeline {
    var id: String {
        switch self {
        case .home:
            return "home"
        case .public(local: let local):
            return "public:\(local)"
        case .list(id: let id):
            return "list:\(id)"
        case .tag(hashtag: let tag):
            return "tag:\(tag)"
        case .instance(let url):
            return "instance:\(url.host!)"
        }
    }
}
