"use client";

import {
  useCallback,
  useEffect,
  useState,
  type ChangeEvent,
  type ReactElement,
  type SyntheticEvent,
} from "react";
import { FleetSettingsNav } from "@/components/settings/FleetSettingsNav";
import { SettingsAccessDenied } from "@/components/settings/SettingsAccessDenied";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  deleteFleetOidcConfig,
  fetchFleetOidcConfig,
  resetBreakglassAdminPassword,
  updateFleetOidcConfig,
  type FleetOidcConfig,
} from "@/lib/api/fleet-settings";
import { fetchOnboardingStatus } from "@/lib/api/onboarding";

interface OidcFormState {
  issuerUrl: string;
  clientId: string;
  clientSecret: string;
}

interface BreakglassFormState {
  username: string;
  currentPassword: string;
  newPassword: string;
  confirmPassword: string;
}

const INITIAL_OIDC_FORM: OidcFormState = {
  issuerUrl: "",
  clientId: "",
  clientSecret: "",
};

const INITIAL_BREAKGLASS_FORM: BreakglassFormState = {
  username: "",
  currentPassword: "",
  newPassword: "",
  confirmPassword: "",
};

function getErrorMessage(error: unknown, fallback: string): string {
  if (error instanceof Error && error.message.trim().length > 0) {
    return error.message;
  }

  return fallback;
}

function isAdminGuardError(error: unknown): boolean {
  if (!(error instanceof Error)) {
    return false;
  }

  const normalized = error.message.toLowerCase();
  return (
    normalized.includes("requires system administrator") ||
    normalized.includes("forbidden") ||
    normalized.includes("403")
  );
}

export default function AuthSettingsPage(): ReactElement {
  const [oidcConfig, setOidcConfig] = useState<FleetOidcConfig | null>(null);
  const [oidcForm, setOidcForm] = useState<OidcFormState>(INITIAL_OIDC_FORM);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [isSavingOidc, setIsSavingOidc] = useState<boolean>(false);
  const [isDeletingOidc, setIsDeletingOidc] = useState<boolean>(false);
  const [oidcError, setOidcError] = useState<string | null>(null);
  const [oidcSuccessMessage, setOidcSuccessMessage] = useState<string | null>(null);
  const [showRemoveOidcDialog, setShowRemoveOidcDialog] = useState<boolean>(false);

  const [breakglassForm, setBreakglassForm] =
    useState<BreakglassFormState>(INITIAL_BREAKGLASS_FORM);
  const [breakglassStatus, setBreakglassStatus] = useState<"active" | "inactive">("inactive");
  const [isResettingPassword, setIsResettingPassword] = useState<boolean>(false);
  const [breakglassError, setBreakglassError] = useState<string | null>(null);
  const [breakglassSuccessMessage, setBreakglassSuccessMessage] = useState<string | null>(null);

  const [isAccessDenied, setIsAccessDenied] = useState<boolean>(false);

  const loadAuthSettings = useCallback(async (): Promise<void> => {
    setIsLoading(true);

    try {
      const [oidcResponse, onboardingStatus] = await Promise.all([
        fetchFleetOidcConfig(),
        fetchOnboardingStatus().catch(() => ({ completed: false })),
      ]);

      setOidcConfig(oidcResponse);
      setOidcForm({
        issuerUrl: oidcResponse.issuerUrl ?? "",
        clientId: oidcResponse.clientId ?? "",
        clientSecret: "",
      });
      setBreakglassStatus(onboardingStatus.completed ? "active" : "inactive");
      setIsAccessDenied(false);
      setOidcError(null);
    } catch (loadError: unknown) {
      if (isAdminGuardError(loadError)) {
        setIsAccessDenied(true);
        return;
      }

      setOidcError(getErrorMessage(loadError, "Failed to load authentication settings."));
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadAuthSettings();
  }, [loadAuthSettings]);

  async function handleSaveOidc(event: SyntheticEvent): Promise<void> {
    event.preventDefault();
    setOidcError(null);
    setOidcSuccessMessage(null);

    const issuerUrl = oidcForm.issuerUrl.trim();
    const clientId = oidcForm.clientId.trim();
    const clientSecret = oidcForm.clientSecret.trim();

    if (issuerUrl.length === 0 || clientId.length === 0 || clientSecret.length === 0) {
      setOidcError("Issuer URL, client ID, and client secret are required.");
      return;
    }

    try {
      setIsSavingOidc(true);
      await updateFleetOidcConfig({
        issuerUrl,
        clientId,
        clientSecret,
      });
      setOidcSuccessMessage("OIDC configuration updated.");
      await loadAuthSettings();
    } catch (saveError: unknown) {
      setOidcError(getErrorMessage(saveError, "Failed to update OIDC configuration."));
    } finally {
      setIsSavingOidc(false);
    }
  }

  async function handleRemoveOidc(): Promise<void> {
    try {
      setIsDeletingOidc(true);
      await deleteFleetOidcConfig();
      setOidcSuccessMessage("OIDC configuration removed.");
      setShowRemoveOidcDialog(false);
      await loadAuthSettings();
    } catch (deleteError: unknown) {
      setOidcError(getErrorMessage(deleteError, "Failed to remove OIDC configuration."));
    } finally {
      setIsDeletingOidc(false);
    }
  }

  async function handleResetBreakglassPassword(event: SyntheticEvent): Promise<void> {
    event.preventDefault();
    setBreakglassError(null);
    setBreakglassSuccessMessage(null);

    const username = breakglassForm.username.trim();
    const newPassword = breakglassForm.newPassword;
    const confirmPassword = breakglassForm.confirmPassword;

    if (username.length === 0) {
      setBreakglassError("Username is required.");
      return;
    }

    if (newPassword.length < 8) {
      setBreakglassError("New password must be at least 8 characters.");
      return;
    }

    if (newPassword !== confirmPassword) {
      setBreakglassError("Password confirmation does not match.");
      return;
    }

    try {
      setIsResettingPassword(true);
      await resetBreakglassAdminPassword({
        username,
        newPassword,
      });
      setBreakglassSuccessMessage(`Password reset for "${username}".`);
      setBreakglassStatus("active");
      setBreakglassForm((previous) => ({
        ...previous,
        currentPassword: "",
        newPassword: "",
        confirmPassword: "",
      }));
    } catch (resetError: unknown) {
      setBreakglassError(getErrorMessage(resetError, "Failed to reset breakglass password."));
    } finally {
      setIsResettingPassword(false);
    }
  }

  return (
    <div className="max-w-6xl mx-auto p-6 space-y-6">
      <div className="space-y-4">
        <div>
          <h1 className="text-3xl font-bold">Authentication Settings</h1>
          <p className="text-muted-foreground mt-1">
            Configure OIDC and breakglass admin recovery credentials.
          </p>
        </div>
        <FleetSettingsNav />
      </div>

      {isLoading ? (
        <Card>
          <CardContent className="py-8 text-sm text-muted-foreground">
            Loading authentication settings...
          </CardContent>
        </Card>
      ) : null}

      {!isLoading && isAccessDenied ? (
        <SettingsAccessDenied message="Authentication settings require system administrator privileges." />
      ) : null}

      {!isLoading && !isAccessDenied ? (
        <>
          <Card>
            <CardHeader>
              <CardTitle>OIDC Provider</CardTitle>
              <CardDescription>
                Manage your OpenID Connect issuer and OAuth client credentials.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-5">
              <div className="rounded-lg border p-4 space-y-2">
                <div className="flex items-center gap-2">
                  <p className="font-medium">Configured</p>
                  <Badge variant={oidcConfig?.configured ? "default" : "secondary"}>
                    {oidcConfig?.configured ? "Yes" : "No"}
                  </Badge>
                </div>
                <p className="text-sm text-muted-foreground">
                  Issuer URL: {oidcConfig?.issuerUrl ?? "Not configured"}
                </p>
                <p className="text-sm text-muted-foreground">
                  Client ID: {oidcConfig?.clientId ?? "Not configured"}
                </p>
                <p className="text-sm text-muted-foreground">Client secret: hidden</p>
              </div>

              <form onSubmit={(event) => void handleSaveOidc(event)} className="space-y-4">
                <div className="space-y-2">
                  <Label htmlFor="oidc-issuer-url">Issuer URL</Label>
                  <Input
                    id="oidc-issuer-url"
                    value={oidcForm.issuerUrl}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setOidcForm((previous) => ({ ...previous, issuerUrl: event.target.value }));
                    }}
                    placeholder="https://issuer.example.com"
                    disabled={isSavingOidc}
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="oidc-client-id">Client ID</Label>
                  <Input
                    id="oidc-client-id"
                    value={oidcForm.clientId}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setOidcForm((previous) => ({ ...previous, clientId: event.target.value }));
                    }}
                    placeholder="mosaic-web"
                    disabled={isSavingOidc}
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="oidc-client-secret">Client Secret</Label>
                  <Input
                    id="oidc-client-secret"
                    type="password"
                    value={oidcForm.clientSecret}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setOidcForm((previous) => ({
                        ...previous,
                        clientSecret: event.target.value,
                      }));
                    }}
                    placeholder="Enter new secret"
                    autoComplete="new-password"
                    disabled={isSavingOidc}
                    required
                  />
                  <p className="text-xs text-muted-foreground">
                    The secret is encrypted on save and never returned to the UI.
                  </p>
                </div>

                {oidcError ? (
                  <p className="text-sm text-destructive" role="alert">
                    {oidcError}
                  </p>
                ) : null}

                {oidcSuccessMessage ? (
                  <p className="text-sm text-emerald-600">{oidcSuccessMessage}</p>
                ) : null}

                <div className="flex items-center gap-2">
                  <Button type="submit" disabled={isSavingOidc}>
                    {isSavingOidc ? "Saving..." : "Save OIDC"}
                  </Button>
                  <Button
                    type="button"
                    variant="destructive"
                    onClick={() => {
                      setShowRemoveOidcDialog(true);
                    }}
                    disabled={isDeletingOidc || !oidcConfig?.configured}
                  >
                    Remove OIDC
                  </Button>
                </div>
              </form>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Breakglass Admin</CardTitle>
              <CardDescription>
                Reset breakglass credentials for emergency local access.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-5">
              <div className="flex items-center gap-2">
                <p className="font-medium">Status</p>
                <Badge variant={breakglassStatus === "active" ? "default" : "secondary"}>
                  {breakglassStatus}
                </Badge>
              </div>

              <form
                onSubmit={(event) => void handleResetBreakglassPassword(event)}
                className="space-y-4"
              >
                <div className="space-y-2">
                  <Label htmlFor="breakglass-username">Username</Label>
                  <Input
                    id="breakglass-username"
                    value={breakglassForm.username}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setBreakglassForm((previous) => ({
                        ...previous,
                        username: event.target.value,
                      }));
                    }}
                    placeholder="admin"
                    disabled={isResettingPassword}
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="breakglass-current-password">Current Password (optional)</Label>
                  <Input
                    id="breakglass-current-password"
                    type="password"
                    value={breakglassForm.currentPassword}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setBreakglassForm((previous) => ({
                        ...previous,
                        currentPassword: event.target.value,
                      }));
                    }}
                    placeholder="Optional operator confirmation"
                    autoComplete="current-password"
                    disabled={isResettingPassword}
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="breakglass-new-password">New Password</Label>
                  <Input
                    id="breakglass-new-password"
                    type="password"
                    value={breakglassForm.newPassword}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setBreakglassForm((previous) => ({
                        ...previous,
                        newPassword: event.target.value,
                      }));
                    }}
                    placeholder="At least 8 characters"
                    autoComplete="new-password"
                    disabled={isResettingPassword}
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="breakglass-confirm-password">Confirm Password</Label>
                  <Input
                    id="breakglass-confirm-password"
                    type="password"
                    value={breakglassForm.confirmPassword}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      setBreakglassForm((previous) => ({
                        ...previous,
                        confirmPassword: event.target.value,
                      }));
                    }}
                    placeholder="Re-enter password"
                    autoComplete="new-password"
                    disabled={isResettingPassword}
                    required
                  />
                </div>

                {breakglassError ? (
                  <p className="text-sm text-destructive" role="alert">
                    {breakglassError}
                  </p>
                ) : null}

                {breakglassSuccessMessage ? (
                  <p className="text-sm text-emerald-600">{breakglassSuccessMessage}</p>
                ) : null}

                <Button type="submit" disabled={isResettingPassword}>
                  {isResettingPassword ? "Resetting..." : "Reset Password"}
                </Button>
              </form>
            </CardContent>
          </Card>
        </>
      ) : null}

      <AlertDialog
        open={showRemoveOidcDialog}
        onOpenChange={(open) => {
          if (!open && !isDeletingOidc) {
            setShowRemoveOidcDialog(false);
          }
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Remove OIDC Configuration</AlertDialogTitle>
            <AlertDialogDescription>
              This will remove issuer URL, client ID, and client secret from system configuration.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isDeletingOidc}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={handleRemoveOidc} disabled={isDeletingOidc}>
              {isDeletingOidc ? "Removing..." : "Remove OIDC"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
