/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.compose

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import org.mozilla.fenix.theme.FirefoxTheme

/**
 * Special caption text for a tab layout shown on one line.
 *
 * This will combine [firstText] with a interdot and then [secondText] ensuring that the second text
 * (which is assumed to be smaller) always fills as much space as needed with the [firstText] automatically
 * being resized to be smaller with an added ellipsis characters if needed.
 *
 * Possible results:
 * ```
 * - when both texts would fit the screen
 * ------------------------------------------
 * |firstText · secondText                  |
 * ------------------------------------------
 *
 * - when both text do not fit, second is shown in entirety, first is ellipsised.
 * ------------------------------------------
 * |longerFirstTextOrSmallSc... · secondText|
 * ------------------------------------------
 * ```
 *
 * @param firstText Text shown at the start of the row.
 * @param secondText Text shown at the end of the row.
 */
@Composable
fun TabSubtitleWithInterdot(
    firstText: String,
    secondText: String,
) {
    val currentLayoutDirection = LocalLayoutDirection.current

    Layout(
        content = {
            Text(
                text = firstText,
                color = FirefoxTheme.colors.textSecondary,
                fontSize = 12.sp,
                overflow = TextOverflow.Ellipsis,
                maxLines = 1,
            )
            Text(
                text = " \u00b7 ",
                color = FirefoxTheme.colors.textSecondary,
                fontSize = 12.sp,
                overflow = TextOverflow.Ellipsis,
                maxLines = 1,
            )
            Text(
                text = secondText,
                color = FirefoxTheme.colors.textSecondary,
                fontSize = 12.sp,
                overflow = TextOverflow.Ellipsis,
                maxLines = 1,
            )
        },
    ) { items, constraints ->

        // We need to measure from the end to start to ensure the secondItem will always be on screen
        // and depending on secondItem's width and interdot's width the firstItem is automatically resized.
        val secondItem = items[2].measure(constraints)
        val interdot = items[1].measure(
            constraints.copy(maxWidth = constraints.maxWidth - secondItem.width),
        )
        val firstItem = items[0].measure(
            constraints.copy(maxWidth = constraints.maxWidth - secondItem.width - interdot.width),
        )

        layout(constraints.maxWidth, constraints.maxHeight) {
            val itemsPositions = IntArray(items.size)
            with(Arrangement.Start) {
                arrange(
                    constraints.maxWidth,
                    intArrayOf(firstItem.width, interdot.width, secondItem.width),
                    currentLayoutDirection,
                    itemsPositions,
                )
            }

            val placementHeight = constraints.maxHeight - firstItem.height
            listOf(firstItem, interdot, secondItem).forEachIndexed { index, item ->
                item.place(itemsPositions[index], placementHeight)
            }
        }
    }
}

@Composable
@Preview
private fun TabSubtitleWithInterdotPreview() {
    FirefoxTheme {
        Box(Modifier.background(FirefoxTheme.colors.layer2)) {
            TabSubtitleWithInterdot(
                firstText = "firstText",
                secondText = "secondText",
            )
        }
    }
}
