use crate::request::Request;
use crate::response::Response;
use crate::{Handler};
use json::{object, JsonValue};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::{Arc, Mutex};
use std::{io, thread};
use std::time::Duration;
use dashmap::DashMap;

pub static USERS: std::sync::LazyLock<DashMap<String, Websocket>> = std::sync::LazyLock::new(DashMap::new);
pub static WS_NOTICE: std::sync::LazyLock<Mutex<Vec<NoticeMsg>>> = std::sync::LazyLock::new(|| Mutex::new(Vec::new()));
#[derive(Debug, Clone)]
pub struct Websocket {
    /// 发送
    send: Option<Sender<Message>>,
    /// 接收
    receive: Option<Arc<Mutex<Receiver<Message>>>>,
    pub key: String,
    pub user_user: String,
    version: String,
    request: Request,
    response: Response,
}


impl Websocket {
    pub fn http(request: Request, response: Response) -> Self {
        Self {
            send: None,
            receive: None,
            request,
            key: String::new(),
            user_user: "".to_string(),
            version: String::new(),
            response,
        }
    }
    pub fn new(request: Request, response: Response) -> Self {
        let (send, receive) = channel();
        Self {
            send: Some(send),
            receive: Some(Arc::new(Mutex::new(receive))),
            request,
            key: String::new(),
            user_user: "".to_string(),
            version: String::new(),
            response,
        }
    }
    /// 发送数据
    pub fn send(&mut self, data: JsonValue) {
        let msg = Message {
            mode: MessageMode::Server,
            message_type: MessageType::Text,
            payload: data.to_string().into_bytes(),
            text: data.to_string(),
            close: CloseCode::None,
            error: ErrorCode::None,
        };
        match self.send.clone().unwrap().send(msg) {
            Ok(()) => (),
            Err(_) => self.on_error(ErrorCode::SendingDataFailed),
        }
    }
    /// 关闭连接
    pub fn close(&mut self, code: CloseCode, reason: &str) {
        let msg = Message {
            mode: MessageMode::Server,
            message_type: MessageType::Close,
            payload: reason.as_bytes().to_vec(),
            text: reason.to_string(),
            close: code,
            error: ErrorCode::None,
        };
        match self.send.clone().unwrap().send(msg) {
            Ok(()) => (),
            Err(_) => self.on_error(ErrorCode::SendingDataFailed),
        }
    }
    /// 发送给所有对象
    pub fn send_all(&mut self, data: JsonValue) {
        for mut user in USERS.iter_mut() {
            user.send(data.clone());
        }
    }
    /// 发送给指定对象
    pub fn send_user(&mut self, user_user: &str, data: JsonValue) {
        if USERS.get(user_user).is_none() {
            for mut user in USERS.iter_mut() {
                if user.user_user == user_user {
                    user.send(data.clone());
                    return;
                }
            }
        } else {
            USERS.get_mut(user_user).unwrap().send(data.clone());
        }
    }
    /// 在线人数
    pub fn online_users(&mut self) -> usize {
        USERS.len()
    }
    pub fn handle(&mut self, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
        let receive = self.receive.clone().unwrap();
        self.on_frame()?;
        let mut factory = factory(self.clone());
        USERS.insert(self.key.to_string(), self.clone());
        factory.on_open()?;
        loop {
            let msg = self.response.scheme.lock().unwrap().read_ws_msg()?;
            match msg.message_type {
                MessageType::TimeOut => {}
                _ => match self.send.clone().unwrap().clone().send(msg) {
                    Ok(_) => {}
                    Err(e) => return Err(io::Error::new(io::ErrorKind::BrokenPipe, e))
                }
            }
            let data = receive.lock().unwrap();
            match data.try_recv() {
                Ok(mut msg) => {
                    match msg.mode {
                        MessageMode::Client => {
                            match msg.message_type {
                                MessageType::Close => {
                                    if USERS.get(&self.key.to_string()).is_some() {
                                        USERS.remove(&self.key);
                                    }
                                    factory.on_close(msg.close.clone(), &msg.text);
                                    self.response.scheme.lock().unwrap().write(&Message::send_close(CloseCode::ServerClose,"客户退出关闭"))?;
                                    return Err(io::Error::new(io::ErrorKind::BrokenPipe, msg.text));
                                }
                                MessageType::Binary | MessageType::Text => {
                                    factory.on_message(msg).expect("TODO: panic message");
                                }
                                MessageType::Continuation | MessageType::Ping | MessageType::Pong | MessageType::None | MessageType::Error => {
                                    println!("有数据: {:?} {:?} {}", msg.mode, msg.message_type, msg.text.clone());
                                }
                                MessageType::TimeOut => continue
                            }
                        }
                        MessageMode::Server => {
                            match msg.message_type {
                                MessageType::Close => {
                                    if USERS.get(&self.key.to_string()).is_some() {
                                        USERS.remove(&self.key);
                                    }
                                    factory.on_close(msg.close.clone(), &msg.text);
                                    self.response.scheme.lock().unwrap().write(&Message::send_close(msg.close.clone(), &msg.text))?;
                                    return Err(io::Error::new(io::ErrorKind::BrokenPipe, msg.text));
                                }
                                MessageType::Binary | MessageType::Text => {
                                    let res = msg.send_message();
                                    self.response.scheme.lock().unwrap().write(&res)?;
                                }
                                MessageType::Continuation | MessageType::Ping | MessageType::Pong | MessageType::None | MessageType::Error => {
                                    println!("有数据: {:?} {:?} {}", msg.mode, msg.message_type, msg.text.clone());
                                }
                                MessageType::TimeOut => continue
                            }
                        }
                    }
                }
                Err(std::sync::mpsc::TryRecvError::Empty) => {
                    thread::sleep(Duration::from_millis(10));
                    continue;
                }
                Err(e) => {
                    return Err(io::Error::new(io::ErrorKind::BrokenPipe, e));
                }
            }
        }
    }
}
impl Handler for Websocket {
    fn on_frame(&mut self) -> io::Result<()> {
        self.key = self.request.header["sec-websocket-key"].as_str().unwrap_or("").to_string();
        self.version = self.request.header["sec-websocket-version"].as_str().unwrap_or("").to_string();
        self.response.status(101).websocket(self.key.as_str()).send()?;
        Ok(())
    }
}
#[derive(Debug, Clone)]
pub struct Message {
    pub mode: MessageMode,
    pub message_type: MessageType,
    pub payload: Vec<u8>, // 消息载荷，以字节向量形式表示
    pub text: String,
    pub close: CloseCode,
    pub error: ErrorCode,
}

impl Message {
    pub fn msg_error() -> Self {
        Message {
            mode: MessageMode::Client,
            message_type: MessageType::Error,
            payload: vec![],
            text: "长度不够".to_string(),
            close: CloseCode::None,
            error: ErrorCode::SendingDataFailed,
        }
    }
    // 解析WebSocket消息
    pub fn parse_message(data: &mut Vec<u8>) -> Message {
        // 检查数据是否足够长来包含消息类型和载荷长度
        if data.len() < 2 {
            return Message {
                mode: MessageMode::Client,
                message_type: MessageType::Error,
                payload: vec![],
                text: "长度不够".to_string(),
                close: CloseCode::None,
                error: ErrorCode::SendingDataFailed,
            };
        }

        let header = data.drain(0..2).collect::<Vec<u8>>();

        // 解析帧头
        let _fin = (header[0] & 0b1000_0000) != 0;
        let opcode = header[0] & 0b0000_1111;
        let masked = (header[1] & 0b1000_0000) != 0;
        let len_flag = header[1] & 0b0111_1111;

        let mut payload_data = Vec::new();
        let message_tpye = MessageType::from(opcode);
        match message_tpye {
            MessageType::Text => {
                let payload_length = match len_flag {
                    0..=125 => len_flag as usize,
                    126 => {
                        let ext = data.drain(..2).collect::<Vec<u8>>();
                        u16::from_be_bytes([ext[0], ext[1]]) as usize
                    }
                    127 => {
                        let ext = data.drain(..8).collect::<Vec<u8>>();
                        u64::from_be_bytes([
                            ext[0], ext[1], ext[2], ext[3],
                            ext[4], ext[5], ext[6], ext[7],
                        ]) as usize
                    }
                    _ => return Message {
                        mode: MessageMode::Client,
                        message_type: MessageType::Error,
                        payload: vec![],
                        text: "数据格式错误".to_string(),
                        close: CloseCode::None,
                        error: ErrorCode::SendingDataFailed,
                    }
                };
                if masked {
                    let mask_key = data.drain(..4).collect::<Vec<u8>>();
                    let payload = std::mem::take(data);
                    for i in 0..payload.len() {
                        payload_data.push(payload[i] ^ mask_key[i % 4]);
                    }
                } else {
                    let t = data.drain(..payload_length).collect::<Vec<u8>>();
                    payload_data.extend_from_slice(&t);
                }
                let text = unsafe { String::from_utf8_unchecked(payload_data.clone()) };
                Message {
                    mode: MessageMode::Client,
                    message_type: message_tpye,
                    payload: payload_data,
                    text: text.to_string(),
                    close: CloseCode::None,
                    error: ErrorCode::None,
                }
            }
            MessageType::Binary => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: payload_data,
                text: String::new(),
                close: CloseCode::None,
                error: ErrorCode::None,
            },
            MessageType::Continuation => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: payload_data,
                text: "继续加载".to_string(),
                close: CloseCode::None,
                error: ErrorCode::None,
            },
            MessageType::Close => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: vec![],
                text: "客户端关闭".to_string(),
                close: CloseCode::ClientClose,
                error: ErrorCode::None,
            },
            MessageType::Ping => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: vec![],
                text: "Ping".to_string(),
                close: CloseCode::None,
                error: ErrorCode::None,
            },
            MessageType::Pong => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: vec![],
                text: "Pong".to_string(),
                close: CloseCode::None,
                error: ErrorCode::None,
            },
            MessageType::Error => {
                Message {
                    mode: MessageMode::Client,
                    message_type: message_tpye,
                    payload: vec![],
                    text: String::new(),
                    close: CloseCode::None,
                    error: ErrorCode::Unknown,
                }
            }
            MessageType::None => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: vec![],
                text: String::new(),
                close: CloseCode::None,
                error: ErrorCode::None,
            },
            MessageType::TimeOut => Message {
                mode: MessageMode::Client,
                message_type: message_tpye,
                payload: vec![],
                text: String::new(),
                close: CloseCode::None,
                error: ErrorCode::TimeOut,
            }
        }
    }
    pub fn send_message(&mut self) -> Vec<u8> {
        let mut frame = Vec::new();

        // 第1字节：FIN + RSV1-3 + OPCODE
        let opcode = self.clone().message_type.to_u8();
        let mut byte1 = opcode & 0x0F;
        byte1 |= 0x80; // FIN = 1

        frame.push(byte1);

        // 第2字节：MASK = 0（服务器发送），+ payload length
        let payload_len = self.payload.len();
        if payload_len < 126 {
            frame.push(payload_len as u8);
        } else if payload_len <= 65535 {
            frame.push(126);
            frame.extend_from_slice(&u16::try_from(payload_len).unwrap().to_be_bytes());
        } else {
            frame.push(127);
            frame.extend_from_slice(&(payload_len as u64).to_be_bytes());
        }
        frame.extend_from_slice(&self.payload);
        frame
    }
    pub fn send_close(code: CloseCode, reason: &str) -> Vec<u8> {
        let mut frame = Vec::new();
        frame.push(0x88);
        let payload_len = code.clone().to_u16().to_be_bytes().len() + reason.len();
        frame.push(u8::try_from(payload_len).unwrap());
        frame.extend(&code.to_u16().to_be_bytes());
        frame.extend(reason.as_bytes());
        frame
    }
}
#[derive(Debug, Clone)]
pub enum MessageType {
    /// 文本
    Text,
    Continuation,
    /// 客户端关闭
    Close,
    Binary,
    Ping,
    Pong,
    None,
    TimeOut,
    Error,
}

impl MessageType {
    #[must_use]
    pub fn from(types: u8) -> Self {
        match types {
            0x0 => Self::Continuation,
            0x1 => Self::Text,
            0x2 => Self::Binary,
            0x8 => Self::Close,
            0x9 => Self::Ping,
            0xa => Self::Pong,
            _ => Self::None,
        }
    }
    #[must_use]
    pub fn to_u8(self) -> u8 {
        match self {
            MessageType::Text => 0x1,
            MessageType::Continuation | MessageType::None => 0x0,
            MessageType::Close => 0x8,
            MessageType::Binary => 0x2,
            MessageType::Ping => 0x9,
            MessageType::Pong => 0xa,
            MessageType::Error | MessageType::TimeOut => 0x0,
        }
    }
}
#[derive(Debug, Clone)]
pub enum CloseCode {
    /// 客户端主动关闭
    ClientClose,
    /// 服务端主动关闭
    ServerClose,
    /// 正常关闭
    NormalClosure,
    GoingAway,
    /// 协议错误
    ProtocolError,
    /// 其它错误
    Other,
    None,
}
impl CloseCode {
    #[must_use]
    pub fn from_err(_err: ErrorCode) -> CloseCode {
        CloseCode::None
    }
    #[must_use]
    pub fn str(&self) -> String {
        match self {
            CloseCode::ClientClose => "客户端主动关闭",
            CloseCode::ServerClose => "服务端主动关闭",
            CloseCode::None => "未知关闭",
            CloseCode::NormalClosure => "正常关闭",
            CloseCode::GoingAway => "对方离开",
            CloseCode::ProtocolError => "协议错误",
            CloseCode::Other => "其它错误",
        }.to_string()
    }
    #[must_use]
    pub fn to_u16(self) -> u16 {
        match self {
            CloseCode::NormalClosure => 1000,
            CloseCode::GoingAway => 1001,
            CloseCode::ProtocolError => 1002,
            CloseCode::ClientClose => 1003,
            CloseCode::ServerClose => 1004,
            CloseCode::Other => 1005,
            CloseCode::None => 1006,
        }
    }
}
#[derive(Debug, Clone, Copy)]
pub enum ErrorCode {
    /// 发送数据失败
    SendingDataFailed,
    /// Unknown request error
    Unknown,
    /// 线程异常
    ThreadException,
    /// 超时
    TimeOut,
    None,
}
#[derive(Debug, Clone)]
pub enum MessageMode {
    Client,
    Server,
}

pub struct NoticeMsg {
    /// 消息实体内容
    pub msg: JsonValue,
    /// 消息创建时间
    pub timestamp: i64,
    /// 通道名称
    pub channel: String,
}
impl NoticeMsg {
    pub fn json(&mut self) -> JsonValue {
        object! {
            type: "notice",
            channel: self.channel.clone(),
            msg: self.msg.clone(),
            timestamp: self.timestamp,
        }
    }
}