import Foundation
import CoreData

class SampleDataService {
    static let shared = SampleDataService()

    private init() {}

    func seedSampleData() {
        let context = CoreDataStack.shared.viewContext
        let sourceRepository = InvestmentSourceRepository(context: context)
        guard sourceRepository.sourceCount == 0 else { return }

        let categoryRepository = CategoryRepository(context: context)
        categoryRepository.createDefaultCategoriesIfNeeded()

        let accountRepository = AccountRepository(context: context)
        let account = accountRepository.createDefaultAccountIfNeeded()

        let snapshotRepository = SnapshotRepository(context: context)
        let goalRepository = GoalRepository(context: context)

        let categories = fetchCategories(in: context)
        guard let fallbackCategory = categories.first else { return }
        let stocksCategory = resolveCategory(
            named: "Stocks",
            fallback: fallbackCategory,
            colorHex: "#3B82F6",
            icon: "chart.line.uptrend.xyaxis",
            repository: categoryRepository,
            context: context
        )
        let cryptoCategory = resolveCategory(
            named: "Crypto",
            fallback: fallbackCategory,
            colorHex: "#10B981",
            icon: "bitcoinsign.circle.fill",
            repository: categoryRepository,
            context: context
        )
        let realEstateCategory = resolveCategory(
            named: "Real Estate",
            fallback: fallbackCategory,
            colorHex: "#F59E0B",
            icon: "house.fill",
            repository: categoryRepository,
            context: context
        )

        let stocks = sourceRepository.createSource(
            name: "Index Fund",
            category: stocksCategory,
            account: account
        )
        let crypto = sourceRepository.createSource(
            name: "BTC",
            category: cryptoCategory,
            account: account
        )
        let realEstate = sourceRepository.createSource(
            name: "Rental Property",
            category: realEstateCategory,
            account: account
        )

        seedSnapshots(for: stocks, baseValue: 12000, monthlyIncrease: 450, repository: snapshotRepository)
        seedSnapshots(for: crypto, baseValue: 3000, monthlyIncrease: 250, repository: snapshotRepository)
        seedSnapshots(for: realEstate, baseValue: 80000, monthlyIncrease: 600, repository: snapshotRepository)

        seedMonthlyNotes()

        _ = goalRepository.createGoal(
            name: "1M Goal",
            targetAmount: 1_000_000,
            targetDate: nil,
            account: account
        )
    }

    private func seedSnapshots(
        for source: InvestmentSource,
        baseValue: Decimal,
        monthlyIncrease: Decimal,
        repository: SnapshotRepository
    ) {
        let calendar = Calendar.current
        for monthOffset in (0..<6).reversed() {
            let date = calendar.date(byAdding: .month, value: -monthOffset, to: Date()) ?? Date()
            let value = baseValue + Decimal(monthOffset) * monthlyIncrease
            repository.createSnapshot(
                for: source,
                date: date,
                value: value,
                contribution: monthOffset == 0 ? monthlyIncrease : nil,
                notes: nil
            )
        }
    }

    private func seedMonthlyNotes() {
        let calendar = Calendar.current
        let notes = [
            "Rebalanced slightly toward equities. Stayed calm despite noise.",
            "Focused on contributions. No major changes.",
            "Reviewed allocation drift and decided to hold positions."
        ]

        for (index, note) in notes.enumerated() {
            let date = calendar.date(byAdding: .month, value: -index, to: Date()) ?? Date()
            MonthlyCheckInStore.setNote(note, for: date)
        }
    }

    private func fetchCategories(in context: NSManagedObjectContext) -> [Category] {
        let request: NSFetchRequest<Category> = Category.fetchRequest()
        request.sortDescriptors = [
            NSSortDescriptor(keyPath: \Category.sortOrder, ascending: true),
            NSSortDescriptor(keyPath: \Category.name, ascending: true)
        ]
        return (try? context.fetch(request)) ?? []
    }

    private func resolveCategory(
        named name: String,
        fallback: Category,
        colorHex: String,
        icon: String,
        repository: CategoryRepository,
        context: NSManagedObjectContext
    ) -> Category {
        if let existing = fetchCategories(in: context)
            .first(where: { $0.name == name }) {
            return existing
        }
        return repository.createCategory(name: name, colorHex: colorHex, icon: icon)
    }
}
