use std::env;
use tdlib_rs::enums::{AuthorizationState, ChatList, MessageContent, Update, User};
use tdlib_rs::functions;
use tdlib_rs::types::{Chat as TdChat, Message as TdMessage};

#[derive(Debug, Clone, PartialEq)]
pub enum AuthState {
    WaitTdlibParameters,
    WaitPhoneNumber,
    WaitCode,
    WaitPassword,
    Ready,
    Closed,
    Error(String),
}

#[derive(Debug, Clone)]
pub struct ChatInfo {
    pub id: i64,
    pub title: String,
    pub last_message: String,
    pub unread_count: i32,
    pub is_pinned: bool,
    pub order: i64,
}

#[derive(Debug, Clone)]
pub struct MessageInfo {
    pub id: i64,
    pub sender_name: String,
    pub is_outgoing: bool,
    pub content: String,
    pub date: i32,
    pub is_read: bool,
}

pub struct TdClient {
    pub auth_state: AuthState,
    pub api_id: i32,
    pub api_hash: String,
    client_id: i32,
    pub chats: Vec<ChatInfo>,
    pub current_chat_messages: Vec<MessageInfo>,
}

impl TdClient {
    pub fn new() -> Self {
        let api_id: i32 = env::var("API_ID")
            .unwrap_or_else(|_| "0".to_string())
            .parse()
            .unwrap_or(0);
        let api_hash = env::var("API_HASH").unwrap_or_default();

        let client_id = tdlib_rs::create_client();

        TdClient {
            auth_state: AuthState::WaitTdlibParameters,
            api_id,
            api_hash,
            client_id,
            chats: Vec::new(),
            current_chat_messages: Vec::new(),
        }
    }

    pub fn is_authenticated(&self) -> bool {
        matches!(self.auth_state, AuthState::Ready)
    }

    /// Инициализация TDLib с параметрами
    pub async fn init(&mut self) -> Result<(), String> {
        let result = functions::set_tdlib_parameters(
            false,                                    // use_test_dc
            "tdlib_data".to_string(),                // database_directory
            "".to_string(),                          // files_directory
            "".to_string(),                          // database_encryption_key (String, not Vec)
            true,                                    // use_file_database
            true,                                    // use_chat_info_database
            true,                                    // use_message_database
            false,                                   // use_secret_chats
            self.api_id,                             // api_id
            self.api_hash.clone(),                   // api_hash
            "en".to_string(),                        // system_language_code
            "Desktop".to_string(),                   // device_model
            "".to_string(),                          // system_version
            env!("CARGO_PKG_VERSION").to_string(),   // application_version
            self.client_id,
        )
        .await;

        match result {
            Ok(_) => Ok(()),
            Err(e) => Err(format!("Failed to set TDLib parameters: {:?}", e)),
        }
    }

    /// Обрабатываем одно обновление от TDLib
    pub fn handle_update(&mut self, update: Update) {
        match update {
            Update::AuthorizationState(state) => {
                self.handle_auth_state(state.authorization_state);
            }
            Update::NewChat(new_chat) => {
                self.add_or_update_chat(&new_chat.chat);
            }
            Update::ChatLastMessage(update) => {
                let chat_id = update.chat_id;
                let last_message_text = update
                    .last_message
                    .as_ref()
                    .map(|msg| extract_message_text_static(msg))
                    .unwrap_or_default();

                if let Some(chat) = self.chats.iter_mut().find(|c| c.id == chat_id) {
                    chat.last_message = last_message_text;
                }
            }
            Update::ChatReadInbox(update) => {
                if let Some(chat) = self.chats.iter_mut().find(|c| c.id == update.chat_id) {
                    chat.unread_count = update.unread_count;
                }
            }
            Update::NewMessage(_new_msg) => {
                // Новые сообщения обрабатываются при обновлении UI
            }
            _ => {}
        }
    }

    fn handle_auth_state(&mut self, state: AuthorizationState) {
        self.auth_state = match state {
            AuthorizationState::WaitTdlibParameters => AuthState::WaitTdlibParameters,
            AuthorizationState::WaitPhoneNumber => AuthState::WaitPhoneNumber,
            AuthorizationState::WaitCode(_) => AuthState::WaitCode,
            AuthorizationState::WaitPassword(_) => AuthState::WaitPassword,
            AuthorizationState::Ready => AuthState::Ready,
            AuthorizationState::Closed => AuthState::Closed,
            _ => self.auth_state.clone(),
        };
    }

    fn add_or_update_chat(&mut self, td_chat: &TdChat) {
        let last_message = td_chat
            .last_message
            .as_ref()
            .map(|m| extract_message_text_static(m))
            .unwrap_or_default();

        let chat_info = ChatInfo {
            id: td_chat.id,
            title: td_chat.title.clone(),
            last_message,
            unread_count: td_chat.unread_count,
            is_pinned: false,
            order: 0,
        };

        if let Some(existing) = self.chats.iter_mut().find(|c| c.id == td_chat.id) {
            existing.title = chat_info.title;
            existing.last_message = chat_info.last_message;
            existing.unread_count = chat_info.unread_count;
        } else {
            self.chats.push(chat_info);
        }
    }

    fn convert_message(&self, message: &TdMessage) -> MessageInfo {
        let sender_name = match &message.sender_id {
            tdlib_rs::enums::MessageSender::User(user) => format!("User_{}", user.user_id),
            tdlib_rs::enums::MessageSender::Chat(chat) => format!("Chat_{}", chat.chat_id),
        };

        MessageInfo {
            id: message.id,
            sender_name,
            is_outgoing: message.is_outgoing,
            content: extract_message_text_static(message),
            date: message.date,
            is_read: !message.is_outgoing || message.id <= 0,
        }
    }

    /// Отправка номера телефона
    pub async fn send_phone_number(&mut self, phone: String) -> Result<(), String> {
        let result = functions::set_authentication_phone_number(
            phone,
            None,
            self.client_id,
        )
        .await;

        match result {
            Ok(_) => Ok(()),
            Err(e) => Err(format!("Ошибка отправки номера: {:?}", e)),
        }
    }

    /// Отправка кода подтверждения
    pub async fn send_code(&mut self, code: String) -> Result<(), String> {
        let result = functions::check_authentication_code(code, self.client_id).await;

        match result {
            Ok(_) => Ok(()),
            Err(e) => Err(format!("Неверный код: {:?}", e)),
        }
    }

    /// Отправка пароля 2FA
    pub async fn send_password(&mut self, password: String) -> Result<(), String> {
        let result = functions::check_authentication_password(password, self.client_id).await;

        match result {
            Ok(_) => Ok(()),
            Err(e) => Err(format!("Неверный пароль: {:?}", e)),
        }
    }

    /// Загрузка списка чатов
    pub async fn load_chats(&mut self, limit: i32) -> Result<(), String> {
        let result = functions::load_chats(
            Some(ChatList::Main),
            limit,
            self.client_id,
        )
        .await;

        match result {
            Ok(_) => Ok(()),
            Err(e) => Err(format!("Ошибка загрузки чатов: {:?}", e)),
        }
    }

    /// Загрузка истории сообщений чата
    pub async fn get_chat_history(
        &mut self,
        chat_id: i64,
        limit: i32,
    ) -> Result<Vec<MessageInfo>, String> {
        let _ = functions::open_chat(chat_id, self.client_id).await;

        let result = functions::get_chat_history(
            chat_id,
            0,
            0,
            limit,
            false,
            self.client_id,
        )
        .await;

        match result {
            Ok(tdlib_rs::enums::Messages::Messages(messages)) => {
                let mut result_messages: Vec<MessageInfo> = messages
                    .messages
                    .into_iter()
                    .filter_map(|m| m.map(|msg| self.convert_message(&msg)))
                    .collect();

                result_messages.reverse();
                self.current_chat_messages = result_messages.clone();
                Ok(result_messages)
            }
            Err(e) => Err(format!("Ошибка загрузки сообщений: {:?}", e)),
        }
    }

    /// Получение информации о пользователе по ID
    pub async fn get_user_name(&self, user_id: i64) -> String {
        match functions::get_user(user_id, self.client_id).await {
            Ok(user) => {
                // User is an enum, need to match it
                match user {
                    User::User(u) => {
                        let first = u.first_name;
                        let last = u.last_name;
                        if last.is_empty() {
                            first
                        } else {
                            format!("{} {}", first, last)
                        }
                    }
                }
            }
            Err(_) => format!("User_{}", user_id),
        }
    }

    /// Получение моего user_id
    pub async fn get_me(&self) -> Result<i64, String> {
        match functions::get_me(self.client_id).await {
            Ok(user) => {
                match user {
                    User::User(u) => Ok(u.id),
                }
            }
            Err(e) => Err(format!("Ошибка получения профиля: {:?}", e)),
        }
    }
}

/// Статическая функция для извлечения текста сообщения (без &self)
fn extract_message_text_static(message: &TdMessage) -> String {
    match &message.content {
        MessageContent::MessageText(text) => text.text.text.clone(),
        MessageContent::MessagePhoto(photo) => {
            if photo.caption.text.is_empty() {
                "[Фото]".to_string()
            } else {
                format!("[Фото] {}", photo.caption.text)
            }
        }
        MessageContent::MessageVideo(_) => "[Видео]".to_string(),
        MessageContent::MessageDocument(doc) => {
            format!("[Файл: {}]", doc.document.file_name)
        }
        MessageContent::MessageVoiceNote(_) => "[Голосовое сообщение]".to_string(),
        MessageContent::MessageVideoNote(_) => "[Видеосообщение]".to_string(),
        MessageContent::MessageSticker(sticker) => {
            format!("[Стикер: {}]", sticker.sticker.emoji)
        }
        MessageContent::MessageAnimation(_) => "[GIF]".to_string(),
        MessageContent::MessageAudio(audio) => {
            format!("[Аудио: {}]", audio.audio.title)
        }
        MessageContent::MessageCall(_) => "[Звонок]".to_string(),
        MessageContent::MessagePoll(poll) => {
            format!("[Опрос: {}]", poll.poll.question.text)
        }
        _ => "[Сообщение]".to_string(),
    }
}
