///|
/// SplitPane - Split layout component for dividing screen into two sections

///|
/// Split direction
pub(all) enum SplitDirection {
  Horizontal // Top and bottom
  Vertical // Left and right
}

///|
/// Split size specification
pub(all) enum SplitSize {
  Fixed(Double) // Fixed size in characters/rows
  Percent(Double) // Percentage of total (0.0 to 1.0)
  Flex(Double) // Flex grow factor
}

///|
/// Calculate actual sizes for split pane
/// Returns (first_size, second_size)
pub fn calc_split_sizes(
  total : Int,
  first : SplitSize,
  second : SplitSize,
  divider_size? : Int = 1,
) -> (Int, Int) {
  let available = total - divider_size
  if available <= 0 {
    return (0, 0)
  }
  let avail = available.to_double()
  match (first, second) {
    // Both fixed
    (SplitSize::Fixed(f1), SplitSize::Fixed(f2)) => {
      let s1 = f1.to_int()
      let s2 = f2.to_int()
      // Clamp to available space
      if s1 + s2 <= available {
        (s1, s2)
      } else {
        // Proportionally reduce
        let ratio = avail / (f1 + f2)
        ((f1 * ratio).to_int(), (f2 * ratio).to_int())
      }
    }
    // First fixed, second fills remaining
    (SplitSize::Fixed(f1), SplitSize::Flex(_)) => {
      let s1 = f1.to_int().min(available)
      (s1, available - s1)
    }
    (SplitSize::Fixed(f1), SplitSize::Percent(p2)) => {
      let s1 = f1.to_int().min(available)
      let s2 = (avail * p2).to_int().min(available - s1)
      (s1, s2)
    }
    // Second fixed, first fills remaining
    (SplitSize::Flex(_), SplitSize::Fixed(f2)) => {
      let s2 = f2.to_int().min(available)
      (available - s2, s2)
    }
    (SplitSize::Percent(p1), SplitSize::Fixed(f2)) => {
      let s2 = f2.to_int().min(available)
      let s1 = (avail * p1).to_int().min(available - s2)
      (s1, s2)
    }
    // Both percent
    (SplitSize::Percent(p1), SplitSize::Percent(p2)) => {
      let total_pct = p1 + p2
      if total_pct > 0.0 {
        let s1 = (avail * p1 / total_pct).to_int()
        (s1, available - s1)
      } else {
        (available / 2, available - available / 2)
      }
    }
    // Both flex
    (SplitSize::Flex(g1), SplitSize::Flex(g2)) => {
      let total_grow = g1 + g2
      if total_grow > 0.0 {
        let s1 = (avail * g1 / total_grow).to_int()
        (s1, available - s1)
      } else {
        (available / 2, available - available / 2)
      }
    }
    // Percent and flex (treat flex as remaining)
    (SplitSize::Percent(p1), SplitSize::Flex(_)) => {
      let s1 = (avail * p1).to_int().min(available)
      (s1, available - s1)
    }
    (SplitSize::Flex(_), SplitSize::Percent(p2)) => {
      let s2 = (avail * p2).to_int().min(available)
      (available - s2, s2)
    }
  }
}

///|
/// Horizontal split pane (top and bottom)
pub fn hsplit(
  top : Array[@core.Component],
  bottom : Array[@core.Component],
  total_height : Int,
  top_size : SplitSize,
  bottom_size : SplitSize,
  divider? : @core.Component? = None,
  divider_size? : Int = 1,
) -> @core.Component {
  let (top_h, bottom_h) = calc_split_sizes(
    total_height,
    top_size,
    bottom_size,
    divider_size~,
  )
  let divider_component = match divider {
    Some(d) => d
    None => hdivider()
  }
  @core.box(
    [
      @core.box(top, height=@types.Dimension::Length(top_h.to_double())),
      divider_component,
      @core.box(bottom, height=@types.Dimension::Length(bottom_h.to_double())),
    ],
    flex_direction=@types.FlexDirection::Column,
    height=@types.Dimension::Length(total_height.to_double()),
  )
}

///|
/// Vertical split pane (left and right)
pub fn vsplit(
  left : Array[@core.Component],
  right : Array[@core.Component],
  total_width : Int,
  left_size : SplitSize,
  right_size : SplitSize,
  divider? : @core.Component? = None,
  divider_size? : Int = 1,
) -> @core.Component {
  let (left_w, right_w) = calc_split_sizes(
    total_width,
    left_size,
    right_size,
    divider_size~,
  )
  let divider_component = match divider {
    Some(d) => d
    None => vdivider()
  }
  @core.box(
    [
      @core.box(left, width=@types.Dimension::Length(left_w.to_double())),
      divider_component,
      @core.box(right, width=@types.Dimension::Length(right_w.to_double())),
    ],
    flex_direction=@types.FlexDirection::Row,
    width=@types.Dimension::Length(total_width.to_double()),
  )
}

///|
/// Simple horizontal split with fixed bottom height
pub fn hsplit_fixed_bottom(
  top : Array[@core.Component],
  bottom : Array[@core.Component],
  total_height : Int,
  bottom_height : Int,
  divider? : @core.Component? = None,
) -> @core.Component {
  hsplit(
    top,
    bottom,
    total_height,
    SplitSize::Flex(1.0),
    SplitSize::Fixed(bottom_height.to_double()),
    divider~,
  )
}

///|
/// Simple horizontal split with fixed top height
pub fn hsplit_fixed_top(
  top : Array[@core.Component],
  bottom : Array[@core.Component],
  total_height : Int,
  top_height : Int,
  divider? : @core.Component? = None,
) -> @core.Component {
  hsplit(
    top,
    bottom,
    total_height,
    SplitSize::Fixed(top_height.to_double()),
    SplitSize::Flex(1.0),
    divider~,
  )
}

///|
/// Simple vertical split with fixed left width
pub fn vsplit_fixed_left(
  left : Array[@core.Component],
  right : Array[@core.Component],
  total_width : Int,
  left_width : Int,
  divider? : @core.Component? = None,
) -> @core.Component {
  vsplit(
    left,
    right,
    total_width,
    SplitSize::Fixed(left_width.to_double()),
    SplitSize::Flex(1.0),
    divider~,
  )
}

///|
/// Simple vertical split with fixed right width
pub fn vsplit_fixed_right(
  left : Array[@core.Component],
  right : Array[@core.Component],
  total_width : Int,
  right_width : Int,
  divider? : @core.Component? = None,
) -> @core.Component {
  vsplit(
    left,
    right,
    total_width,
    SplitSize::Flex(1.0),
    SplitSize::Fixed(right_width.to_double()),
    divider~,
  )
}

// ============================================
// Window Splitter - Interactive resizable splitter
// ============================================

///|
/// Splitter state
pub(all) struct SplitterState {
  position : Int // percentage 0-100
  collapsed : Bool
  prev_position : Int // position before collapse
  focused : Bool
}

///|
/// Create initial splitter state
pub fn SplitterState::new(
  initial_position? : Int = 50,
  collapsed? : Bool = false,
) -> SplitterState {
  {
    position: initial_position,
    collapsed,
    prev_position: initial_position,
    focused: false,
  }
}

///|
/// Splitter orientation
pub(all) enum SplitterOrientation {
  Horizontal // Left | Right (vertical divider line)
  Vertical // Top | Bottom (horizontal divider line)
}

///|
/// Create a window splitter with draggable divider
pub fn window_splitter(
  primary : @core.Component,
  secondary : @core.Component,
  state : SplitterState,
  orientation? : SplitterOrientation = SplitterOrientation::Horizontal,
  id? : String = "",
  // Constraints
  min? : Int = 10,
  max? : Int = 90,
  // Style
  divider_fg? : @core.Color = @core.Color::white(),
  divider_bg? : @core.Color = @core.Color::rgb(60, 60, 80),
  focused_fg? : @core.Color = @core.Color::cyan(),
  focused_bg? : @core.Color = @core.Color::rgb(40, 80, 100),
  // Size (total container size)
  total_size? : Int = 80,
  divider_width? : Double = 1.0,
) -> @core.Component {
  // Calculate actual position (handle collapsed state)
  let actual_position = if state.collapsed { 0 } else { state.position }

  // Determine divider appearance
  let (div_fg, div_bg) = if state.focused {
    (focused_fg, focused_bg)
  } else {
    (divider_fg, divider_bg)
  }

  // Build divider with grab handle
  let divider_component = match orientation {
    SplitterOrientation::Horizontal => {
      // Vertical line divider with grip
      let grip = if state.focused { "┃" } else { "│" }
      let handle = column(
        [text(grip, fg=div_fg)],
        id=id + "-divider",
        width=@types.Dimension::Length(divider_width),
        height=@types.Dimension::Percent(1.0),
        bg=div_bg,
        justify=@types.Alignment::Center,
        align=@types.Alignment::Center,
      )
      handle
    }
    SplitterOrientation::Vertical => {
      // Horizontal line divider with grip
      let grip = if state.focused { "━" } else { "─" }
      let handle = row(
        [text(grip.repeat(3), fg=div_fg)],
        id=id + "-divider",
        height=@types.Dimension::Length(divider_width),
        width=@types.Dimension::Percent(1.0),
        bg=div_bg,
        justify=@types.Alignment::Center,
        align=@types.Alignment::Center,
      )
      handle
    }
  }

  // Calculate sizes based on position
  let actual_divider_width = divider_width
  let available = total_size.to_double() - actual_divider_width
  let primary_size = if state.collapsed {
    0.0
  } else {
    actual_position.clamp(min~, max~).to_double() / 100.0 * available
  }
  let secondary_size = available - primary_size
  match orientation {
    SplitterOrientation::Horizontal =>
      // Left | Right
      row(
        [
          column(
            [primary],
            width=@types.Dimension::Length(primary_size),
            height=@types.Dimension::Percent(1.0),
          ),
          divider_component,
          column(
            [secondary],
            width=@types.Dimension::Length(secondary_size),
            height=@types.Dimension::Percent(1.0),
          ),
        ],
        id~,
        width=@types.Dimension::Length(total_size.to_double()),
      )
    SplitterOrientation::Vertical =>
      // Top | Bottom
      column(
        [
          row(
            [primary],
            height=@types.Dimension::Length(primary_size),
            width=@types.Dimension::Percent(1.0),
          ),
          divider_component,
          row(
            [secondary],
            height=@types.Dimension::Length(secondary_size),
            width=@types.Dimension::Percent(1.0),
          ),
        ],
        id~,
        height=@types.Dimension::Length(total_size.to_double()),
      )
  }
}

///|
/// Interactive divider handle (standalone)
pub fn splitter_handle(
  orientation : SplitterOrientation,
  focused? : Bool = false,
  id? : String = "",
  fg? : @core.Color = @core.Color::white(),
  bg? : @core.Color = @core.Color::rgb(60, 60, 80),
  focused_fg? : @core.Color = @core.Color::cyan(),
  focused_bg? : @core.Color = @core.Color::rgb(40, 80, 100),
) -> @core.Component {
  let (actual_fg, actual_bg) = if focused {
    (focused_fg, focused_bg)
  } else {
    (fg, bg)
  }
  match orientation {
    SplitterOrientation::Horizontal => {
      let grip = if focused { "┃" } else { "│" }
      column(
        [text(grip, fg=actual_fg)],
        id~,
        width=@types.Dimension::Length(1.0),
        bg=actual_bg,
        justify=@types.Alignment::Center,
      )
    }
    SplitterOrientation::Vertical => {
      let grip = if focused { "━━━" } else { "───" }
      row(
        [text(grip, fg=actual_fg)],
        id~,
        height=@types.Dimension::Length(1.0),
        bg=actual_bg,
        justify=@types.Alignment::Center,
      )
    }
  }
}

///|
/// Resizable pane with visible position indicator
pub fn resizable_pane(
  primary : @core.Component,
  secondary : @core.Component,
  position : Int, // percentage 0-100
  orientation? : SplitterOrientation = SplitterOrientation::Horizontal,
  id? : String = "",
  focused? : Bool = false,
  show_position? : Bool = false,
  total_size? : Int = 80,
) -> @core.Component {
  let state = SplitterState::{
    position,
    collapsed: false,
    prev_position: position,
    focused,
  }
  let splitter = window_splitter(
    primary,
    secondary,
    state,
    orientation~,
    id~,
    total_size~,
  )
  if show_position {
    let indicator = text(
      " " + position.to_string() + "% ",
      fg=@core.Color::rgb(150, 150, 150),
    )
    match orientation {
      SplitterOrientation::Horizontal =>
        column([indicator, splitter], id=id + "-container")
      SplitterOrientation::Vertical =>
        row([splitter, indicator], id=id + "-container")
    }
  } else {
    splitter
  }
}