import { Button } from "@/components/ui/button";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useTranslation } from "react-i18next";
import { useState, useCallback, useMemo } from "react";
import { LuEye, LuEyeOff } from "react-icons/lu";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import axios from "axios";
import { toast } from "sonner";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import {
  WizardFormData,
  CameraBrand,
  CAMERA_BRANDS,
  CAMERA_BRAND_VALUES,
  TestResult,
  FfprobeStream,
  FfprobeData,
  FfprobeResponse,
  StreamRole,
  StreamConfig,
  OnvifProbeResponse,
} from "@/types/cameraWizard";
import type { CandidateTestMap } from "@/types/cameraWizard";
import { FaCircleCheck } from "react-icons/fa6";
import { Card, CardContent, CardTitle } from "../../ui/card";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { LuInfo } from "react-icons/lu";
import { detectReolinkCamera } from "@/utils/cameraUtil";
import ProbeDialog from "./ProbeDialog";

type Step1NameCameraProps = {
  wizardData: Partial<WizardFormData>;
  onUpdate: (data: Partial<WizardFormData>) => void;
  onNext: (data?: Partial<WizardFormData>) => void;
  onCancel: () => void;
  canProceed?: boolean;
};

export default function Step1NameCamera({
  wizardData,
  onUpdate,
  onNext,
  onCancel,
}: Step1NameCameraProps) {
  const { t } = useTranslation(["views/settings"]);
  const { data: config } = useSWR<FrigateConfig>("config");
  const [showPassword, setShowPassword] = useState(false);
  const [isTesting, setIsTesting] = useState(false);
  const [testStatus, setTestStatus] = useState<string>("");
  const [testResult, setTestResult] = useState<TestResult | null>(null);
  const [probeMode, setProbeMode] = useState<boolean>(true);
  const [onvifPort, setOnvifPort] = useState<number>(80);
  const [isProbing, setIsProbing] = useState(false);
  const [probeError, setProbeError] = useState<string | null>(null);
  const [probeResult, setProbeResult] = useState<OnvifProbeResponse | null>(
    null,
  );
  const [probeDialogOpen, setProbeDialogOpen] = useState(false);
  const [selectedCandidateUris, setSelectedCandidateUris] = useState<string[]>(
    [],
  );
  const [candidateTests, setCandidateTests] = useState<CandidateTestMap>(
    {} as CandidateTestMap,
  );
  const [testingCandidates, setTestingCandidates] = useState<
    Record<string, boolean>
  >({} as Record<string, boolean>);

  const existingCameraNames = useMemo(() => {
    if (!config?.cameras) {
      return [];
    }
    return Object.keys(config.cameras);
  }, [config]);

  const step1FormData = z
    .object({
      cameraName: z
        .string()
        .min(1, t("cameraWizard.step1.errors.nameRequired"))
        .max(64, t("cameraWizard.step1.errors.nameLength"))
        .refine(
          (value) => !existingCameraNames.includes(value),
          t("cameraWizard.step1.errors.nameExists"),
        ),
      host: z.string().optional(),
      username: z.string().optional(),
      password: z.string().optional(),
      brandTemplate: z.enum(CAMERA_BRAND_VALUES).optional(),
      customUrl: z
        .string()
        .optional()
        .refine(
          (val) => !val || val.startsWith("rtsp://"),
          t("cameraWizard.step1.errors.customUrlRtspRequired"),
        ),
    })
    .refine(
      (data) => {
        // If brand is "other", customUrl is required
        if (data.brandTemplate === "other") {
          return data.customUrl && data.customUrl.trim().length > 0;
        }
        // If brand is not "other", host is required
        return data.host && data.host.trim().length > 0;
      },
      {
        message: t("cameraWizard.step1.errors.brandOrCustomUrlRequired"),
        path: ["customUrl"],
      },
    );

  const form = useForm<z.infer<typeof step1FormData>>({
    resolver: zodResolver(step1FormData),
    defaultValues: {
      cameraName: wizardData.cameraName || "",
      host: wizardData.host || "",
      username: wizardData.username || "",
      password: wizardData.password || "",
      brandTemplate:
        wizardData.brandTemplate &&
        CAMERA_BRAND_VALUES.includes(wizardData.brandTemplate as CameraBrand)
          ? (wizardData.brandTemplate as CameraBrand)
          : "dahua",
      customUrl: wizardData.customUrl || "",
    },
    mode: "onChange",
  });

  const watchedBrand = form.watch("brandTemplate");
  const watchedHost = form.watch("host");
  const watchedCustomUrl = form.watch("customUrl");

  const hostPresent = !!(watchedHost && watchedHost.trim());
  const customPresent = !!(watchedCustomUrl && watchedCustomUrl.trim());
  const cameraNamePresent = !!(form.getValues().cameraName || "").trim();

  const isTestButtonEnabled =
    cameraNamePresent &&
    (probeMode
      ? hostPresent
      : watchedBrand === "other"
        ? customPresent
        : hostPresent);

  const generateDynamicStreamUrl = useCallback(
    async (data: z.infer<typeof step1FormData>): Promise<string | null> => {
      const brand = CAMERA_BRANDS.find((b) => b.value === data.brandTemplate);
      if (!brand || !data.host) return null;

      let protocol = undefined;
      if (data.brandTemplate === "reolink" && data.username && data.password) {
        try {
          protocol = await detectReolinkCamera(
            data.host,
            data.username,
            data.password,
          );
        } catch (error) {
          return null;
        }
      }

      // Use detected protocol or fallback to rtsp
      const protocolKey = protocol || "rtsp";
      const templates: Record<string, string> = brand.dynamicTemplates || {};

      if (Object.keys(templates).includes(protocolKey)) {
        const template =
          templates[protocolKey as keyof typeof brand.dynamicTemplates];
        return template
          .replace("{username}", data.username || "")
          .replace("{password}", data.password || "")
          .replace("{host}", data.host);
      }

      return null;
    },
    [],
  );

  const generateStreamUrl = useCallback(
    async (data: z.infer<typeof step1FormData>): Promise<string> => {
      if (data.brandTemplate === "other") {
        return data.customUrl || "";
      }

      const brand = CAMERA_BRANDS.find((b) => b.value === data.brandTemplate);
      if (!brand || !data.host) return "";

      if (brand.template === "dynamic" && "dynamicTemplates" in brand) {
        const dynamicUrl = await generateDynamicStreamUrl(data);

        if (dynamicUrl) {
          return dynamicUrl;
        }

        return "";
      }

      return brand.template
        .replace("{username}", data.username || "")
        .replace("{password}", data.password || "")
        .replace("{host}", data.host);
    },
    [generateDynamicStreamUrl],
  );

  const probeCamera = useCallback(async () => {
    const data = form.getValues();

    if (!data.host) {
      toast.error(t("cameraWizard.step1.errors.hostRequired"));
      return;
    }

    setIsProbing(true);
    setProbeError(null);
    setProbeResult(null);

    try {
      const response = await axios.get("/onvif/probe", {
        params: {
          host: data.host,
          port: onvifPort,
          username: data.username || "",
          password: data.password || "",
          test: false,
        },
        timeout: 30000,
      });

      if (response.data && response.data.success) {
        setProbeResult(response.data);
        // open the probe dialog to show results
        setProbeDialogOpen(true);
      } else {
        setProbeError(response.data?.message || "Probe failed");
      }
    } catch (error) {
      const axiosError = error as {
        response?: { data?: { message?: string; detail?: string } };
        message?: string;
      };
      const errorMessage =
        axiosError.response?.data?.message ||
        axiosError.response?.data?.detail ||
        axiosError.message ||
        "Failed to probe camera";
      setProbeError(errorMessage);
      toast.error(t("cameraWizard.step1.probeFailed", { error: errorMessage }));
    } finally {
      setIsProbing(false);
    }
  }, [form, onvifPort, t]);

  const handleSelectCandidate = useCallback((uri: string) => {
    // toggle selection: add or remove from selectedCandidateUris
    setSelectedCandidateUris((s) => {
      if (s.includes(uri)) {
        return s.filter((u) => u !== uri);
      }
      return [...s, uri];
    });
  }, []);

  // Probe a single URI and return a TestResult. If fetchSnapshot is true,
  // also attempt to fetch a snapshot (may be undefined on failure).
  const probeUri = useCallback(
    async (
      uri: string,
      fetchSnapshot = false,
      setStatus?: (s: string) => void,
    ): Promise<TestResult> => {
      try {
        const probeResponse = await axios.get("ffprobe", {
          params: { paths: uri, detailed: true },
          timeout: 10000,
        });

        let probeData: FfprobeResponse | null = null;
        if (
          probeResponse.data &&
          probeResponse.data.length > 0 &&
          probeResponse.data[0].return_code === 0
        ) {
          probeData = probeResponse.data[0];
        }

        if (!probeData) {
          const error =
            Array.isArray(probeResponse.data?.[0]?.stderr) &&
            probeResponse.data[0].stderr.length > 0
              ? probeResponse.data[0].stderr.join("\n")
              : "Unable to probe stream";
          return { success: false, error };
        }

        // stdout may be a string or structured object. Normalize to FfprobeData.
        let ffprobeData: FfprobeData;
        if (typeof probeData.stdout === "string") {
          try {
            ffprobeData = JSON.parse(probeData.stdout as string) as FfprobeData;
          } catch {
            ffprobeData = { streams: [] };
          }
        } else {
          ffprobeData = probeData.stdout as FfprobeData;
        }

        const streams = ffprobeData.streams || [];

        const videoStream = streams.find(
          (s: FfprobeStream) =>
            s.codec_type === "video" ||
            s.codec_name?.includes("h264") ||
            s.codec_name?.includes("hevc"),
        );

        const audioStream = streams.find(
          (s: FfprobeStream) =>
            s.codec_type === "audio" ||
            s.codec_name?.includes("aac") ||
            s.codec_name?.includes("mp3") ||
            s.codec_name?.includes("pcm_mulaw") ||
            s.codec_name?.includes("pcm_alaw"),
        );

        const resolution = videoStream
          ? `${videoStream.width}x${videoStream.height}`
          : undefined;

        const fps = videoStream?.avg_frame_rate
          ? parseFloat(videoStream.avg_frame_rate.split("/")[0]) /
            parseFloat(videoStream.avg_frame_rate.split("/")[1])
          : undefined;

        let snapshotBase64: string | undefined = undefined;
        if (fetchSnapshot) {
          if (setStatus) {
            setStatus(t("cameraWizard.step1.testing.fetchingSnapshot"));
          }
          try {
            const snapshotResponse = await axios.get("ffprobe/snapshot", {
              params: { url: uri },
              responseType: "blob",
              timeout: 10000,
            });
            const snapshotBlob = snapshotResponse.data;
            snapshotBase64 = await new Promise<string>((resolve) => {
              const reader = new FileReader();
              reader.onload = () => resolve(reader.result as string);
              reader.readAsDataURL(snapshotBlob);
            });
          } catch (snapshotError) {
            snapshotBase64 = undefined;
          }
        }

        const streamTestResult: TestResult = {
          success: true,
          snapshot: snapshotBase64,
          resolution,
          videoCodec: videoStream?.codec_name,
          audioCodec: audioStream?.codec_name,
          fps: fps && !isNaN(fps) ? fps : undefined,
        };

        return streamTestResult;
      } catch (err) {
        const axiosError = err as {
          response?: { data?: { message?: string; detail?: string } };
          message?: string;
        };
        const errorMessage =
          axiosError.response?.data?.message ||
          axiosError.response?.data?.detail ||
          axiosError.message ||
          "Connection failed";
        return { success: false, error: errorMessage };
      }
    },
    [t],
  );

  const testAllSelectedCandidates = useCallback(async () => {
    const uris = selectedCandidateUris;
    if (!uris || uris.length === 0) {
      toast.error(t("cameraWizard.commonErrors.noUrl"));
      return;
    }

    setIsTesting(true);
    setTestStatus(t("cameraWizard.step1.testing.probingMetadata"));

    const streamConfigs: StreamConfig[] = [];
    let firstSuccessfulTestResult: TestResult | null = null;
    let firstSuccessfulUri: string | undefined = undefined;

    try {
      for (let i = 0; i < uris.length; i++) {
        const uri = uris[i];
        const streamTestResult = await probeUri(uri, false);

        if (streamTestResult && streamTestResult.success) {
          const streamId = `stream_${Date.now()}_${i}`;
          streamConfigs.push({
            id: streamId,
            url: uri,
            // Only the first stream should have the detect role
            roles:
              streamConfigs.length === 0
                ? (["detect"] as StreamRole[])
                : ([] as StreamRole[]),
            testResult: streamTestResult,
          });

          // keep first successful for main pane snapshot
          if (!firstSuccessfulTestResult) {
            firstSuccessfulTestResult = streamTestResult;
            firstSuccessfulUri = uri;
          }
          // also store candidate test summary
          setCandidateTests((s) => ({ ...s, [uri]: streamTestResult }));
        } else {
          setCandidateTests((s) => ({
            ...s,
            [uri]: streamTestResult,
          }));
        }
      }

      if (streamConfigs.length > 0) {
        // Add all successful streams and navigate to Step 2
        onNext({ streams: streamConfigs, customUrl: firstSuccessfulUri });
        toast.success(t("cameraWizard.step1.testSuccess"));
        setProbeDialogOpen(false);
        setProbeResult(null);
      } else {
        toast.error(
          t("cameraWizard.commonErrors.testFailed", {
            error: "No streams succeeded",
          }),
        );
      }
    } catch (error) {
      const axiosError = error as {
        response?: { data?: { message?: string; detail?: string } };
        message?: string;
      };
      const errorMessage =
        axiosError.response?.data?.message ||
        axiosError.response?.data?.detail ||
        axiosError.message ||
        "Connection failed";
      setTestResult({
        success: false,
        error: errorMessage,
      });
      toast.error(
        t("cameraWizard.commonErrors.testFailed", { error: errorMessage }),
      );
    } finally {
      setIsTesting(false);
      setTestStatus("");
    }
  }, [selectedCandidateUris, t, onNext, probeUri]);

  const testCandidate = useCallback(
    async (uri: string) => {
      if (!uri) return;
      setTestingCandidates((s) => ({ ...s, [uri]: true }));
      try {
        const result = await probeUri(uri, false);
        setCandidateTests((s) => ({ ...s, [uri]: result }));
      } finally {
        setTestingCandidates((s) => ({ ...s, [uri]: false }));
      }
    },
    [probeUri],
  );

  const testConnection = useCallback(async () => {
    const _data = form.getValues();
    const streamUrl = await generateStreamUrl(_data);

    if (!streamUrl) {
      toast.error(t("cameraWizard.commonErrors.noUrl"));
      return;
    }

    setIsTesting(true);
    setTestStatus("");
    setTestResult(null);

    try {
      setTestStatus(t("cameraWizard.step1.testing.probingMetadata"));
      const result = await probeUri(streamUrl, true, setTestStatus);

      if (result && result.success) {
        setTestResult(result);
        onUpdate({
          streams: [{ id: "", url: streamUrl, roles: [], testResult: result }],
        });
        toast.success(t("cameraWizard.step1.testSuccess"));
      } else {
        const errMsg = result?.error || "Unable to probe stream";
        setTestResult({
          success: false,
          error: errMsg,
        });
        toast.error(
          t("cameraWizard.commonErrors.testFailed", { error: errMsg }),
          {
            duration: 6000,
          },
        );
      }
    } catch (error) {
      const axiosError = error as {
        response?: { data?: { message?: string; detail?: string } };
        message?: string;
      };
      const errorMessage =
        axiosError.response?.data?.message ||
        axiosError.response?.data?.detail ||
        axiosError.message ||
        "Connection failed";
      setTestResult({
        success: false,
        error: errorMessage,
      });
      toast.error(
        t("cameraWizard.commonErrors.testFailed", { error: errorMessage }),
        {
          duration: 10000,
        },
      );
    } finally {
      setIsTesting(false);
      setTestStatus("");
    }
  }, [form, generateStreamUrl, t, onUpdate, probeUri]);

  const onSubmit = (data: z.infer<typeof step1FormData>) => {
    onUpdate(data);
  };

  const handleContinue = useCallback(async () => {
    const data = form.getValues();
    const streamUrl = await generateStreamUrl(data);
    const streamId = `stream_${Date.now()}`;

    const streamConfig: StreamConfig = {
      id: streamId,
      url: streamUrl,
      roles: ["detect" as StreamRole],
      resolution: testResult?.resolution,
      testResult: testResult || undefined,
      userTested: false,
    };

    const updatedData = {
      ...data,
      streams: [streamConfig],
    };

    onNext(updatedData);
  }, [form, generateStreamUrl, testResult, onNext]);

  return (
    <div className="space-y-6">
      {!testResult?.success && (
        <>
          <div className="text-sm text-muted-foreground">
            {t("cameraWizard.step1.description")}
          </div>

          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
              <FormField
                control={form.control}
                name="cameraName"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="text-primary-variant">
                      {t("cameraWizard.step1.cameraName")}
                    </FormLabel>
                    <FormControl>
                      <Input
                        className="text-md h-8"
                        placeholder={t(
                          "cameraWizard.step1.cameraNamePlaceholder",
                        )}
                        {...field}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <div className="space-y-4">
                <FormField
                  control={form.control}
                  name="host"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel className="text-primary-variant">
                        {t("cameraWizard.step1.host")}
                      </FormLabel>
                      <FormControl>
                        <Input
                          className="text-md h-8"
                          placeholder="192.168.1.100"
                          {...field}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="username"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel className="text-primary-variant">
                        {t("cameraWizard.step1.username")}
                      </FormLabel>
                      <FormControl>
                        <Input
                          className="text-md h-8"
                          placeholder={t(
                            "cameraWizard.step1.usernamePlaceholder",
                          )}
                          {...field}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="password"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel className="text-primary-variant">
                        {t("cameraWizard.step1.password")}
                      </FormLabel>
                      <FormControl>
                        <div className="relative">
                          <Input
                            className="text-md h-8 pr-10"
                            type={showPassword ? "text" : "password"}
                            placeholder={t(
                              "cameraWizard.step1.passwordPlaceholder",
                            )}
                            {...field}
                          />
                          <Button
                            type="button"
                            variant="ghost"
                            size="sm"
                            className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
                            onClick={() => setShowPassword(!showPassword)}
                          >
                            {showPassword ? (
                              <LuEyeOff className="size-4" />
                            ) : (
                              <LuEye className="size-4" />
                            )}
                          </Button>
                        </div>
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>

              <div className="space-y-3 pt-4">
                <FormLabel className="text-primary-variant">
                  {t("cameraWizard.step1.detectionMethod")}
                </FormLabel>
                <RadioGroup
                  value={probeMode ? "probe" : "manual"}
                  onValueChange={(value) => {
                    setProbeMode(value === "probe");
                    setProbeResult(null);
                    setProbeError(null);
                  }}
                >
                  <div className="flex items-center space-x-2">
                    <RadioGroupItem value="probe" id="probe-mode" />
                    <label
                      htmlFor="probe-mode"
                      className="cursor-pointer text-sm"
                    >
                      {t("cameraWizard.step1.probeMode")}
                    </label>
                  </div>
                  <div className="flex items-center space-x-2">
                    <RadioGroupItem value="manual" id="manual-mode" />
                    <label
                      htmlFor="manual-mode"
                      className="cursor-pointer text-sm"
                    >
                      {t("cameraWizard.step1.manualMode")}
                    </label>
                  </div>
                </RadioGroup>
              </div>

              {probeMode && (
                <FormItem>
                  <FormLabel className="text-primary-variant">
                    {t("cameraWizard.step1.onvifPort")}
                  </FormLabel>
                  <FormControl>
                    <Input
                      className="text-md h-8"
                      type="number"
                      min="1"
                      max="65535"
                      value={onvifPort}
                      onChange={(e) =>
                        setOnvifPort(parseInt(e.target.value, 10) || 80)
                      }
                      placeholder="80"
                    />
                  </FormControl>
                </FormItem>
              )}

              {!probeMode && (
                <div className="space-y-4">
                  <FormField
                    control={form.control}
                    name="brandTemplate"
                    render={({ field }) => (
                      <FormItem>
                        <div className="flex items-center gap-1 pb-1">
                          <FormLabel className="text-primary-variant">
                            {t("cameraWizard.step1.cameraBrand")}
                          </FormLabel>
                          {field.value &&
                            (() => {
                              const selectedBrand = CAMERA_BRANDS.find(
                                (brand) => brand.value === field.value,
                              );
                              return selectedBrand &&
                                selectedBrand.value != "other" ? (
                                <Popover>
                                  <PopoverTrigger asChild>
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      className="h-4 w-4 p-0"
                                    >
                                      <LuInfo className="size-3" />
                                    </Button>
                                  </PopoverTrigger>
                                  <PopoverContent className="pointer-events-auto w-80 text-primary-variant">
                                    <div className="space-y-2">
                                      <h4 className="font-medium">
                                        {selectedBrand.label}
                                      </h4>
                                      <p className="break-all text-sm text-muted-foreground">
                                        {t(
                                          "cameraWizard.step1.brandUrlFormat",
                                          {
                                            exampleUrl:
                                              selectedBrand.exampleUrl,
                                          },
                                        )}
                                      </p>
                                    </div>
                                  </PopoverContent>
                                </Popover>
                              ) : null;
                            })()}
                        </div>
                        <Select
                          onValueChange={field.onChange}
                          defaultValue={field.value}
                        >
                          <FormControl>
                            <SelectTrigger className="h-8">
                              <SelectValue
                                placeholder={t(
                                  "cameraWizard.step1.selectBrand",
                                )}
                              />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            {CAMERA_BRANDS.map((brand) => (
                              <SelectItem key={brand.value} value={brand.value}>
                                {brand.label}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  {watchedBrand == "other" && (
                    <FormField
                      control={form.control}
                      name="customUrl"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className="text-primary-variant">
                            {t("cameraWizard.step1.customUrl")}
                          </FormLabel>
                          <FormControl>
                            <Input
                              className="text-md h-8"
                              placeholder="rtsp://username:password@host:port/path"
                              {...field}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  )}
                </div>
              )}
            </form>
          </Form>
        </>
      )}

      {probeMode && probeResult && (
        <div className="p-4">
          <ProbeDialog
            open={probeDialogOpen}
            onOpenChange={setProbeDialogOpen}
            isLoading={isProbing}
            isError={!!probeError}
            error={probeError || undefined}
            probeResult={probeResult}
            onSelectCandidate={handleSelectCandidate}
            onRetry={probeCamera}
            selectedCandidateUris={selectedCandidateUris}
            testAllSelectedCandidates={testAllSelectedCandidates}
            isTesting={isTesting}
            testStatus={testStatus}
            testCandidate={testCandidate}
            candidateTests={candidateTests}
            testingCandidates={testingCandidates}
          />
        </div>
      )}

      {testResult?.success && (
        <div className="p-4">
          <div className="mb-3 flex flex-row items-center gap-2 text-sm font-medium text-success">
            <FaCircleCheck className="size-4" />
            {t("cameraWizard.step1.testSuccess")}
          </div>

          <div className="space-y-3">
            {testResult.snapshot ? (
              <div className="relative flex justify-center">
                <img
                  src={testResult.snapshot}
                  alt="Camera snapshot"
                  className="max-h-[50dvh] max-w-full rounded-lg object-contain"
                />
                <div className="absolute bottom-2 right-2 rounded-md bg-black/70 p-3 text-sm backdrop-blur-sm">
                  <div className="space-y-1">
                    <StreamDetails testResult={testResult} />
                  </div>
                </div>
              </div>
            ) : (
              <Card className="p-4">
                <CardTitle className="mb-2 text-sm">
                  {t("cameraWizard.step1.streamDetails")}
                </CardTitle>
                <CardContent className="p-0 text-sm">
                  <StreamDetails testResult={testResult} />
                </CardContent>
              </Card>
            )}
          </div>
        </div>
      )}

      {isTesting && (
        <div className="flex items-center gap-2 text-sm text-muted-foreground">
          <ActivityIndicator className="size-4" />
          {testStatus}
        </div>
      )}
      <div className="flex flex-col gap-3 pt-3 sm:flex-row sm:justify-end sm:gap-4">
        <Button
          type="button"
          onClick={testResult?.success ? () => setTestResult(null) : onCancel}
          className="sm:flex-1"
        >
          {testResult?.success
            ? t("button.back", { ns: "common" })
            : t("button.cancel", { ns: "common" })}
        </Button>
        {testResult?.success ? (
          <Button
            type="button"
            onClick={handleContinue}
            variant="select"
            className="flex items-center justify-center gap-2 sm:flex-1"
          >
            {t("button.continue", { ns: "common" })}
          </Button>
        ) : (
          <Button
            type="button"
            onClick={probeMode ? probeCamera : testConnection}
            disabled={
              (probeMode ? isProbing : isTesting) || !isTestButtonEnabled
            }
            variant="select"
            className="flex items-center justify-center gap-2 sm:flex-1"
          >
            {probeMode
              ? t("cameraWizard.step1.probeMode")
              : t("cameraWizard.step1.testConnection")}
          </Button>
        )}
      </div>
    </div>
  );
}

function StreamDetails({ testResult }: { testResult: TestResult }) {
  const { t } = useTranslation(["views/settings"]);

  return (
    <>
      {testResult.resolution && (
        <div>
          <span className="text-white/70">
            {t("cameraWizard.testResultLabels.resolution")}:
          </span>{" "}
          <span className="text-white">{testResult.resolution}</span>
        </div>
      )}
      {testResult.fps && (
        <div>
          <span className="text-white/70">
            {t("cameraWizard.testResultLabels.fps")}:
          </span>{" "}
          <span className="text-white">{testResult.fps}</span>
        </div>
      )}
      {testResult.videoCodec && (
        <div>
          <span className="text-white/70">
            {t("cameraWizard.testResultLabels.video")}:
          </span>{" "}
          <span className="text-white">{testResult.videoCodec}</span>
        </div>
      )}
      {testResult.audioCodec && (
        <div>
          <span className="text-white/70">
            {t("cameraWizard.testResultLabels.audio")}:
          </span>{" "}
          <span className="text-white">{testResult.audioCodec}</span>
        </div>
      )}
    </>
  );
}
