import { Alert, Button, PinInput, Stack, Text } from "@mantine/core";
import { AlertCircle, ArrowLeft, RotateCw, ShieldCheck } from "lucide-react";

import { maskEmail, maskPhone } from "@/utils/identifier";

export const OTP_LENGTH = 6;

export interface OtpChannelStepProps {
  /**
   * Raw contacts the code was sent to; masked before display. The API sends one
   * code to every contact on the account, so both are usually set — pass only
   * what the client actually knows. Omit both when the client cannot know them
   * (the forgot-password flow deliberately never reveals an account's contacts)
   * and a generic line is shown instead.
   */
  email?: string;
  phone?: string;
  value: string;
  onChange: (otp: string) => void;
  onVerify: () => void;
  onBack: () => void;
  onResend: () => void;
  /** Seconds until resend is allowed; 0 enables the button. */
  resendIn: number;
  sending: boolean;
  verifying: boolean;
  error: string | null;
  title?: string;
  description?: string;
  submitLabel: string;
}

/**
 * The "enter the code we sent you" stage. Shared by signup and the
 * forgot-password flow — both send through the same `/api/otp/*` service, which
 * delivers a single code to the account's email AND phone; whichever message
 * arrives first can be typed here.
 */
export default function OtpChannelStep({
  email,
  phone,
  value,
  onChange,
  onVerify,
  onBack,
  onResend,
  resendIn,
  sending,
  verifying,
  error,
  title,
  description,
  submitLabel,
}: OtpChannelStepProps) {
  const maskedTargets = [
    email ? maskEmail(email) : null,
    phone ? maskPhone(phone) : null,
  ].filter(Boolean) as string[];
  const busy = sending || verifying;

  return (
    <Stack gap="md">
      <div className="mb-1 flex justify-center">
        <span className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary">
          <ShieldCheck size={22} />
        </span>
      </div>

      <div className="space-y-1.5 text-center">
        <h1 className="text-xl font-bold tracking-tight text-gray-900 sm:text-2xl">
          {title ?? "Verify it's you"}
        </h1>
        <p className="text-sm leading-relaxed text-gray-500">
          We sent a {OTP_LENGTH}-digit code to{" "}
          {maskedTargets.length ? (
            maskedTargets.map((target, index) => (
              <span key={target}>
                {index > 0 ? " and " : null}
                <span className="font-medium text-gray-700">{target}</span>
              </span>
            ))
          ) : (
            <span className="font-medium text-gray-700">
              the email and phone on your account
            </span>
          )}
          . {description ?? "Enter it to continue."}
        </p>
      </div>

      {error ? (
        <Alert color="red" variant="light" icon={<AlertCircle size={18} />}>
          {error}
        </Alert>
      ) : null}

      <Stack gap={6} align="center">
        <Text size="sm" fw={500} c="edr-text">
          Verification code
        </Text>
        <PinInput
          length={OTP_LENGTH}
          type="number"
          oneTimeCode
          value={value}
          placeholder="0"
          disabled={verifying}
          styles={{ input: { textAlign: "center" } }}
          onChange={onChange}
        />
      </Stack>

      <Button
        color="edr-green"
        fullWidth
        loading={verifying}
        disabled={verifying || value.trim().length !== OTP_LENGTH}
        onClick={onVerify}
      >
        {submitLabel}
      </Button>

      <div className="flex items-center justify-between">
        <Button
          variant="subtle"
          color="gray"
          leftSection={<ArrowLeft size={14} />}
          disabled={busy}
          onClick={onBack}
        >
          Back
        </Button>
        <Button
          variant="subtle"
          color="edr-green"
          leftSection={<RotateCw size={14} />}
          disabled={resendIn > 0 || busy}
          onClick={onResend}
        >
          {resendIn > 0 ? `Resend in ${resendIn}s` : "Resend code"}
        </Button>
      </div>
    </Stack>
  );
}
