import type { TailwindSize } from "./types"
import "hono/jsx"
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
import { Grid } from "./grid"
import { Section } from "./section"
import { H2 } from "./text"
import { RedBox, GreenBox, BlueBox } from "./box"
import { CodeExamples } from "./code"
import { cn } from "./cn"

export const VStack: FC<VStackProps> = (props) => {
  return (
    <Stack
      direction="col"
      mainAxis={props.v}
      crossAxis={props.h}
      wrap={props.wrap}
      gap={props.gap}
      maxWidth={props.maxWidth}
      gridSizes={props.rows}
      componentName="VStack"
      class={props.class}
      style={props.style}
    >
      {props.children}
    </Stack>
  )
}

export const HStack: FC<HStackProps> = (props) => {
  return (
    <Stack
      direction="row"
      mainAxis={props.h}
      crossAxis={props.v}
      wrap={props.wrap}
      gap={props.gap}
      maxWidth={props.maxWidth}
      gridSizes={props.cols}
      componentName="HStack"
      class={props.class}
      style={props.style}
    >
      {props.children}
    </Stack>
  )
}

const Stack: FC<StackProps> = (props) => {
  const gapPx = props.gap ? props.gap * 4 : 0

  // Use CSS Grid when gridSizes (cols/rows) is provided
  if (props.gridSizes) {
    const gridTemplate = props.gridSizes.map(size => `${size}fr`).join(" ")

    const gridStyles: JSX.CSSProperties = {
      display: "grid",
      gap: `${gapPx}px`,
      maxWidth: props.maxWidth,
    }

    if (props.direction === "row") {
      gridStyles.gridTemplateColumns = gridTemplate
    } else {
      gridStyles.gridTemplateRows = gridTemplate
    }

    const combinedStyles = {
      ...gridStyles,
      ...props.style,
    }

    return <div class={cn(props.componentName, props.class)} style={combinedStyles}>{props.children}</div>
  }

  // Default flexbox behavior
  const baseStyles: JSX.CSSProperties = {
    display: "flex",
    flexDirection: props.direction === "row" ? "row" : "column",
    flexWrap: props.wrap ? "wrap" : "nowrap",
    gap: `${gapPx}px`,
    maxWidth: props.maxWidth,
  }

  if (props.mainAxis) {
    baseStyles.justifyContent = getJustifyContent(props.mainAxis)
  }

  if (props.crossAxis) {
    baseStyles.alignItems = getAlignItems(props.crossAxis)
  }

  const combinedStyles = {
    ...baseStyles,
    ...props.style,
  }

  return <div class={cn(props.componentName, props.class)} style={combinedStyles}>{props.children}</div>
}

export const Test = () => {
  const mainAxisOpts: MainAxisOpts[] = ["start", "center", "end", "between", "around", "evenly"]
  const crossAxisOpts: CrossAxisOpts[] = ["start", "center", "end", "stretch", "baseline"]

  return (
    <Section gap={8} style={{ padding: "16px" }}>
      {/* API Usage Examples */}
      <CodeExamples
        examples={[
          '<VStack>...</VStack>',
          '<VStack gap={4} v="center">...</VStack>',
          '<HStack>...</HStack>',
          '<HStack gap={6} h="between" v="center">...</HStack>',
          '<HStack cols={[7, 3]} maxWidth="1200px" gap={4}>...</HStack>',
          '<VStack rows={[2, 1]} maxWidth="800px">...</VStack>',
        ]}
      />

      {/* HStack layout matrix */}
      <VStack gap={2}>
        <H2>HStack Layout</H2>
        <div style={{ overflowX: "auto" }}>
          <Grid cols={7} gap={1} style={{ gridTemplateColumns: "auto repeat(6, 1fr)" }}>
            {/* Header row: blank + h labels */}
            <div></div>
            {mainAxisOpts.map((h) => (
              <div key={h} style={{ fontSize: "14px", fontWeight: "500", textAlign: "center" }}>
                h: {h}
              </div>
            ))}

            {/* Each row: v label + HStack cells */}
            {crossAxisOpts.map((v) => [
              <div key={v} style={{ fontSize: "14px", fontWeight: "500" }}>
                v: {v}
              </div>,
              ...mainAxisOpts.map((h) => (
                <HStack
                  key={`${h}-${v}`}
                  h={h}
                  v={v}
                  style={{ backgroundColor: "#f3f4f6", padding: "8px", height: "96px", border: "1px solid #9ca3af" }}
                >
                  <RedBox>Aa</RedBox>
                  <GreenBox>Aa</GreenBox>
                  <BlueBox>Aa</BlueBox>
                </HStack>
              )),
            ])}
          </Grid>
        </div>
      </VStack>

      {/* VStack layout matrix */}
      <VStack gap={2}>
        <H2>VStack Layout</H2>
        <div style={{ overflowX: "auto" }}>
          <Grid cols={6} gap={1} style={{ gridTemplateColumns: "auto repeat(5, 1fr)" }}>
            {/* Header row: blank + h labels */}
            <div></div>
            {crossAxisOpts.map((h) => (
              <div key={h} style={{ fontSize: "14px", fontWeight: "500", textAlign: "center" }}>
                h: {h}
              </div>
            ))}

            {/* Each row: v label + VStack cells */}
            {mainAxisOpts.map((v) => [
              <div key={v} style={{ fontSize: "14px", fontWeight: "500" }}>
                v: {v}
              </div>,
              ...crossAxisOpts.map((h) => (
                <VStack
                  key={`${h}-${v}`}
                  v={v}
                  h={h}
                  style={{ backgroundColor: "#f3f4f6", padding: "8px", height: "168px", border: "1px solid #9ca3af" }}
                >
                  <RedBox>Aa</RedBox>
                  <GreenBox>Aa</GreenBox>
                  <BlueBox>Aa</BlueBox>
                </VStack>
              )),
            ])}
          </Grid>
        </div>
      </VStack>

      {/* Custom column sizing */}
      <VStack gap={4}>
        <H2>HStack with Custom Column Sizing</H2>
        <VStack gap={4}>
          <div>
            <div style={{ fontSize: "14px", fontWeight: "500", marginBottom: "8px" }}>
              cols=[7, 3] (70%/30% split)
            </div>
            <HStack cols={[7, 3]} gap={4} style={{ backgroundColor: "#f3f4f6", padding: "16px" }}>
              <div style={{ backgroundColor: "#bfdbfe", padding: "16px", textAlign: "center" }}>
                70% width
              </div>
              <div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>
                30% width
              </div>
            </HStack>
          </div>

          <div>
            <div style={{ fontSize: "14px", fontWeight: "500", marginBottom: "8px" }}>
              cols=[2, 1] (66%/33% split)
            </div>
            <HStack cols={[2, 1]} gap={4} style={{ backgroundColor: "#f3f4f6", padding: "16px" }}>
              <div style={{ backgroundColor: "#bbf7d0", padding: "16px", textAlign: "center" }}>
                2/3 width
              </div>
              <div style={{ backgroundColor: "#fef08a", padding: "16px", textAlign: "center" }}>
                1/3 width
              </div>
            </HStack>
          </div>

          <div>
            <div style={{ fontSize: "14px", fontWeight: "500", marginBottom: "8px" }}>
              cols=[1, 2, 1] (25%/50%/25% split)
            </div>
            <HStack cols={[1, 2, 1]} gap={4} style={{ backgroundColor: "#f3f4f6", padding: "16px" }}>
              <div style={{ backgroundColor: "#e9d5ff", padding: "16px", textAlign: "center" }}>
                25%
              </div>
              <div style={{ backgroundColor: "#bfdbfe", padding: "16px", textAlign: "center" }}>
                50%
              </div>
              <div style={{ backgroundColor: "#fbcfe8", padding: "16px", textAlign: "center" }}>
                25%
              </div>
            </HStack>
          </div>

          <div>
            <div style={{ fontSize: "14px", fontWeight: "500", marginBottom: "8px" }}>
              With maxWidth="600px"
            </div>
            <HStack cols={[7, 3]} maxWidth="600px" gap={4} style={{ backgroundColor: "#f3f4f6", padding: "16px" }}>
              <div style={{ backgroundColor: "#bfdbfe", padding: "16px", textAlign: "center" }}>
                70% of max 600px
              </div>
              <div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>
                30% of max 600px
              </div>
            </HStack>
          </div>
        </VStack>
      </VStack>

      {/* Custom row sizing */}
      <VStack gap={4}>
        <H2>VStack with Custom Row Sizing</H2>
        <VStack gap={4}>
          <div>
            <div style={{ fontSize: "14px", fontWeight: "500", marginBottom: "8px" }}>
              rows=[2, 1] (2/3 and 1/3 height)
            </div>
            <VStack
              rows={[2, 1]}
              gap={4}
              style={{ backgroundColor: "#f3f4f6", padding: "16px", height: "300px" }}
            >
              <div style={{ backgroundColor: "#bfdbfe", padding: "16px", textAlign: "center" }}>
                2/3 height
              </div>
              <div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>
                1/3 height
              </div>
            </VStack>
          </div>
        </VStack>
      </VStack>
    </Section>
  )
}

type StackDirection = "row" | "col"

type StackProps = {
  direction: StackDirection
  mainAxis?: string
  crossAxis?: string
  wrap?: boolean
  gap?: TailwindSize
  maxWidth?: string
  gridSizes?: number[] // cols for row, rows for col
  componentName?: string // for data-howl attribute
  class?: string
  style?: JSX.CSSProperties
  children?: any
}

type MainAxisOpts = "start" | "center" | "end" | "between" | "around" | "evenly"
type CrossAxisOpts = "start" | "center" | "end" | "stretch" | "baseline"

type CommonStackProps = PropsWithChildren & {
  wrap?: boolean
  gap?: TailwindSize
  maxWidth?: string
  class?: string
  style?: JSX.CSSProperties
}

type VStackProps = CommonStackProps & {
  v?: MainAxisOpts // main axis for vertical stack
  h?: CrossAxisOpts // cross axis for vertical stack
  rows?: number[] // custom row sizing (e.g., [7, 3] for 70%/30%)
}

type HStackProps = CommonStackProps & {
  h?: MainAxisOpts // main axis for horizontal stack
  v?: CrossAxisOpts // cross axis for horizontal stack
  cols?: number[] // custom column sizing (e.g., [7, 3] for 70%/30%)
}

function getJustifyContent(axis: string): string {
  const map: Record<string, string> = {
    start: "flex-start",
    center: "center",
    end: "flex-end",
    between: "space-between",
    around: "space-around",
    evenly: "space-evenly",
  }
  return map[axis] || "flex-start"
}

function getAlignItems(axis: string): string {
  const map: Record<string, string> = {
    start: "flex-start",
    center: "center",
    end: "flex-end",
    stretch: "stretch",
    baseline: "baseline",
  }
  return map[axis] || "stretch"
}
