//
//  PollDetailViewModel.swift
//  SportsTime
//
//  ViewModel for viewing poll details and results
//

import Foundation
import SwiftUI

@Observable
@MainActor
final class PollDetailViewModel {
    var poll: TripPoll?
    var votes: [PollVote] = []
    var myVote: PollVote?
    var isLoading = false
    var isRefreshing = false
    var error: PollError?

    private let pollService = PollService.shared

    var results: PollResults? {
        guard let poll else { return nil }
        return PollResults(poll: poll, votes: votes)
    }

    func checkIsOwner() async -> Bool {
        guard let poll else { return false }
        do {
            let userId = try await pollService.getCurrentUserRecordID()
            return poll.ownerId == userId
        } catch {
            return false
        }
    }

    var isOwner: Bool {
        get async {
            await checkIsOwner()
        }
    }

    var hasVoted: Bool {
        myVote != nil
    }

    var shareURL: URL? {
        poll?.shareURL
    }

    func loadPoll(byId pollId: UUID) async {
        isLoading = true
        error = nil

        do {
            async let pollTask = pollService.fetchPoll(byId: pollId)
            async let votesTask = pollService.fetchVotes(forPollId: pollId)
            async let myVoteTask = pollService.fetchMyVote(forPollId: pollId)

            let (fetchedPoll, fetchedVotes, fetchedMyVote) = try await (pollTask, votesTask, myVoteTask)

            self.poll = fetchedPoll
            self.votes = fetchedVotes
            self.myVote = fetchedMyVote

            // Subscribe to vote updates
            try? await pollService.subscribeToVoteUpdates(forPollId: pollId)
        } catch let pollError as PollError {
            error = pollError
        } catch {
            self.error = .unknown(error)
        }

        isLoading = false
    }

    func loadPoll(byShareCode shareCode: String) async {
        isLoading = true
        error = nil

        do {
            let fetchedPoll = try await pollService.fetchPoll(byShareCode: shareCode)
            self.poll = fetchedPoll

            // Now fetch votes with the poll ID
            async let votesTask = pollService.fetchVotes(forPollId: fetchedPoll.id)
            async let myVoteTask = pollService.fetchMyVote(forPollId: fetchedPoll.id)

            let (fetchedVotes, fetchedMyVote) = try await (votesTask, myVoteTask)
            self.votes = fetchedVotes
            self.myVote = fetchedMyVote

            // Subscribe to vote updates
            try? await pollService.subscribeToVoteUpdates(forPollId: fetchedPoll.id)
        } catch let pollError as PollError {
            error = pollError
        } catch {
            self.error = .unknown(error)
        }

        isLoading = false
    }

    /// Load poll from an existing object (avoids CloudKit fetch delay)
    func loadPoll(from existingPoll: TripPoll) async {
        isLoading = true
        error = nil

        self.poll = existingPoll

        do {
            // Still fetch votes and subscription from CloudKit
            async let votesTask = pollService.fetchVotes(forPollId: existingPoll.id)
            async let myVoteTask = pollService.fetchMyVote(forPollId: existingPoll.id)

            let (fetchedVotes, fetchedMyVote) = try await (votesTask, myVoteTask)
            self.votes = fetchedVotes
            self.myVote = fetchedMyVote

            // Subscribe to vote updates
            try? await pollService.subscribeToVoteUpdates(forPollId: existingPoll.id)
        } catch {
            // Votes fetch failed, but we have the poll - non-critical error
            self.votes = []
        }

        isLoading = false
    }

    func refresh() async {
        guard let poll else { return }

        isRefreshing = true

        do {
            async let votesTask = pollService.fetchVotes(forPollId: poll.id)
            async let myVoteTask = pollService.fetchMyVote(forPollId: poll.id)

            let (fetchedVotes, fetchedMyVote) = try await (votesTask, myVoteTask)
            self.votes = fetchedVotes
            self.myVote = fetchedMyVote
        } catch {
            // Silently fail refresh - user can pull to refresh again
        }

        isRefreshing = false
    }

    func deletePoll() async -> Bool {
        guard let poll else { return false }

        isLoading = true
        error = nil

        do {
            try await pollService.deletePoll(poll.id)
            try? await pollService.unsubscribeFromVoteUpdates()
            self.poll = nil
            return true
        } catch let pollError as PollError {
            error = pollError
        } catch {
            self.error = .unknown(error)
        }

        isLoading = false
        return false
    }

    func cleanup() async {
        try? await pollService.unsubscribeFromVoteUpdates()
    }
}
