import Foundation

public struct VejalNaiChatResponse: Decodable {
    public let data: Payload

    public struct Payload: Decodable {
        public let status: String
        public let platform: String
        public let conversationId: Int
        public let customerMessage: String
        public let botMessage: String?

        enum CodingKeys: String, CodingKey {
            case status
            case platform
            case conversationId = "conversation_id"
            case customerMessage = "customer_message"
            case botMessage = "bot_message"
        }
    }
}

public final class VejalNaiChatClient {
    private let baseURL: URL
    private let widgetKey: String
    private let visitorId: String
    private let locale: String
    private let session: URLSession

    public init(
        baseURL: URL,
        widgetKey: String,
        visitorId: String = "ios-\(UUID().uuidString)",
        locale: String = "bn",
        session: URLSession = .shared
    ) {
        self.baseURL = baseURL
        self.widgetKey = widgetKey
        self.visitorId = visitorId
        self.locale = locale
        self.session = session
    }

    public func sendMessage(
        _ body: String,
        name: String? = nil,
        phone: String? = nil,
        email: String? = nil
    ) async throws -> VejalNaiChatResponse {
        guard let endpoint = URL(string: "api/widget/messages", relativeTo: baseURL) else {
            throw URLError(.badURL)
        }

        var request = URLRequest(url: endpoint)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        var payload: [String: String] = [
            "widget_key": widgetKey,
            "visitor_id": visitorId,
            "platform": "ios",
            "locale": locale,
            "body": body,
        ]

        if let name {
            payload["name"] = name
        }

        if let phone {
            payload["phone"] = phone
        }

        if let email {
            payload["email"] = email
        }

        request.httpBody = try JSONEncoder().encode(payload)

        let (data, response) = try await session.data(for: request)

        guard let httpResponse = response as? HTTPURLResponse,
              (200...299).contains(httpResponse.statusCode) else {
            throw URLError(.badServerResponse)
        }

        return try JSONDecoder().decode(VejalNaiChatResponse.self, from: data)
    }
}
