//
//  SwitchAccountContainerView.swift
//  ShareExtension
//
//  Created by Shadowfacts on 4/19/23.
//  Copyright © 2023 Shadowfacts. All rights reserved.
//

import SwiftUI
import UserAccounts
import TuskerPreferences
import Pachyderm
import Combine
import ComposeUI

struct SwitchAccountContainerView: View {
    let content: AnyView
    let mastodonContextPublisher: CurrentValueSubject<ShareMastodonContext, Never>
    
    var accounts: [UserAccountInfo] {
        UserAccountsManager.shared.accounts
    }
    
    var body: some View {
        if accounts.count > 1 {
            Menu {
                ForEach(accounts) { account in
                    Button(action: { selectAccount(account) }) {
                        AccountButtonLabel(account: account)
                    }
                }
            } label: {
                HStack(alignment: .center) {
                    VStack(spacing: 2) {
                        Image(systemName: "arrowtriangle.up.fill")
                            .resizable()
                            .frame(width: 10, height: 5)
                        Image(systemName: "arrowtriangle.down.fill")
                            .resizable()
                            .frame(width: 10, height: 5)
                    }
                    .foregroundColor(.secondary)
                    
                    content
                }
            }
        } else {
            content
        }
    }
    
    private func selectAccount(_ account: UserAccountInfo) {
        mastodonContextPublisher.send(ShareMastodonContext(accountInfo: account))
    }
}

@MainActor
private struct AccountButtonLabel: View {
    static let urlSession = URLSession(configuration: .ephemeral)
    
    let account: UserAccountInfo
    @State private var avatarImage: Image?
    
    var body: some View {
        label
            .task {
                await fetchAvatar()
            }
    }
    
    @ViewBuilder
    private var label: some View {
        // subtitles only started being supported on 16.4
        if #available(iOS 16.4, *) {
            Label {
                Text(account.username)
            } icon: {
                avatar
            }
            Text(account.instanceURL.host!)
        } else {
            Label {
                Text("@\(account.username)@\(account.instanceURL.host!)")
            } icon: {
                avatar
            }
        }
    }
    
    @ViewBuilder
    private var avatar: some View {
        if let avatarImage {
            avatarImage
        } else {
            avatarPlaceholder
        }
    }
    
    private var avatarPlaceholder: Image {
        switch Preferences.shared.avatarStyle {
        case .circle:
            return Image(systemName: "person.crop.circle")
        case .roundRect:
            return Image(systemName: "person.crop.square")
        }
    }
    
    private func fetchAvatar() async {
        let client = Client(baseURL: account.instanceURL, accessToken: account.accessToken, session: Self.urlSession)
        let account: Account? = await withCheckedContinuation({ continuation in
            client.run(Client.getSelfAccount()) { response in
                switch response {
                case .success(let account, _):
                    continuation.resume(returning: account)
                case .failure(_):
                    continuation.resume(returning: nil)
                }
            }
        })
        if let account,
           let avatarURL = account.avatar,
           let data = try? await Self.urlSession.data(from: avatarURL).0,
           let image = UIImage(data: data) {
            let size = CGSize(width: 50, height: 50)
            let renderer = UIGraphicsImageRenderer(size: size)
            let clipped = renderer.image { context in
                let bounds = CGRect(origin: .zero, size: size)
                let path: UIBezierPath
                switch Preferences.shared.avatarStyle {
                case .circle:
                    path = UIBezierPath(ovalIn: bounds)
                case .roundRect:
                    path = UIBezierPath(roundedRect: bounds, cornerRadius: 5)
                }
                path.addClip()
                image.draw(in: bounds)
            }
            self.avatarImage = Image(uiImage: clipped)
        }
    }
}