//
//  AuthService.swift
//  VolnahubApp
//
//  Created by cheykrym on 09/06/2025.
//

import Foundation

class AuthService {
    
    func autoLogin(completion: @escaping (Bool, String?) -> Void) {
        // 1️⃣ Проверяем наличие текущего пользователя
        if let currentUser = UserDefaults.standard.string(forKey: "currentUser"),
           let _ = KeychainService.shared.get(forKey: "access_token", service: currentUser),
           let _ = KeychainService.shared.get(forKey: "refresh_token", service: currentUser) {
            if AppConfig.DEBUG{ print("AutoLogin: найден текущий пользователь — \(currentUser)")}
            completion(true, nil)
            return
        }

        // 2️⃣ Текущий пользователь не найден или токены отсутствуют
        if AppConfig.DEBUG{ print("AutoLogin: текущий пользователь не найден или токены отсутствуют. Пробуем найти другого пользователя...")}
        
        let allUsers = KeychainService.shared.getAllServices()
        
        for user in allUsers {
            let hasAccessToken = KeychainService.shared.get(forKey: "access_token", service: user) != nil
            let hasRefreshToken = KeychainService.shared.get(forKey: "refresh_token", service: user) != nil
            
            if hasAccessToken && hasRefreshToken {
                // Нашли пользователя с токенами — назначаем как currentUser
                UserDefaults.standard.set(user, forKey: "currentUser")
                if AppConfig.DEBUG{ print("AutoLogin: переключились на пользователя \(user)")}
                completion(true, nil)
                return
            }
        }
        
        // 3️⃣ Если никто не найден
//        completion(false, "Не найден авторизованный пользователь. Пожалуйста, войдите снова.")
        completion(false, nil)
    }

    
    func login(username: String, password: String, completion: @escaping (Bool, String?) -> Void) {
        let url = URL(string: "\(AppConfig.API_SERVER)/v1/auth/login")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("\(AppConfig.USER_AGENT)", forHTTPHeaderField: "User-Agent")

        let payload: [String: String] = [
            "login": username,
            "password": password
        ]

        do {
            let jsonData = try JSONEncoder().encode(payload)
            request.httpBody = jsonData
        } catch {
            DispatchQueue.main.async {
                completion(false, NSLocalizedString("AuthService_error_serialization", comment: ""))
            }
            return
        }

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async {
                if let error = error {
                    let errorMessage = String(format: NSLocalizedString("AuthService_error_network", comment: ""), error.localizedDescription)
                    completion(false, errorMessage)
                    return
                }
                
                guard let httpResponse = response as? HTTPURLResponse else {
                    completion(false, NSLocalizedString("AuthService_error_invalid_response", comment: ""))
                    return
                }
                
                guard (200...299).contains(httpResponse.statusCode) else {
                    if httpResponse.statusCode == 401{
                        completion(false, NSLocalizedString("AuthService_error_invalid_credentials", comment: ""))
                    } else if httpResponse.statusCode == 502{
                        completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
                    } else if httpResponse.statusCode == 429 {
                        completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
                    } else {
                        let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
                        completion(false, errorMessage)
                    }
                    return
                }

                guard let data = data else {
                    completion(false, NSLocalizedString("AuthService_error_empty_response", comment: ""))
                    return
                }

                do {
                    let decoder = JSONDecoder()
                    let loginResponse = try decoder.decode(LoginResponse.self, from: data)
                    
                    // Сохраняем токены в Keychain
                    KeychainService.shared.save(loginResponse.access_token, forKey: "access_token", service: username)
                    KeychainService.shared.save(loginResponse.refresh_token, forKey: "refresh_token", service: username)
                    UserDefaults.standard.set(username, forKey: "currentUser")
                    
                    completion(true, nil)
                } catch {
                    completion(false, NSLocalizedString("AuthService_error_parsing_response", comment: ""))
                }
            }
        }
        task.resume()
    }

    func register(username: String, password: String, invite: String?, completion: @escaping (Bool, String?) -> Void) {
        let url = URL(string: "\(AppConfig.API_SERVER)/v1/auth/register")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue(AppConfig.USER_AGENT, forHTTPHeaderField: "User-Agent")

        let payload: [String: Any] = [
            "login": username,
            "password": password,
            "invite": invite ?? NSNull()
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: payload)
            request.httpBody = jsonData
        } catch {
            DispatchQueue.main.async {
                completion(false, NSLocalizedString("AuthService_error_serialization", comment: ""))
            }
            return
        }

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async {
                if let error = error {
                    let errorMessage = String(format: NSLocalizedString("AuthService_error_network", comment: ""), error.localizedDescription)
                    completion(false, errorMessage)
                    return
                }
                
                guard let httpResponse = response as? HTTPURLResponse else {
                    completion(false, NSLocalizedString("AuthService_error_invalid_response", comment: ""))
                    return
                }
                
                guard let data = data else {
                    completion(false, NSLocalizedString("AuthService_error_empty_response", comment: ""))
                    return
                }
                
                let decoder = JSONDecoder()
                
                if (200...299).contains(httpResponse.statusCode) {
                    do {
                        let _ = try decoder.decode(RegisterResponse.self, from: data)
                        if AppConfig.DEBUG{ print("Регистрация успешна. Пытаемся сразу войти...")}

                        // Сразу логинимся
                        self.login(username: username, password: password) { loginSuccess, loginMessage in
                            if loginSuccess {
                                completion(true, "Регистрация и вход выполнены успешно.")
                            } else {
                                // Регистрация успешна, но логин не удался — покажем сообщение
                                completion(false, loginMessage ?? NSLocalizedString("AuthService_login_success_but_failed", comment: ""))
                            }
                        }
                    } catch {
                        completion(false, NSLocalizedString("AuthService_error_parsing_response", comment: ""))
                    }
                } else {
                    // Ошибка сервера — пробуем распарсить message
                    if let errorResponseMessage = try? decoder.decode(ErrorResponseMessage.self, from: data),
                       let message = errorResponseMessage.message {
                        
                        if let jsonString = String(data: data, encoding: .utf8) {
                            if AppConfig.DEBUG{ print("Raw JSON:", jsonString)}
                        }
                        if AppConfig.DEBUG{ print("message:", message)}
                        
                        if httpResponse.statusCode == 400 {
                            if message.contains("Invalid invitation code") {
                                completion(false, NSLocalizedString("AuthService_error_invalid_invitation_code", comment: ""))
                            } else if message.contains("This invitation is not active") {
                                completion(false, NSLocalizedString("AuthService_error_invitation_not_active", comment: ""))
                            } else if message.contains("This invitation has reached its usage limit") {
                                completion(false, NSLocalizedString("AuthService_error_invitation_usage_limit", comment: ""))
                            } else if message.contains("This invitation has expired") {
                                completion(false, NSLocalizedString("AuthService_error_invitation_expired", comment: ""))
                            } else if message.contains("Login already registered") {
                                completion(false, NSLocalizedString("AuthService_error_login_already_registered", comment: ""))
                            } else {
                                completion(false, message)
                            }
                        } else if httpResponse.statusCode == 403 {
                            if message.contains("Registration is currently disabled") {
                                completion(false, NSLocalizedString("AuthService_error_registration_disabled", comment: ""))
                            } else {
                                completion(false, message)
                            }
                        } else if httpResponse.statusCode == 429 {
                            completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
                        } else if httpResponse.statusCode == 502{
                            completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
                        } else {
                            let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
                            completion(false, errorMessage)
                        }
                    } else {
                        // Не удалось распарсить JSON — fallback
                        if httpResponse.statusCode == 400 {
                            completion(false, NSLocalizedString("AuthService_error_invalid_request", comment: ""))
                        } else if httpResponse.statusCode == 403 {
                            completion(false, NSLocalizedString("AuthService_error_registration_forbidden", comment: ""))
                        } else if httpResponse.statusCode == 429 {
                            completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
                        } else if httpResponse.statusCode == 502{
                            completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
                        } else {
                            let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
                            completion(false, errorMessage)
                        }
                    }
                }
            }
        }
        task.resume()
    }




    func logoutCurrentUser(completion: @escaping (Bool, String?) -> Void) {
        guard let currentUser = UserDefaults.standard.string(forKey: "currentUser") else {
            completion(false, "Не найден текущий пользователь.")
            return
        }
        
        // Удаляем токены текущего пользователя
        KeychainService.shared.delete(forKey: "access_token", service: currentUser)
        KeychainService.shared.delete(forKey: "refresh_token", service: currentUser)
        
        // Сбрасываем текущего пользователя
        UserDefaults.standard.removeObject(forKey: "currentUser")
        
        // Пробуем переключиться на другого пользователя
        let allUsers = KeychainService.shared.getAllServices()
        for user in allUsers {
            let hasAccessToken = KeychainService.shared.get(forKey: "access_token", service: user) != nil
            let hasRefreshToken = KeychainService.shared.get(forKey: "refresh_token", service: user) != nil
            
            if hasAccessToken && hasRefreshToken {
                UserDefaults.standard.set(user, forKey: "currentUser")
                if AppConfig.DEBUG{ print("Logout: переключились на пользователя \(user)")}
                completion(true, nil)
                return
            }
        }

        // Если пользователей больше нет
//        completion(false, "Нет доступных пользователей. Пожалуйста, войдите снова.")
        completion(false, nil)
    }
}

struct LoginResponse: Decodable {
    let status: String
    let access_token: String
    let refresh_token: String
    let token_type: String
}

struct TokenRefreshResponse: Decodable {
    let status: String
    let access_token: String
    let token_type: String
}

struct RegisterResponse: Decodable {
    let status: String
    let message: String
}

struct ErrorResponseMessage: Decodable {
    let status: String?
    let message: String?
}
