use iced::widget::{column, text, text_input, Column, Scrollable, Space};
use iced::{Alignment, Element, Sandbox, Settings};
use once_cell::sync::Lazy;

pub fn main() -> iced::Result {
    Andes::run(Settings::default())
}

struct Andes {
    chat: Chat,
    context: String,
    input: String,
}

#[derive(Debug, Clone)]
enum Message {
    EditContext(String),
    EditInput(String),
    Send,
}

#[derive(Debug, Clone)]
struct ChatMessage {
    role: String,
    message: String,
}

#[derive(Debug, Clone)]
struct Chat {
    messages: Vec<ChatMessage>,
}

static INPUT_ID: Lazy<text_input::Id> = Lazy::new(|| text_input::Id::new("user_input"));

impl Sandbox for Andes {
    type Message = Message;

    fn new() -> Self {
        Self {
            chat: Chat {
                messages: vec![
                    ChatMessage {
                        role: "Andes".to_string(),
                        message: "Hello".to_string(),
                    },
                    ChatMessage {
                        role: "User".to_string(),
                        message: "Hi".to_string(),
                    },
                    ChatMessage {
                        role: "Andes".to_string(),
                        message: "How are you?".to_string(),
                    },
                    ChatMessage {
                        role: "User".to_string(),
                        message: "I'm fine".to_string(),
                    },
                    ChatMessage {
                        role: "Andes".to_string(),
                        message: "Good to hear".to_string(),
                    },
                ],
            },
            input: String::new(),
            context: String::new(),
        }
    }

    fn title(&self) -> String {
        String::from("Andes")
    }

    fn update(&mut self, message: Message) {
        match message {
            Message::EditContext(context) => {
                self.context = context;
            }
            Message::EditInput(input) => {
                self.input = input;
            }
            Message::Send => {
                let message = ChatMessage {
                    role: "user".to_string(),
                    message: self.input.clone(),
                };
                self.chat.messages.push(message);
                self.input.clear();
            }
        }
    }

    fn view(&self) -> Element<Message> {
        // lets dynamicall add the chat messages
        let mut messages = self
            .chat
            .messages
            .iter()
            .map(|message| {
                column![
                    text(&message.role).size(15),
                    text(&message.message).size(10)
                ]
                .align_items(Alignment::Start)
                .into()
            })
            .collect::<Vec<Element<Message>>>();

        messages.push(Space::new(20, 20).into());
        messages.push(
            text_input("Context... ", &self.context)
                .on_input(|s| Message::EditContext(s))
                .into(),
        );
        messages.push(Space::new(20, 20).into());
        messages.push(
            text_input("Message...", &self.input)
                .id(INPUT_ID.clone())
                .on_input(|s| Message::EditInput(s))
                .on_submit(Message::Send)
                .into(),
        );

        // full width
        let ui = Column::from_vec(messages)
            .padding(20)
            .width(iced::Length::Fill)
            .align_items(Alignment::Start);

        // put it in a scrollable container
        Scrollable::new(ui)
            .width(iced::Length::Fill)
            .height(iced::Length::Fill)
            .into()
    }
}
