//
//  PDFGenerator.swift
//  SportsTime
//
//  Generates beautiful PDF trip itineraries with maps, photos, and attractions.
//

import Foundation
import PDFKit
import UIKit

@MainActor
final class PDFGenerator {

    // MARK: - Constants

    private let pageWidth: CGFloat = 612   // Letter size
    private let pageHeight: CGFloat = 792
    private let margin: CGFloat = 50
    private let contentWidth: CGFloat = 512  // 612 - 50*2

    // MARK: - Colors

    private let primaryColor = UIColor(red: 0.12, green: 0.23, blue: 0.54, alpha: 1.0)  // Dark blue
    private let accentColor = UIColor(red: 0.97, green: 0.45, blue: 0.09, alpha: 1.0)   // Orange

    // MARK: - Generate PDF

    func generatePDF(
        for trip: Trip,
        games: [String: RichGame],
        assets: PDFAssetPrefetcher.PrefetchedAssets? = nil
    ) async throws -> Data {
        let pdfRenderer = UIGraphicsPDFRenderer(
            bounds: CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)
        )

        let data = pdfRenderer.pdfData { context in
            // Page 1: Cover
            context.beginPage()
            drawCoverPage(context: context, trip: trip, assets: assets)

            // Page 2: Route Overview
            context.beginPage()
            drawRouteOverviewPage(context: context, trip: trip, assets: assets)

            // Day-by-Day Itinerary
            drawItineraryPages(context: context, trip: trip, games: games, assets: assets)

            // City Spotlight pages
            drawCitySpotlightPages(context: context, trip: trip, games: games, assets: assets)

            // Final page: Summary
            context.beginPage()
            drawSummaryPage(context: context, trip: trip, games: games)
        }

        return data
    }

    // MARK: - Cover Page

    private func drawCoverPage(
        context: UIGraphicsPDFRendererContext,
        trip: Trip,
        assets: PDFAssetPrefetcher.PrefetchedAssets?
    ) {
        var y: CGFloat = margin

        // Hero route map (if available)
        if let routeMap = assets?.routeMap {
            let mapHeight: CGFloat = 350
            let mapRect = CGRect(x: margin, y: y, width: contentWidth, height: mapHeight)

            // Draw map with rounded corners
            let path = UIBezierPath(roundedRect: mapRect, cornerRadius: 12)
            context.cgContext.saveGState()
            path.addClip()
            routeMap.draw(in: mapRect)
            context.cgContext.restoreGState()

            // Border
            UIColor.lightGray.setStroke()
            path.lineWidth = 1
            path.stroke()

            y += mapHeight + 30
        } else {
            // No map - add extra spacing
            y = 180
        }

        // Color accent bar
        let barRect = CGRect(x: margin, y: y, width: contentWidth, height: 6)
        let barPath = UIBezierPath(roundedRect: barRect, cornerRadius: 3)
        primaryColor.setFill()
        barPath.fill()
        y += 25

        // Trip name
        let titleAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 32),
            .foregroundColor: UIColor.black
        ]
        let titleRect = CGRect(x: margin, y: y, width: contentWidth, height: 50)
        (trip.displayName as NSString).draw(in: titleRect, withAttributes: titleAttributes)
        y += 55

        // Date range
        let subtitleAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 18),
            .foregroundColor: UIColor.darkGray
        ]
        let dateRect = CGRect(x: margin, y: y, width: contentWidth, height: 30)
        (trip.formattedDateRange as NSString).draw(in: dateRect, withAttributes: subtitleAttributes)
        y += 45

        // Quick stats row
        let statsText = "\(trip.stops.count) Cities  |  \(trip.totalGames) Games  |  \(trip.formattedTotalDistance)"
        let statsAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 16, weight: .medium),
            .foregroundColor: primaryColor
        ]
        let statsRect = CGRect(x: margin, y: y, width: contentWidth, height: 25)
        (statsText as NSString).draw(in: statsRect, withAttributes: statsAttributes)
        y += 40

        // Driving info
        let drivingText = "\(trip.tripDuration) Days  |  \(trip.formattedTotalDriving) Total Driving"
        let drivingAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 14),
            .foregroundColor: UIColor.gray
        ]
        let drivingRect = CGRect(x: margin, y: y, width: contentWidth, height: 22)
        (drivingText as NSString).draw(in: drivingRect, withAttributes: drivingAttributes)
        y += 50

        // Cities list
        drawSectionHeader("Route", at: &y)

        let cityAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 13),
            .foregroundColor: UIColor.darkGray
        ]

        for (index, city) in trip.cities.enumerated() {
            let cityText = "\(index + 1). \(city)"
            let cityRect = CGRect(x: margin + 15, y: y, width: contentWidth - 15, height: 20)
            (cityText as NSString).draw(in: cityRect, withAttributes: cityAttributes)
            y += 22
        }

        // Footer
        drawFooter(context: context, pageNumber: 1)
    }

    // MARK: - Route Overview Page

    private func drawRouteOverviewPage(
        context: UIGraphicsPDFRendererContext,
        trip: Trip,
        assets: PDFAssetPrefetcher.PrefetchedAssets?
    ) {
        var y: CGFloat = margin

        // Page header
        drawPageHeader("Route Overview", at: &y)

        // Route map (larger on this page)
        if let routeMap = assets?.routeMap {
            let mapHeight: CGFloat = 300
            let mapRect = CGRect(x: margin, y: y, width: contentWidth, height: mapHeight)

            let path = UIBezierPath(roundedRect: mapRect, cornerRadius: 8)
            context.cgContext.saveGState()
            path.addClip()
            routeMap.draw(in: mapRect)
            context.cgContext.restoreGState()

            UIColor.lightGray.setStroke()
            path.lineWidth = 1
            path.stroke()

            y += mapHeight + 25
        }

        // Stop table header
        drawSectionHeader("Stops", at: &y)

        // Table headers
        let headerAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 11),
            .foregroundColor: UIColor.darkGray
        ]

        let col1 = margin + 5
        let col2 = margin + 35
        let col3 = margin + 200
        let col4 = margin + 310
        let col5 = margin + 410

        ("#" as NSString).draw(at: CGPoint(x: col1, y: y), withAttributes: headerAttributes)
        ("City" as NSString).draw(at: CGPoint(x: col2, y: y), withAttributes: headerAttributes)
        ("Arrival" as NSString).draw(at: CGPoint(x: col3, y: y), withAttributes: headerAttributes)
        ("Games" as NSString).draw(at: CGPoint(x: col4, y: y), withAttributes: headerAttributes)
        ("Distance" as NSString).draw(at: CGPoint(x: col5, y: y), withAttributes: headerAttributes)
        y += 20

        // Separator line
        drawHorizontalLine(at: y)
        y += 8

        // Table rows
        let rowAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 11),
            .foregroundColor: UIColor.black
        ]

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMM d"

        for (index, stop) in trip.stops.enumerated() {
            ("\(index + 1)" as NSString).draw(at: CGPoint(x: col1, y: y), withAttributes: rowAttributes)
            ("\(stop.city), \(stop.state)" as NSString).draw(at: CGPoint(x: col2, y: y), withAttributes: rowAttributes)
            (dateFormatter.string(from: stop.arrivalDate) as NSString).draw(at: CGPoint(x: col3, y: y), withAttributes: rowAttributes)
            ("\(stop.games.count)" as NSString).draw(at: CGPoint(x: col4, y: y), withAttributes: rowAttributes)

            // Distance to next stop
            if index < trip.travelSegments.count {
                let segment = trip.travelSegments[index]
                (segment.formattedDistance as NSString).draw(at: CGPoint(x: col5, y: y), withAttributes: rowAttributes)
            } else {
                ("--" as NSString).draw(at: CGPoint(x: col5, y: y), withAttributes: rowAttributes)
            }

            y += 22
        }

        drawFooter(context: context, pageNumber: 2)
    }

    // MARK: - Itinerary Pages

    private func drawItineraryPages(
        context: UIGraphicsPDFRendererContext,
        trip: Trip,
        games: [String: RichGame],
        assets: PDFAssetPrefetcher.PrefetchedAssets?
    ) {
        var pageNumber = 3
        var y: CGFloat = margin
        var isFirstDayOnPage = true

        context.beginPage()
        drawPageHeader("Day-by-Day Itinerary", at: &y)

        for day in trip.itineraryDays() {
            // Check if we need a new page
            let estimatedHeight = estimateDayHeight(day: day, games: games)
            if y + estimatedHeight > pageHeight - 80 {
                drawFooter(context: context, pageNumber: pageNumber)
                pageNumber += 1
                context.beginPage()
                y = margin
                isFirstDayOnPage = true
            }

            if !isFirstDayOnPage {
                y += 15  // Space between days
            }

            y = drawDay(
                context: context,
                day: day,
                games: games,
                assets: assets,
                y: y
            )

            isFirstDayOnPage = false
        }

        drawFooter(context: context, pageNumber: pageNumber)
    }

    private func estimateDayHeight(day: ItineraryDay, games: [String: RichGame]) -> CGFloat {
        var height: CGFloat = 60  // Day header + city

        // Games
        height += CGFloat(day.gameIds.count) * 80  // Each game card

        // Travel
        if day.hasTravelSegment {
            height += 50
        }

        // Rest day
        if day.isRestDay {
            height += 30
        }

        return height
    }

    private func drawDay(
        context: UIGraphicsPDFRendererContext,
        day: ItineraryDay,
        games: [String: RichGame],
        assets: PDFAssetPrefetcher.PrefetchedAssets?,
        y: CGFloat
    ) -> CGFloat {
        var currentY = y

        // Day header with accent background
        let headerRect = CGRect(x: margin, y: currentY, width: contentWidth, height: 32)
        let headerPath = UIBezierPath(roundedRect: headerRect, cornerRadius: 6)
        primaryColor.withAlphaComponent(0.1).setFill()
        headerPath.fill()

        let dayHeaderAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 16),
            .foregroundColor: primaryColor
        ]
        let dayHeader = "Day \(day.dayNumber) - \(day.formattedDate)"
        (dayHeader as NSString).draw(
            at: CGPoint(x: margin + 12, y: currentY + 7),
            withAttributes: dayHeaderAttributes
        )
        currentY += 40

        // City
        if let city = day.primaryCity {
            let cityAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.systemFont(ofSize: 13),
                .foregroundColor: UIColor.darkGray
            ]
            let cityText = "Location: \(city)"
            (cityText as NSString).draw(at: CGPoint(x: margin + 12, y: currentY), withAttributes: cityAttributes)
            currentY += 25
        }

        // Games
        for gameId in day.gameIds {
            if let richGame = games[gameId] {
                currentY = drawGameCard(
                    context: context,
                    richGame: richGame,
                    assets: assets,
                    y: currentY
                )
                currentY += 10
            }
        }

        // Travel segments
        for segment in day.travelSegments {
            currentY = drawTravelSegment(segment: segment, y: currentY)
        }

        // Rest day
        if day.isRestDay && day.gameIds.isEmpty {
            let restAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.italicSystemFont(ofSize: 13),
                .foregroundColor: UIColor.gray
            ]
            let restRect = CGRect(x: margin + 12, y: currentY, width: contentWidth - 12, height: 25)
            ("Rest Day - Explore the city!" as NSString).draw(in: restRect, withAttributes: restAttributes)
            currentY += 30
        }

        // Day separator line
        drawHorizontalLine(at: currentY + 5, alpha: 0.3)
        currentY += 15

        return currentY
    }

    private func drawGameCard(
        context: UIGraphicsPDFRendererContext,
        richGame: RichGame,
        assets: PDFAssetPrefetcher.PrefetchedAssets?,
        y: CGFloat
    ) -> CGFloat {
        let currentY = y

        // Card background
        let cardRect = CGRect(x: margin + 10, y: currentY, width: contentWidth - 20, height: 65)
        let cardPath = UIBezierPath(roundedRect: cardRect, cornerRadius: 8)

        UIColor.white.setFill()
        cardPath.fill()

        // Card border with team color if available
        let borderColor = teamColor(from: richGame.homeTeam.primaryColor) ?? primaryColor
        borderColor.withAlphaComponent(0.5).setStroke()
        cardPath.lineWidth = 1.5
        cardPath.stroke()

        // Sport badge
        let sportText = richGame.game.sport.rawValue.uppercased()
        let badgeRect = CGRect(x: margin + 20, y: currentY + 8, width: 35, height: 18)
        let badgePath = UIBezierPath(roundedRect: badgeRect, cornerRadius: 4)
        borderColor.withAlphaComponent(0.2).setFill()
        badgePath.fill()

        let badgeAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 9),
            .foregroundColor: borderColor
        ]
        (sportText as NSString).draw(
            at: CGPoint(x: badgeRect.midX - 10, y: currentY + 10),
            withAttributes: badgeAttributes
        )

        // Team logos (if available)
        let logoSize: CGFloat = 28
        let logoY = currentY + 30

        // Away team logo
        if let awayLogo = assets?.teamLogos[richGame.awayTeam.id] {
            let awayLogoRect = CGRect(x: margin + 20, y: logoY, width: logoSize, height: logoSize)
            awayLogo.draw(in: awayLogoRect)
        } else {
            // Placeholder circle with abbreviation
            drawTeamPlaceholder(
                abbreviation: richGame.awayTeam.abbreviation,
                at: CGPoint(x: margin + 20, y: logoY),
                size: logoSize,
                color: teamColor(from: richGame.awayTeam.primaryColor)
            )
        }

        // "at" text
        let atAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 11),
            .foregroundColor: UIColor.gray
        ]
        ("@" as NSString).draw(at: CGPoint(x: margin + 55, y: logoY + 8), withAttributes: atAttributes)

        // Home team logo
        if let homeLogo = assets?.teamLogos[richGame.homeTeam.id] {
            let homeLogoRect = CGRect(x: margin + 70, y: logoY, width: logoSize, height: logoSize)
            homeLogo.draw(in: homeLogoRect)
        } else {
            drawTeamPlaceholder(
                abbreviation: richGame.homeTeam.abbreviation,
                at: CGPoint(x: margin + 70, y: logoY),
                size: logoSize,
                color: teamColor(from: richGame.homeTeam.primaryColor)
            )
        }

        // Matchup text
        let matchupAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 13),
            .foregroundColor: UIColor.black
        ]
        let matchupText = "\(richGame.awayTeam.name) at \(richGame.homeTeam.name)"
        (matchupText as NSString).draw(
            at: CGPoint(x: margin + 110, y: currentY + 12),
            withAttributes: matchupAttributes
        )

        // Venue and time
        let venueAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 11),
            .foregroundColor: UIColor.darkGray
        ]
        let venueText = "\(richGame.stadium.name)  |  \(richGame.localGameTimeShort)"
        (venueText as NSString).draw(
            at: CGPoint(x: margin + 110, y: currentY + 30),
            withAttributes: venueAttributes
        )

        // City
        let cityAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 10),
            .foregroundColor: UIColor.gray
        ]
        let cityText = "\(richGame.stadium.city), \(richGame.stadium.state)"
        (cityText as NSString).draw(
            at: CGPoint(x: margin + 110, y: currentY + 46),
            withAttributes: cityAttributes
        )

        return currentY + 70
    }

    private func drawTravelSegment(segment: TravelSegment, y: CGFloat) -> CGFloat {
        let currentY = y

        let travelRect = CGRect(x: margin + 10, y: currentY, width: contentWidth - 20, height: 35)
        let travelPath = UIBezierPath(roundedRect: travelRect, cornerRadius: 6)
        UIColor.systemGray6.setFill()
        travelPath.fill()

        // Car icon placeholder
        let iconAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 14),
            .foregroundColor: UIColor.gray
        ]
        (">" as NSString).draw(at: CGPoint(x: margin + 20, y: currentY + 10), withAttributes: iconAttributes)

        // Travel text
        let travelAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 12),
            .foregroundColor: UIColor.darkGray
        ]
        let travelText = "Drive to \(segment.toLocation.name)  |  \(segment.formattedDistance)  |  \(segment.formattedDuration)"
        (travelText as NSString).draw(
            at: CGPoint(x: margin + 40, y: currentY + 10),
            withAttributes: travelAttributes
        )

        return currentY + 45
    }

    // MARK: - City Spotlight Pages

    private func drawCitySpotlightPages(
        context: UIGraphicsPDFRendererContext,
        trip: Trip,
        games: [String: RichGame],
        assets: PDFAssetPrefetcher.PrefetchedAssets?
    ) {
        guard let cityPOIs = assets?.cityPOIs, !cityPOIs.isEmpty else { return }

        var pageNumber = 10  // Estimate, will be overwritten

        // Draw spotlight for each city with POIs
        var seenCities: Set<String> = []
        for stop in trip.stops {
            guard !seenCities.contains(stop.city),
                  let pois = cityPOIs[stop.city], !pois.isEmpty else { continue }
            seenCities.insert(stop.city)

            context.beginPage()
            var y: CGFloat = margin

            drawPageHeader("City Guide: \(stop.city)", at: &y)

            // City map
            if let cityMap = assets?.cityMaps[stop.city] {
                let mapRect = CGRect(x: margin, y: y, width: 250, height: 180)
                let mapPath = UIBezierPath(roundedRect: mapRect, cornerRadius: 8)
                context.cgContext.saveGState()
                mapPath.addClip()
                cityMap.draw(in: mapRect)
                context.cgContext.restoreGState()

                UIColor.lightGray.setStroke()
                mapPath.lineWidth = 1
                mapPath.stroke()

                // City info next to map
                let infoX = margin + 270
                var infoY = y

                let cityNameAttributes: [NSAttributedString.Key: Any] = [
                    .font: UIFont.boldSystemFont(ofSize: 18),
                    .foregroundColor: UIColor.black
                ]
                ("\(stop.city), \(stop.state)" as NSString).draw(
                    at: CGPoint(x: infoX, y: infoY),
                    withAttributes: cityNameAttributes
                )
                infoY += 28

                // Find stadium for this city
                let cityGames = stop.games.compactMap { games[$0] }
                if let stadium = cityGames.first?.stadium {
                    let venueAttributes: [NSAttributedString.Key: Any] = [
                        .font: UIFont.systemFont(ofSize: 13),
                        .foregroundColor: UIColor.darkGray
                    ]
                    ("Stadium: \(stadium.name)" as NSString).draw(
                        at: CGPoint(x: infoX, y: infoY),
                        withAttributes: venueAttributes
                    )
                    infoY += 20

                    let capacityText = "Capacity: \(NumberFormatter.localizedString(from: NSNumber(value: stadium.capacity), number: .decimal))"
                    (capacityText as NSString).draw(
                        at: CGPoint(x: infoX, y: infoY),
                        withAttributes: venueAttributes
                    )
                }

                y += 200
            }

            y += 20
            drawSectionHeader("Nearby Attractions", at: &y)

            // POI list
            for (index, poi) in pois.enumerated() {
                y = drawPOIItem(poi: poi, index: index + 1, y: y)
            }

            pageNumber += 1
        }
    }

    private func drawPOIItem(poi: POISearchService.POI, index: Int, y: CGFloat) -> CGFloat {
        let currentY = y

        // Number badge
        let badgeRect = CGRect(x: margin + 10, y: currentY, width: 22, height: 22)
        let badgePath = UIBezierPath(roundedRect: badgeRect, cornerRadius: 11)
        accentColor.withAlphaComponent(0.2).setFill()
        badgePath.fill()

        let numberAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 11),
            .foregroundColor: accentColor
        ]
        ("\(index)" as NSString).draw(
            at: CGPoint(x: margin + 17, y: currentY + 4),
            withAttributes: numberAttributes
        )

        // POI name
        let nameAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 13),
            .foregroundColor: UIColor.black
        ]
        (poi.name as NSString).draw(
            at: CGPoint(x: margin + 45, y: currentY + 2),
            withAttributes: nameAttributes
        )

        // Category and distance
        let detailAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 11),
            .foregroundColor: UIColor.gray
        ]
        let detailText = "\(poi.category.displayName)  |  \(poi.formattedDistance) from stadium"
        (detailText as NSString).draw(
            at: CGPoint(x: margin + 45, y: currentY + 20),
            withAttributes: detailAttributes
        )

        // Address if available
        if let address = poi.address {
            let addressAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.systemFont(ofSize: 10),
                .foregroundColor: UIColor.lightGray
            ]
            (address as NSString).draw(
                at: CGPoint(x: margin + 45, y: currentY + 36),
                withAttributes: addressAttributes
            )
            return currentY + 55
        }

        return currentY + 45
    }

    // MARK: - Summary Page

    private func drawSummaryPage(
        context: UIGraphicsPDFRendererContext,
        trip: Trip,
        games: [String: RichGame]
    ) {
        var y: CGFloat = margin

        drawPageHeader("Trip Summary", at: &y)

        // Stats grid
        let statsBoxWidth: CGFloat = 150
        let statsBoxHeight: CGFloat = 80
        let spacing: CGFloat = 20

        let stats: [(String, String)] = [
            ("\(trip.tripDuration)", "Days"),
            ("\(trip.stops.count)", "Cities"),
            ("\(trip.totalGames)", "Games"),
            (String(format: "%.0f", trip.totalDistanceMiles), "Miles")
        ]

        var col: CGFloat = 0
        for (index, stat) in stats.enumerated() {
            let x = margin + (statsBoxWidth + spacing) * CGFloat(index % 3)
            let boxY = y + (index >= 3 ? statsBoxHeight + 15 : 0)

            if index == 3 && col < 3 {
                col = 0  // New row
            }

            let boxRect = CGRect(x: x, y: boxY, width: statsBoxWidth, height: statsBoxHeight)
            let boxPath = UIBezierPath(roundedRect: boxRect, cornerRadius: 10)
            primaryColor.withAlphaComponent(0.08).setFill()
            boxPath.fill()

            // Big number
            let numberAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.boldSystemFont(ofSize: 28),
                .foregroundColor: primaryColor
            ]
            let numberSize = (stat.0 as NSString).size(withAttributes: numberAttributes)
            (stat.0 as NSString).draw(
                at: CGPoint(x: x + (statsBoxWidth - numberSize.width) / 2, y: boxY + 15),
                withAttributes: numberAttributes
            )

            // Label
            let labelAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.systemFont(ofSize: 13),
                .foregroundColor: UIColor.darkGray
            ]
            let labelSize = (stat.1 as NSString).size(withAttributes: labelAttributes)
            (stat.1 as NSString).draw(
                at: CGPoint(x: x + (statsBoxWidth - labelSize.width) / 2, y: boxY + 50),
                withAttributes: labelAttributes
            )

            col += 1
        }

        y += statsBoxHeight * 2 + 50

        // Driving stats
        drawSectionHeader("Driving", at: &y)

        let drivingStats = [
            ("Total Driving Time", trip.formattedTotalDriving),
            ("Average Per Day", String(format: "%.1f hours", trip.averageDrivingHoursPerDay)),
            ("Travel Segments", "\(trip.travelSegments.count)")
        ]

        for stat in drivingStats {
            drawStatRow(label: stat.0, value: stat.1, y: &y)
        }

        y += 20

        // Sports breakdown
        drawSectionHeader("Sports Breakdown", at: &y)

        var sportCounts: [Sport: Int] = [:]
        for gameId in trip.stops.flatMap({ $0.games }) {
            if let game = games[gameId] {
                sportCounts[game.game.sport, default: 0] += 1
            }
        }

        for (sport, count) in sportCounts.sorted(by: { $0.value > $1.value }) {
            drawStatRow(label: sport.rawValue, value: "\(count) games", y: &y)
        }

        // Trip score if available
        if let score = trip.score {
            y += 20
            drawSectionHeader("Trip Score", at: &y)

            let gradeAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.boldSystemFont(ofSize: 36),
                .foregroundColor: UIColor.systemGreen
            ]
            let gradeText = score.scoreGrade
            (gradeText as NSString).draw(at: CGPoint(x: margin + 20, y: y), withAttributes: gradeAttributes)

            let scoreAttributes: [NSAttributedString.Key: Any] = [
                .font: UIFont.systemFont(ofSize: 16),
                .foregroundColor: UIColor.darkGray
            ]
            let scoreText = "\(score.formattedOverallScore)/100"
            (scoreText as NSString).draw(at: CGPoint(x: margin + 80, y: y + 10), withAttributes: scoreAttributes)
        }

        // Footer
        let footerY = pageHeight - 50
        let footerAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.italicSystemFont(ofSize: 10),
            .foregroundColor: UIColor.lightGray
        ]
        ("Generated by SportsTime" as NSString).draw(
            at: CGPoint(x: margin, y: footerY),
            withAttributes: footerAttributes
        )
    }

    // MARK: - Drawing Helpers

    private func drawPageHeader(_ title: String, at y: inout CGFloat) {
        let headerAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 22),
            .foregroundColor: UIColor.black
        ]
        (title as NSString).draw(at: CGPoint(x: margin, y: y), withAttributes: headerAttributes)
        y += 35
    }

    private func drawSectionHeader(_ title: String, at y: inout CGFloat) {
        let headerAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 14),
            .foregroundColor: primaryColor
        ]
        (title as NSString).draw(at: CGPoint(x: margin, y: y), withAttributes: headerAttributes)
        y += 22
    }

    private func drawStatRow(label: String, value: String, y: inout CGFloat) {
        let labelAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 12),
            .foregroundColor: UIColor.darkGray
        ]
        let valueAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 12),
            .foregroundColor: UIColor.black
        ]

        (label as NSString).draw(at: CGPoint(x: margin + 15, y: y), withAttributes: labelAttributes)
        (value as NSString).draw(at: CGPoint(x: margin + 200, y: y), withAttributes: valueAttributes)
        y += 20
    }

    private func drawHorizontalLine(at y: CGFloat, alpha: CGFloat = 0.5) {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: margin, y: y))
        path.addLine(to: CGPoint(x: pageWidth - margin, y: y))
        UIColor.lightGray.withAlphaComponent(alpha).setStroke()
        path.lineWidth = 0.5
        path.stroke()
    }

    private func drawFooter(context: UIGraphicsPDFRendererContext, pageNumber: Int) {
        let footerY = pageHeight - 35
        let footerAttributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 9),
            .foregroundColor: UIColor.lightGray
        ]
        let footerText = "Page \(pageNumber)"
        let footerSize = (footerText as NSString).size(withAttributes: footerAttributes)
        (footerText as NSString).draw(
            at: CGPoint(x: (pageWidth - footerSize.width) / 2, y: footerY),
            withAttributes: footerAttributes
        )
    }

    private func drawTeamPlaceholder(abbreviation: String, at point: CGPoint, size: CGFloat, color: UIColor?) {
        let rect = CGRect(origin: point, size: CGSize(width: size, height: size))
        let path = UIBezierPath(ovalIn: rect)

        (color ?? primaryColor).withAlphaComponent(0.2).setFill()
        path.fill()

        let attributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.boldSystemFont(ofSize: 10),
            .foregroundColor: color ?? primaryColor
        ]
        let textSize = (abbreviation as NSString).size(withAttributes: attributes)
        (abbreviation as NSString).draw(
            at: CGPoint(
                x: point.x + (size - textSize.width) / 2,
                y: point.y + (size - textSize.height) / 2
            ),
            withAttributes: attributes
        )
    }

    private func teamColor(from hexString: String?) -> UIColor? {
        guard let hex = hexString else { return nil }
        return UIColor(hex: hex)
    }
}

// MARK: - UIColor Extension

extension UIColor {
    convenience init?(hex: String) {
        var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
        hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")

        guard hexSanitized.count == 6 else { return nil }

        var rgb: UInt64 = 0
        Scanner(string: hexSanitized).scanHexInt64(&rgb)

        let red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0
        let green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0
        let blue = CGFloat(rgb & 0x0000FF) / 255.0

        self.init(red: red, green: green, blue: blue, alpha: 1.0)
    }
}

// MARK: - Export Service

@MainActor
final class ExportService {
    private let pdfGenerator = PDFGenerator()
    private let assetPrefetcher = PDFAssetPrefetcher()

    /// Export trip to PDF with full prefetched assets
    func exportToPDF(
        trip: Trip,
        games: [String: RichGame],
        progressCallback: ((PDFAssetPrefetcher.PrefetchProgress) async -> Void)? = nil
    ) async throws -> URL {
        // Prefetch all assets
        let assets = await assetPrefetcher.prefetchAssets(
            for: trip,
            games: games,
            progressCallback: progressCallback
        )

        // Generate PDF with assets
        let data = try await pdfGenerator.generatePDF(for: trip, games: games, assets: assets)

        // Save to temp file
        let fileName = "\(trip.name.replacingOccurrences(of: " ", with: "_"))_\(Date().timeIntervalSince1970).pdf"
        let url = FileManager.default.temporaryDirectory.appendingPathComponent(fileName)

        try data.write(to: url)
        return url
    }

    /// Quick export without prefetching (basic PDF)
    func exportToPDFBasic(trip: Trip, games: [String: RichGame]) async throws -> URL {
        let data = try await pdfGenerator.generatePDF(for: trip, games: games, assets: nil)

        let fileName = "\(trip.name.replacingOccurrences(of: " ", with: "_"))_\(Date().timeIntervalSince1970).pdf"
        let url = FileManager.default.temporaryDirectory.appendingPathComponent(fileName)

        try data.write(to: url)
        return url
    }

    func shareTrip(_ trip: Trip) -> URL? {
        let baseURL = "sportstime://trip/"
        return URL(string: baseURL + trip.id.uuidString)
    }
}
