use crate::registry::RouteInfo;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EditField {
    Method,
    Url,
    HeaderKey(usize),
    HeaderVal(usize),
    Body,
    None,
}

#[derive(Debug, Clone)]
pub struct RequestEditor {
    pub method: String,
    pub url: String,
    pub headers: Vec<(String, String)>,
    pub body: String,
    pub editing: EditField,
}

impl Default for RequestEditor {
    fn default() -> Self {
        Self {
            method: "GET".to_string(),
            url: String::new(),
            headers: vec![("Content-Type".to_string(), "application/json".to_string())],
            body: String::new(),
            editing: EditField::None,
        }
    }
}

impl RequestEditor {
    pub fn load_route(&mut self, route: &RouteInfo, base_url: &str) {
        self.method = route.method.clone();
        self.url = format!("{}{}", base_url.trim_end_matches('/'), route.path);
        self.body.clear();
        self.editing = EditField::None;
    }

    pub fn cycle_method(&mut self) {
        self.method = match self.method.as_str() {
            "GET" => "POST",
            "POST" => "PUT",
            "PUT" => "PATCH",
            "PATCH" => "DELETE",
            "DELETE" => "HEAD",
            _ => "GET",
        }
        .to_string();
    }

    pub fn add_header(&mut self) {
        self.headers.push((String::new(), String::new()));
    }

    pub fn remove_header(&mut self, idx: usize) {
        if idx < self.headers.len() {
            self.headers.remove(idx);
        }
    }

    pub fn push_char(&mut self, c: char) {
        match &self.editing {
            EditField::Url => self.url.push(c),
            EditField::Body => self.body.push(c),
            EditField::HeaderKey(i) => {
                if let Some((k, _)) = self.headers.get_mut(*i) {
                    k.push(c);
                }
            }
            EditField::HeaderVal(i) => {
                if let Some((_, v)) = self.headers.get_mut(*i) {
                    v.push(c);
                }
            }
            _ => {}
        }
    }

    pub fn pop_char(&mut self) {
        match &self.editing {
            EditField::Url => {
                self.url.pop();
            }
            EditField::Body => {
                self.body.pop();
            }
            EditField::HeaderKey(i) => {
                if let Some((k, _)) = self.headers.get_mut(*i) {
                    k.pop();
                }
            }
            EditField::HeaderVal(i) => {
                if let Some((_, v)) = self.headers.get_mut(*i) {
                    v.pop();
                }
            }
            _ => {}
        }
    }

    pub fn clear(&mut self) {
        *self = Self::default();
    }
}
