import CoreText
import Foundation
import SwiftUI
import UIKit

enum SybilFontRegistry {
    static func registerIfNeeded() {
        _ = registeredFonts
    }

    private static let registeredFonts: Void = {
        for fontName in ["Inter", "Orbitron", "StalinistOne-Regular"] {
            guard let url = Bundle.main.url(forResource: fontName, withExtension: "ttf", subdirectory: "Fonts") ??
                Bundle.main.url(forResource: fontName, withExtension: "ttf")
            else {
                continue
            }

            CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
        }
    }()
}

extension Font {
    static func sybil(_ textStyle: Font.TextStyle, weight: Font.Weight = .regular) -> Font {
        SybilFontRegistry.registerIfNeeded()
        return .custom("Inter", size: Self.sybilPointSize(for: textStyle), relativeTo: textStyle)
            .weight(weight)
    }

    static func sybil(size: CGFloat, weight: Font.Weight = .regular) -> Font {
        SybilFontRegistry.registerIfNeeded()
        return .custom("Inter", size: size)
            .weight(weight)
    }

    private static func sybilPointSize(for textStyle: Font.TextStyle) -> CGFloat {
        switch textStyle {
        case .largeTitle:
            return 34
        case .title:
            return 28
        case .title2:
            return 22
        case .title3:
            return 20
        case .headline:
            return 17
        case .subheadline:
            return 15
        case .callout:
            return 16
        case .caption:
            return 12
        case .caption2:
            return 11
        case .footnote:
            return 13
        case .body:
            return 17
        @unknown default:
            return 17
        }
    }
}

enum SybilLayout {
    static let webContentMaxWidth: CGFloat = 896
}

enum SybilTheme {
    static let background = Color(red: 0.02, green: 0.02, blue: 0.05)
    static let surface = Color(red: 0.05, green: 0.04, blue: 0.10)
    static let surfaceStrong = Color(red: 0.07, green: 0.06, blue: 0.14)
    static let card = Color(red: 0.06, green: 0.05, blue: 0.12)
    static let border = Color(red: 0.24, green: 0.20, blue: 0.38)
    static let primary = Color(red: 0.57, green: 0.38, blue: 0.96)
    static let primarySoft = Color(red: 0.43, green: 0.25, blue: 0.76)
    static let accent = Color(red: 0.31, green: 0.88, blue: 0.95)
    static let text = Color(red: 0.96, green: 0.94, blue: 1.0)
    static let textMuted = Color(red: 0.65, green: 0.62, blue: 0.76)
    static let searchCard = Color(red: 0.07, green: 0.06, blue: 0.14)
    static let userBubble = Color(red: 0.29, green: 0.13, blue: 0.65)
    static let danger = Color(red: 0.96, green: 0.32, blue: 0.40)
    static let warning = Color(red: 0.95, green: 0.69, blue: 0.25)

    @MainActor static func applySystemAppearance() {
        let navAppearance = UINavigationBarAppearance()
        navAppearance.configureWithOpaqueBackground()
        navAppearance.backgroundColor = UIColor(red: 0.02, green: 0.02, blue: 0.05, alpha: 1)
        navAppearance.shadowColor = UIColor(red: 0.24, green: 0.20, blue: 0.38, alpha: 0.9)
        navAppearance.titleTextAttributes = [
            .foregroundColor: UIColor(red: 0.96, green: 0.94, blue: 1.0, alpha: 1)
        ]
        navAppearance.largeTitleTextAttributes = navAppearance.titleTextAttributes

        UINavigationBar.appearance().prefersLargeTitles = false
        UINavigationBar.appearance().standardAppearance = navAppearance
        UINavigationBar.appearance().compactAppearance = navAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navAppearance
        UINavigationBar.appearance().compactScrollEdgeAppearance = navAppearance
    }

    static var backgroundGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.12, green: 0.08, blue: 0.28),
                Color(red: 0.04, green: 0.03, blue: 0.09),
                background
            ],
            startPoint: .top,
            endPoint: .bottom
        )
    }

    static var brandGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 1.0, green: 0.55, blue: 0.97),
                Color(red: 0.60, green: 0.43, blue: 1.0),
                Color(red: 0.40, green: 0.87, blue: 1.0)
            ],
            startPoint: .leading,
            endPoint: .trailing
        )
    }

    static var panelGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.07, green: 0.06, blue: 0.15).opacity(0.94),
                Color(red: 0.03, green: 0.03, blue: 0.08).opacity(0.96)
            ],
            startPoint: .top,
            endPoint: .bottom
        )
    }

    static var primaryGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.43, green: 0.27, blue: 0.92),
                Color(red: 0.45, green: 0.09, blue: 0.63)
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }

    static var selectedRowGradient: LinearGradient {
        LinearGradient(
            colors: [
                primary.opacity(0.56),
                primarySoft.opacity(0.48)
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }

    static var userBubbleGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.38, green: 0.16, blue: 0.80),
                Color(red: 0.25, green: 0.08, blue: 0.55)
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }

    static var composerGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.04, green: 0.04, blue: 0.10).opacity(0.98),
                Color(red: 0.09, green: 0.06, blue: 0.16).opacity(0.94)
            ],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    }

    static var toolCallGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.01, green: 0.15, blue: 0.17),
                Color(red: 0.03, green: 0.09, blue: 0.15)
            ],
            startPoint: .leading,
            endPoint: .trailing
        )
    }

    static var runningToolCallGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.30, green: 0.19, blue: 0.04),
                Color(red: 0.09, green: 0.05, blue: 0.17)
            ],
            startPoint: .leading,
            endPoint: .trailing
        )
    }

    static var failedToolCallGradient: LinearGradient {
        LinearGradient(
            colors: [
                Color(red: 0.27, green: 0.04, blue: 0.10),
                Color(red: 0.15, green: 0.03, blue: 0.07)
            ],
            startPoint: .leading,
            endPoint: .trailing
        )
    }
}

struct SybilWordmark: View {
    var size: CGFloat = 30

    var body: some View {
        Text("SYBIL")
            .font(.custom("Stalinist One", size: size))
            .fontWeight(.black)
            .tracking(0)
            .foregroundStyle(SybilTheme.brandGradient)
            .accessibilityLabel("Sybil")
    }
}
