use std::{iter, mem, str};

use crate::markdown::{MdStream, MdTree};

/// Short aliases that we can use in match patterns. If an end pattern is not
/// included, this type may be variable
const ANC_E: &[u8] = b">";
const ANC_S: &[u8] = b"<";
const BRK: &[u8] = b"---";
const CBK: &[u8] = b"```";
const CIL: &[u8] = b"`";
const CMT_E: &[u8] = b"-->";
const CMT_S: &[u8] = b"<!--";
const EMP_U: &[u8] = b"_";
const EMP_A: &[u8] = b"*";
const HDG: &[u8] = b"#";
const LNK_CHARS: &str = "$-_.+!*'()/&?=:%";
const LNK_E: &[u8] = b"]";
const LNK_S: &[u8] = b"[";
const STG_U: &[u8] = b"__";
const STG_A: &[u8] = b"**";
const STK: &[u8] = b"~~";

/// Pattern replacements
const REPLACEMENTS: &[(&str, &str)] = &[
    ("(c)", "©"),
    ("(C)", "©"),
    ("(r)", "®"),
    ("(R)", "®"),
    ("(tm)", "™"),
    ("(TM)", "™"),
    (":crab:", "🦀"),
    ("\n", " "),
];

/// `(extracted, remaining)`
type Parsed<'a> = (MdTree<'a>, &'a [u8]);
/// Output of a parse function
type ParseResult<'a> = Option<Parsed<'a>>;

/// Parsing context
#[derive(Clone, Copy, Debug, PartialEq)]
// The default values are the most common setting for non top-level parsing: not top block, not at
// line start (yes leading whitespace, not escaped).
struct Context {
    /// If true, we are at a the topmost level (not recursing a nested tt)
    top_block: bool = false,
    /// Previous character
    prev: Prev = Prev::Whitespace,
}

/// Character class preceding this one
#[derive(Clone, Copy, Debug, PartialEq)]
enum Prev {
    Newline,
    /// Whitespace that is not a newline
    Whitespace,
    Escape,
    Any,
}

/// Flags to simple parser function
#[derive(Clone, Copy, Debug, PartialEq)]
enum ParseOpt {
    /// Ignore escapes before closing pattern, trim content
    TrimNoEsc,
    None,
}

/// Parse a buffer
pub(crate) fn entrypoint(txt: &str) -> MdStream<'_> {
    let ctx = Context { top_block: true, prev: Prev::Newline };
    normalize(parse_recursive(txt.trim().as_bytes(), ctx), &mut Vec::new())
}

/// Parse a buffer with specified context
fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'a> {
    use ParseOpt as Po;
    use Prev::{Escape, Newline, Whitespace};

    let mut stream: Vec<MdTree<'a>> = Vec::new();
    let Context { top_block: top_blk, mut prev } = ctx;

    // wip_buf is our entire unprocessed (unpushed) buffer, loop_buf is our to
    // check buffer that shrinks with each loop
    let mut wip_buf = buf;
    let mut loop_buf = wip_buf;

    while !loop_buf.is_empty() {
        let next_prev = match loop_buf[0] {
            b'\n' => Newline,
            b'\\' => Escape,
            x if x.is_ascii_whitespace() => Whitespace,
            _ => Prev::Any,
        };

        let res: ParseResult<'_> = match (top_blk, prev) {
            _ if loop_buf.starts_with(CMT_S) => {
                parse_simple_pat(loop_buf, CMT_S, CMT_E, Po::TrimNoEsc, MdTree::Comment)
            }
            (true, Newline) if loop_buf.starts_with(CBK) => Some(parse_codeblock(loop_buf)),
            _ if loop_buf.starts_with(CIL) => parse_codeinline(loop_buf),
            (true, Newline | Whitespace) if loop_buf.starts_with(HDG) => parse_heading(loop_buf),
            (true, Newline) if loop_buf.starts_with(BRK) => {
                Some((MdTree::HorizontalRule, parse_to_newline(loop_buf).1))
            }
            (_, Newline) if unordered_list_start(loop_buf) => Some(parse_unordered_li(loop_buf)),
            (_, Newline | Whitespace) if loop_buf.starts_with(STG_U) => {
                parse_simple_pat(loop_buf, STG_U, STG_U, Po::None, MdTree::Strong)
            }
            _ if loop_buf.starts_with(STG_A) => {
                parse_simple_pat(loop_buf, STG_A, STG_A, Po::None, MdTree::Strong)
            }
            (_, Newline | Whitespace) if loop_buf.starts_with(EMP_U) => {
                parse_simple_pat(loop_buf, EMP_U, EMP_U, Po::None, MdTree::Emphasis)
            }
            _ if loop_buf.starts_with(EMP_A) => {
                parse_simple_pat(loop_buf, EMP_A, EMP_A, Po::None, MdTree::Emphasis)
            }
            _ if loop_buf.starts_with(STK) => {
                parse_simple_pat(loop_buf, STK, STK, Po::None, MdTree::Strikethrough)
            }
            (_, Newline | Whitespace) if loop_buf.starts_with(ANC_S) => {
                let tt_fn = |link| MdTree::Link { disp: link, link };
                let ret = parse_simple_pat(loop_buf, ANC_S, ANC_E, Po::None, tt_fn);
                match ret {
                    Some((MdTree::Link { disp, .. }, _))
                        if disp.chars().all(|ch| LNK_CHARS.contains(ch)) =>
                    {
                        ret
                    }
                    _ => None,
                }
            }
            (_, Newline) if ord_list_start(loop_buf).is_some() => Some(parse_ordered_li(loop_buf)),
            _ if loop_buf.starts_with(LNK_S) => {
                parse_any_link(loop_buf, top_blk && prev == Prev::Newline)
            }
            (_, Escape | _) => None,
        };

        if let Some((tree, rest)) = res {
            // We found something: push our WIP and then push the found tree
            let prev_buf = &wip_buf[..(wip_buf.len() - loop_buf.len())];
            if !prev_buf.is_empty() {
                let prev_str = str::from_utf8(prev_buf).unwrap();
                stream.push(MdTree::PlainText(prev_str));
            }
            stream.push(tree);

            wip_buf = rest;
            loop_buf = rest;
        } else {
            // Just move on to the next character
            loop_buf = &loop_buf[1..];
            // If we are at the end and haven't found anything, just push plain text
            if loop_buf.is_empty() && !wip_buf.is_empty() {
                let final_str = str::from_utf8(wip_buf).unwrap();
                stream.push(MdTree::PlainText(final_str));
            }
        };

        prev = next_prev;
    }

    MdStream(stream)
}

/// The simplest kind of patterns: data within start and end patterns
fn parse_simple_pat<'a, F>(
    buf: &'a [u8],
    start_pat: &[u8],
    end_pat: &[u8],
    opts: ParseOpt,
    create_tt: F,
) -> ParseResult<'a>
where
    F: FnOnce(&'a str) -> MdTree<'a>,
{
    let ignore_esc = matches!(opts, ParseOpt::TrimNoEsc);
    let trim = matches!(opts, ParseOpt::TrimNoEsc);
    let (txt, rest) = parse_with_end_pat(&buf[start_pat.len()..], end_pat, ignore_esc)?;
    let mut txt = str::from_utf8(txt).unwrap();
    if trim {
        txt = txt.trim();
    }
    Some((create_tt(txt), rest))
}

/// Parse backtick-wrapped inline code. Accounts for >1 backtick sets
fn parse_codeinline(buf: &[u8]) -> ParseResult<'_> {
    let seps = buf.iter().take_while(|ch| **ch == b'`').count();
    let (txt, rest) = parse_with_end_pat(&buf[seps..], &buf[..seps], true)?;
    Some((MdTree::CodeInline(str::from_utf8(txt).unwrap()), rest))
}

/// Parse a codeblock. Accounts for >3 backticks and language specification
fn parse_codeblock(buf: &[u8]) -> Parsed<'_> {
    // account for ````code```` style
    let seps = buf.iter().take_while(|ch| **ch == b'`').count();
    let end_sep = &buf[..seps];
    let mut working = &buf[seps..];

    // Handle "````rust" style language specifications
    let next_ws_idx = working.iter().take_while(|ch| !ch.is_ascii_whitespace()).count();

    let lang = if next_ws_idx > 0 {
        // Munch the lang
        let tmp = str::from_utf8(&working[..next_ws_idx]).unwrap();
        working = &working[next_ws_idx..];
        Some(tmp)
    } else {
        None
    };

    let mut end_pat = vec![b'\n'];
    end_pat.extend(end_sep);

    // Find first end pattern with nothing else on its line
    let mut found = None;
    for idx in (0..working.len()).filter(|idx| working[*idx..].starts_with(&end_pat)) {
        let (eol_txt, rest) = parse_to_newline(&working[(idx + end_pat.len())..]);
        if !eol_txt.iter().any(u8::is_ascii_whitespace) {
            found = Some((&working[..idx], rest));
            break;
        }
    }

    let (txt, rest) = found.unwrap_or((working, &[]));
    let txt = str::from_utf8(txt).unwrap().trim_matches('\n');

    (MdTree::CodeBlock { txt, lang }, rest)
}

fn parse_heading(buf: &[u8]) -> ParseResult<'_> {
    let level = buf.iter().take_while(|ch| **ch == b'#').count();
    let buf = &buf[level..];

    if level > 6 || (buf.len() > 1 && !buf[0].is_ascii_whitespace()) {
        // Enforce max 6 levels and whitespace following the `##` pattern
        return None;
    }

    let (txt, rest) = parse_to_newline(&buf[1..]);
    let ctx = Context { .. };
    let stream = parse_recursive(txt, ctx);

    Some((MdTree::Heading(level.try_into().unwrap(), stream), rest))
}

/// Bulleted list
fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> {
    let (txt, rest) = get_indented_section(&buf[2..]);
    let ctx = Context { .. };
    let stream = parse_recursive(trim_ascii_start(txt), ctx);
    (MdTree::UnorderedListItem(stream), rest)
}

/// Numbered list
fn parse_ordered_li(buf: &[u8]) -> Parsed<'_> {
    let (num, pos) = ord_list_start(buf).unwrap(); // success tested in caller
    let (txt, rest) = get_indented_section(&buf[pos..]);
    let ctx = Context { .. };
    let stream = parse_recursive(trim_ascii_start(txt), ctx);
    (MdTree::OrderedListItem(num, stream), rest)
}

fn get_indented_section(buf: &[u8]) -> (&[u8], &[u8]) {
    let mut lines = buf.split(|&byte| byte == b'\n');
    let mut end = lines.next().map_or(0, |line| line.len());
    for line in lines {
        if let Some(first) = line.first() {
            if unordered_list_start(line) || !first.is_ascii_whitespace() {
                break;
            }
        }
        end += line.len() + 1;
    }

    (&buf[..end], &buf[end..])
}

fn unordered_list_start(mut buf: &[u8]) -> bool {
    while let [b' ', rest @ ..] = buf {
        buf = rest;
    }
    matches!(buf, [b'*' | b'-', b' ', ..])
}

/// Verify a valid ordered list start (e.g. `1.`) and parse it. Returns the
/// parsed number and offset of character after the dot.
fn ord_list_start(buf: &[u8]) -> Option<(u16, usize)> {
    let pos = buf.iter().take(10).position(|ch| *ch == b'.')?;
    let n = str::from_utf8(&buf[..pos]).ok()?;
    if !buf.get(pos + 1)?.is_ascii_whitespace() {
        return None;
    }
    n.parse::<u16>().ok().map(|v| (v, pos + 2))
}

/// Parse links. `can_be_def` indicates that a link definition is possible (top
/// level, located at the start of a line)
fn parse_any_link(buf: &[u8], can_be_def: bool) -> ParseResult<'_> {
    let (bracketed, rest) = parse_with_end_pat(&buf[1..], LNK_E, true)?;
    if rest.is_empty() {
        return None;
    }

    let disp = str::from_utf8(bracketed).unwrap();
    match (can_be_def, rest[0]) {
        (true, b':') => {
            let (link, tmp) = parse_to_newline(&rest[1..]);
            let link = str::from_utf8(link).unwrap().trim();
            Some((MdTree::LinkDef { id: disp, link }, tmp))
        }
        (_, b'(') => parse_simple_pat(rest, b"(", b")", ParseOpt::TrimNoEsc, |link| MdTree::Link {
            disp,
            link,
        }),
        (_, b'[') => parse_simple_pat(rest, b"[", b"]", ParseOpt::TrimNoEsc, |id| {
            MdTree::RefLink { disp, id: Some(id) }
        }),
        _ => Some((MdTree::RefLink { disp, id: None }, rest)),
    }
}

/// Find and consume an end pattern, return `(match, residual)`
fn parse_with_end_pat<'a>(
    buf: &'a [u8],
    end_sep: &[u8],
    ignore_esc: bool,
) -> Option<(&'a [u8], &'a [u8])> {
    // Find positions that start with the end separator
    for idx in (0..buf.len()).filter(|idx| buf[*idx..].starts_with(end_sep)) {
        if !ignore_esc && idx > 0 && buf[idx - 1] == b'\\' {
            continue;
        }
        return Some((&buf[..idx], &buf[idx + end_sep.len()..]));
    }
    None
}

/// Return `(match, residual)` to end of line. The EOL is returned with the
/// residual.
fn parse_to_newline(buf: &[u8]) -> (&[u8], &[u8]) {
    buf.iter().position(|ch| *ch == b'\n').map_or((buf, &[]), |pos| buf.split_at(pos))
}

/// Take a parsed stream and fix the little things
fn normalize<'a>(MdStream(stream): MdStream<'a>, linkdefs: &mut Vec<MdTree<'a>>) -> MdStream<'a> {
    let mut new_stream = Vec::with_capacity(stream.len());
    let new_defs = stream.iter().filter(|tt| matches!(tt, MdTree::LinkDef { .. }));
    linkdefs.extend(new_defs.cloned());

    // Run plaintext expansions on types that need it, call this function on nested types
    for item in stream {
        match item {
            MdTree::PlainText(txt) => expand_plaintext(txt, &mut new_stream, MdTree::PlainText),
            MdTree::Strong(txt) => expand_plaintext(txt, &mut new_stream, MdTree::Strong),
            MdTree::Emphasis(txt) => expand_plaintext(txt, &mut new_stream, MdTree::Emphasis),
            MdTree::Strikethrough(txt) => {
                expand_plaintext(txt, &mut new_stream, MdTree::Strikethrough);
            }
            MdTree::RefLink { disp, id } => new_stream.push(match_reflink(linkdefs, disp, id)),
            MdTree::OrderedListItem(n, st) => {
                new_stream.push(MdTree::OrderedListItem(n, normalize(st, linkdefs)));
            }
            MdTree::UnorderedListItem(st) => {
                new_stream.push(MdTree::UnorderedListItem(normalize(st, linkdefs)));
            }
            MdTree::Heading(n, st) => new_stream.push(MdTree::Heading(n, normalize(st, linkdefs))),
            _ => new_stream.push(item),
        }
    }

    // Remove non printing types, duplicate paragraph breaks, and breaks at start/end
    new_stream.retain(|x| !matches!(x, MdTree::Comment(_) | MdTree::LinkDef { .. }));
    new_stream.dedup_by(|r, l| matches!((r, l), (MdTree::ParagraphBreak, MdTree::ParagraphBreak)));

    if new_stream.first().is_some_and(is_break_ty) {
        new_stream.remove(0);
    }
    if new_stream.last().is_some_and(is_break_ty) {
        new_stream.pop();
    }

    // Remove paragraph breaks that shouldn't be there. w[1] is what will be
    // removed in these cases. Note that these are the items to keep, not delete
    // (for `retain`)
    let to_keep: Vec<bool> = new_stream
        .windows(3)
        .map(|w| {
            !((matches!(&w[1], MdTree::ParagraphBreak)
                && matches!(should_break(&w[0], &w[2]), BreakRule::Always(1) | BreakRule::Never))
                || (matches!(&w[1], MdTree::PlainText(txt) if txt.trim().is_empty())
                    && matches!(
                        should_break(&w[0], &w[2]),
                        BreakRule::Always(_) | BreakRule::Never
                    )))
        })
        .collect();
    let mut iter = iter::once(true).chain(to_keep).chain(iter::once(true));
    new_stream.retain(|_| iter.next().unwrap());

    // Insert line or paragraph breaks where there should be some
    let mut insertions = 0;
    let to_insert: Vec<(usize, MdTree<'_>)> = new_stream
        .windows(2)
        .enumerate()
        .filter_map(|(idx, w)| match should_break(&w[0], &w[1]) {
            BreakRule::Always(1) => Some((idx, MdTree::LineBreak)),
            BreakRule::Always(2) => Some((idx, MdTree::ParagraphBreak)),
            _ => None,
        })
        .map(|(idx, tt)| {
            insertions += 1;
            (idx + insertions, tt)
        })
        .collect();
    to_insert.into_iter().for_each(|(idx, tt)| new_stream.insert(idx, tt));

    MdStream(new_stream)
}

/// Whether two types should or shouldn't have a paragraph break between them
#[derive(Clone, Copy, Debug, PartialEq)]
enum BreakRule {
    Always(u8),
    Never,
    Optional,
}

/// Blocks that automatically handle their own text wrapping
fn should_break(left: &MdTree<'_>, right: &MdTree<'_>) -> BreakRule {
    use MdTree::*;

    match (left, right) {
        // Separate these types with a single line
        (HorizontalRule, _)
        | (_, HorizontalRule)
        | (OrderedListItem(_, _), OrderedListItem(_, _))
        | (UnorderedListItem(_), UnorderedListItem(_)) => BreakRule::Always(1),
        // Condensed types shouldn't have an extra break on either side
        (Comment(_) | ParagraphBreak | Heading(_, _), _) | (_, Comment(_) | ParagraphBreak) => {
            BreakRule::Never
        }
        // Block types should always be separated by full breaks
        (CodeBlock { .. } | OrderedListItem(_, _) | UnorderedListItem(_), _)
        | (_, CodeBlock { .. } | Heading(_, _) | OrderedListItem(_, _) | UnorderedListItem(_)) => {
            BreakRule::Always(2)
        }
        // Text types may or may not be separated by a break
        (
            CodeInline(_)
            | Strong(_)
            | Emphasis(_)
            | Strikethrough(_)
            | PlainText(_)
            | Link { .. }
            | RefLink { .. }
            | LinkDef { .. },
            CodeInline(_)
            | Strong(_)
            | Emphasis(_)
            | Strikethrough(_)
            | PlainText(_)
            | Link { .. }
            | RefLink { .. }
            | LinkDef { .. },
        ) => BreakRule::Optional,
        (LineBreak, _) | (_, LineBreak) => {
            unreachable!("should have been removed during deduplication")
        }
    }
}

/// Types that indicate some form of break
fn is_break_ty(val: &MdTree<'_>) -> bool {
    matches!(val, MdTree::ParagraphBreak | MdTree::LineBreak)
        // >1 break between paragraphs acts as a break
        || matches!(val, MdTree::PlainText(txt) if txt.trim().is_empty())
}

/// Perform transformations to text. This splits paragraphs, replaces patterns,
/// and corrects newlines.
///
/// To avoid allocating strings (and using a different heavier tt type), our
/// replace method means split into three and append each. For this reason, any
/// viewer should treat consecutive `PlainText` types as belonging to the same
/// paragraph.
fn expand_plaintext<'a>(
    txt: &'a str,
    stream: &mut Vec<MdTree<'a>>,
    mut f: fn(&'a str) -> MdTree<'a>,
) {
    if txt.is_empty() {
        return;
    } else if txt == "\n" {
        if let Some(tt) = stream.last() {
            let tmp = MdTree::PlainText(" ");
            if should_break(tt, &tmp) == BreakRule::Optional {
                stream.push(tmp);
            }
        }
        return;
    }
    let mut queue1 = Vec::new();
    let mut queue2 = Vec::new();
    let stream_start_len = stream.len();
    for paragraph in txt.split("\n\n") {
        if paragraph.is_empty() {
            stream.push(MdTree::ParagraphBreak);
            continue;
        }
        let paragraph = trim_extra_ws(paragraph);

        queue1.clear();
        queue1.push(paragraph);

        for (from, to) in REPLACEMENTS {
            queue2.clear();
            for item in &queue1 {
                for s in item.split(from) {
                    queue2.extend(&[s, to]);
                }
                if queue2.len() > 1 {
                    let _ = queue2.pop(); // remove last unnecessary intersperse
                }
            }
            mem::swap(&mut queue1, &mut queue2);
        }

        // Make sure we don't double whitespace
        queue1.retain(|s| !s.is_empty());
        for idx in 0..queue1.len() {
            queue1[idx] = trim_extra_ws(queue1[idx]);
            if idx < queue1.len() - 1
                && queue1[idx].ends_with(char::is_whitespace)
                && queue1[idx + 1].starts_with(char::is_whitespace)
            {
                queue1[idx] = queue1[idx].trim_end();
            }
        }
        stream.extend(queue1.iter().copied().filter(|txt| !txt.is_empty()).map(&mut f));
        stream.push(MdTree::ParagraphBreak);
    }

    if stream.len() - stream_start_len > 1 {
        let _ = stream.pop(); // remove last unnecessary intersperse
    }
}

/// Turn reflinks (links with reference IDs) into normal standalone links using
/// listed link definitions
fn match_reflink<'a>(linkdefs: &[MdTree<'a>], disp: &'a str, match_id: Option<&str>) -> MdTree<'a> {
    let to_match = match_id.unwrap_or(disp); // Match with the display name if there isn't an id
    for def in linkdefs {
        if let MdTree::LinkDef { id, link } = def {
            if *id == to_match {
                return MdTree::Link { disp, link };
            }
        }
    }
    MdTree::Link { disp, link: "" } // link not found
}

/// If there is more than one whitespace char at start or end, trim the extras
fn trim_extra_ws(mut txt: &str) -> &str {
    let start_ws =
        txt.bytes().position(|ch| !ch.is_ascii_whitespace()).unwrap_or(txt.len()).saturating_sub(1);
    txt = &txt[start_ws..];
    let end_ws = txt
        .bytes()
        .rev()
        .position(|ch| !ch.is_ascii_whitespace())
        .unwrap_or(txt.len())
        .saturating_sub(1);
    &txt[..txt.len() - end_ws]
}

/// If there is more than one whitespace char at start, trim the extras
fn trim_ascii_start(buf: &[u8]) -> &[u8] {
    let count = buf.iter().take_while(|ch| ch.is_ascii_whitespace()).count();
    &buf[count..]
}

#[cfg(test)]
#[path = "tests/parse.rs"]
mod tests;
