import Foundation
import Observation
import SwiftData

@Observable
@MainActor
final class CardStore: BusinessCardProviding {
    private let modelContext: ModelContext
    private(set) var cards: [BusinessCard] = []
    var selectedCardID: UUID?

    init(modelContext: ModelContext) {
        self.modelContext = modelContext
        fetchCards()
        self.selectedCardID = cards.first(where: { $0.isDefault })?.id ?? cards.first?.id
        syncToWatch()
    }

    var selectedCard: BusinessCard? {
        guard let selectedCardID else { return nil }
        return cards.first(where: { $0.id == selectedCardID })
    }

    func fetchCards() {
        let descriptor = FetchDescriptor<BusinessCard>(
            sortBy: [SortDescriptor(\.createdAt, order: .forward)]
        )
        do {
            cards = try modelContext.fetch(descriptor)
        } catch {
            cards = []
        }
    }

    func addCard(_ card: BusinessCard) {
        modelContext.insert(card)
        saveContext()
        fetchCards()
        selectedCardID = card.id
        syncToWatch()
    }

    func updateCard(_ card: BusinessCard) {
        card.updatedAt = .now
        saveContext()
        fetchCards()
        syncToWatch()
    }

    func deleteCard(_ card: BusinessCard) {
        let wasSelected = selectedCardID == card.id
        modelContext.delete(card)
        saveContext()
        fetchCards()
        
        if wasSelected {
            selectedCardID = cards.first(where: { $0.isDefault })?.id ?? cards.first?.id
        }
        syncToWatch()
    }

    func setSelectedTheme(_ theme: CardTheme) {
        guard let card = selectedCard else { return }
        card.theme = theme
        updateCard(card)
    }

    func setSelectedLayout(_ layout: CardLayoutStyle) {
        guard let card = selectedCard else { return }
        card.layoutStyle = layout
        updateCard(card)
    }

    func setDefaultCard(_ card: BusinessCard) {
        for existingCard in cards {
            existingCard.isDefault = existingCard.id == card.id
        }
        selectedCardID = card.id
        saveContext()
        fetchCards()
        syncToWatch()
    }

    private func saveContext() {
        do {
            try modelContext.save()
        } catch {
            // Handle error silently for now
        }
    }
    
    private func syncToWatch() {
        WatchSyncService.syncCards(cards)
    }
}
