@page "/components/otp-input"

<PageTitle>OTP Input — Lumeo</PageTitle>

<PageHeader Title="OTP Input" Description="A one-time password input with auto-focus and auto-advance between fields." />

<div class="mt-10 space-y-3">
    <Heading Id="when-to-use" Level="2" Class="scroll-mt-20">When to Use</Heading>
    <ul class="list-disc list-inside space-y-1 text-muted-foreground text-sm">
        <li>Verification code entry for email or SMS confirmation</li>
        <li>Two-factor authentication (2FA) flows</li>
        <li>PIN entry screens for secure access</li>
        <li>Any scenario requiring a fixed-length numeric or alphanumeric code</li>
    </ul>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Default (6 digits)" Code="@_defaultCode">
        <Stack Gap="4" Align="center">
            <OtpInput @bind-Value="_otpValue" OnComplete="HandleComplete" />
            @if (!string.IsNullOrEmpty(_otpValue))
            {
                <Lumeo.Text Size="sm" Color="muted">Value: @_otpValue</Lumeo.Text>
            }
            @if (_completed)
            {
                <Badge Variant="Badge.BadgeVariant.Success">Code entered</Badge>
            }
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="2FA Verification" Code="@_tfaCode">
        <Container MaxWidth="sm" Center="false" Padding="">
            <Card>
                <CardHeader>
                    <Heading Level="3" Class="leading-none tracking-tight">Two-factor authentication</Heading>
                    <Lumeo.Text Size="sm" Color="muted">Enter the 6-digit code from your authenticator app.</Lumeo.Text>
                </CardHeader>
                <CardContent>
                    <Stack Gap="4" Align="center">
                        <OtpInput @bind-Value="_tfaValue" OnComplete="HandleTfa" />
                        @if (_tfaVerified)
                        {
                            <Badge Variant="Badge.BadgeVariant.Success">
                                <DynamicIcon Name="Check" Class="h-3 w-3 mr-1" /> Verified
                            </Badge>
                        }
                    </Stack>
                </CardContent>
                <CardFooter>
                    <Button Class="w-full" Disabled="@(_tfaValue.Length < 6)">Verify</Button>
                </CardFooter>
            </Card>
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="4 Digit Code" Code="@_fourDigitCode">
        <Stack Gap="4" Align="center">
            <OtpInput @bind-Value="_shortOtp" Length="4" />
            @if (!string.IsNullOrEmpty(_shortOtp))
            {
                <Lumeo.Text Size="sm" Color="muted">Value: @_shortOtp</Lumeo.Text>
            }
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Variable Length" Description="Dynamically change the number of OTP digits." Code="@_lengthCode">
        <Stack Gap="3">
            <Flex Align="center" Gap="3" Wrap="true">
                <Lumeo.Text Size="sm" Weight="medium">Length:</Lumeo.Text>
                <Segmented @bind-Value="_otpLength">
                    <SegmentedItem Value="4">4 digits</SegmentedItem>
                    <SegmentedItem Value="6">6 digits</SegmentedItem>
                    <SegmentedItem Value="8">8 digits</SegmentedItem>
                </Segmented>
            </Flex>
            <Stack Gap="2" Align="center">
                <OtpInput Length="@(int.Parse(_otpLength))" Value="@_otpLengthValue" ValueChanged="@(v => _otpLengthValue = v)" />
                @if (!string.IsNullOrEmpty(_otpLengthValue))
                {
                    <Lumeo.Text Size="sm" Color="muted">Value: @_otpLengthValue</Lumeo.Text>
                }
            </Stack>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Paste Support" Code="@_pasteCode">
        <Stack Gap="3">
            <Lumeo.Text Size="sm" Color="muted">Try pasting a code like "123456" into any field</Lumeo.Text>
            <OtpInput Length="6" @bind-Value="_pasteOtp" OnComplete="@HandlePasteComplete" />
            @if (!string.IsNullOrEmpty(_pasteResult))
            {
                <Lumeo.Text Size="sm" Class="text-green-600">Pasted code: @_pasteResult</Lumeo.Text>
            }
        </Stack>
    </ComponentDemo>
</Stack>

<div class="mt-16">
    <Heading Id="api-reference" Level="2" Class="scroll-mt-20">API Reference</Heading>

    <Heading Id="otpinput" Level="3" Class="mt-8 scroll-mt-20">OtpInput</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">Length</TableCell><TableCell Class="font-mono text-xs">int</TableCell><TableCell Class="font-mono text-xs">6</TableCell><TableCell>Number of input fields.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Value</TableCell><TableCell Class="font-mono text-xs">string</TableCell><TableCell Class="font-mono text-xs">""</TableCell><TableCell>Current OTP value. Use with @@bind-Value for two-way binding.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">ValueChanged</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;string&gt;</TableCell><TableCell Class="font-mono text-xs">—</TableCell><TableCell>Callback invoked when the value changes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">OnComplete</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;string&gt;</TableCell><TableCell Class="font-mono text-xs">—</TableCell><TableCell>Callback invoked when all fields are filled.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">InputMode</TableCell><TableCell Class="font-mono text-xs">string</TableCell><TableCell Class="font-mono text-xs">"Numeric"</TableCell><TableCell>Input validation mode. Values: "Numeric", "Alphanumeric", "Password".</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Disabled</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Disables all input fields.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Masked</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Hides input characters (password-style).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Separator</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Character displayed between groups (e.g. "-").</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">GroupSizes</TableCell><TableCell Class="font-mono text-xs">int[]?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Defines how inputs are grouped (e.g. [3,3] for two groups of three).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Required</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Marks the field as required for form validation.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Invalid</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Applies error styling to indicate a validation error.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">ErrorText</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Error message shown below when Invalid is true (standalone).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">HelperText</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Help text shown below when there is no error (standalone).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Label</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Inline label rendered above the input (standalone).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Name</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>HTML name attribute for form identification.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">FormField</TableCell><TableCell Class="font-mono text-xs">FormFieldContext?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Cascaded context from a parent FormField; drives validation state automatically.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>
</div>

<div class="mt-12">
    <Heading Id="related" Level="2" Class="scroll-mt-20">Related Components</Heading>
    <ul class="mt-4 space-y-2 text-sm">
        <li><a href="/components/input" class="text-primary hover:underline">Input</a> — Standard text input for general free-form text</li>
        <li><a href="/components/password-input" class="text-primary hover:underline">PasswordInput</a> — Password field with visibility toggle and strength meter</li>
        <li><a href="/components/form" class="text-primary hover:underline">Form</a> — Combine OtpInput with form validation and labels</li>
    </ul>
</div>

@code {
    private string _otpValue = "";
    private string _shortOtp = "";
    private string _tfaValue = "";
    private bool _completed;
    private bool _tfaVerified;

    private void HandleComplete(string code)
    {
        _completed = true;
    }

    private void HandleTfa(string code)
    {
        _tfaVerified = true;
    }

    private string _defaultCode = @"<OtpInput @bind-Value=""_otpValue"" OnComplete=""HandleComplete"" />";

    private string _tfaCode = @"<Card>
    <CardHeader>
        <Heading Level=""3"">Two-factor authentication</Heading>
        <Lumeo.Text Size=""sm"" Color=""muted"">Enter the 6-digit code from your authenticator app.</Lumeo.Text>
    </CardHeader>
    <CardContent>
        <OtpInput @bind-Value=""_tfaValue"" OnComplete=""HandleTfa"" />
        @if (_tfaVerified)
        {
            <Badge Variant=""Badge.BadgeVariant.Success"">Verified</Badge>
        }
    </CardContent>
    <CardFooter>
        <Button Class=""w-full"" Disabled=""@(_tfaValue.Length < 6)"">Verify</Button>
    </CardFooter>
</Card>";

    private string _fourDigitCode = @"<OtpInput @bind-Value=""_otp"" Length=""4"" />";

    private string _otpLength = "6";
    private string _otpLengthValue = "";

    private string _lengthCode = @"<Segmented @bind-Value=""_otpLength"">
    <SegmentedItem Value=""4"">4 digits</SegmentedItem>
    <SegmentedItem Value=""6"">6 digits</SegmentedItem>
    <SegmentedItem Value=""8"">8 digits</SegmentedItem>
</Segmented>

<OtpInput Length=""@(int.Parse(_otpLength))"" Value=""@_otpValue"" ValueChanged=""@(v => _otpValue = v)"" />

@if (!string.IsNullOrEmpty(_otpValue))
{
    <Lumeo.Text Size=""sm"" Color=""muted"">Value: @_otpValue</Lumeo.Text>
}

@code {
    private string _otpLength = ""6"";
    private string _otpValue = """";
}";

    private string _pasteOtp = "";
    private string _pasteResult = "";

    private void HandlePasteComplete(string code)
    {
        _pasteResult = code;
    }

    private string _pasteCode = @"<Lumeo.Text Size=""sm"" Color=""muted"">Try pasting a code like ""123456"" into any field</Lumeo.Text>
<OtpInput Length=""6"" @bind-Value=""_pasteOtp"" OnComplete=""@HandlePasteComplete"" />
@if (!string.IsNullOrEmpty(_pasteResult))
{
    <Lumeo.Text Size=""sm"" Class=""text-green-600"">Pasted code: @_pasteResult</Lumeo.Text>
}

@code {
    private string _pasteOtp = """";
    private string _pasteResult = """";
    private void HandlePasteComplete(string code)
    {
        _pasteResult = code;
    }
}";
}
