"use client";

import { ChevronLeftIcon, ChevronRightIcon, Loader2 } from "lucide-react";
import { useEffect } from "react";
import { Control, UseFormSetValue } from "react-hook-form";

import { Button } from "@/components/shadcn";
import { Form } from "@/components/shadcn/form";
import { Separator } from "@/components/shadcn/separator/separator";
import { useCredentialsForm } from "@/hooks/use-credentials-form";
import { getAWSCredentialsTemplateLinks } from "@/lib";
import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields";
import { requiresBackButton } from "@/lib/provider-helpers";
import {
  AlibabaCloudCredentials,
  AlibabaCloudCredentialsRole,
  ApiResponse,
  AWSCredentials,
  AWSCredentialsRole,
  AzureCredentials,
  CloudflareApiKeyCredentials,
  CloudflareTokenCredentials,
  GCPDefaultCredentials,
  GCPServiceAccountKey,
  GoogleWorkspaceCredentials,
  IacCredentials,
  ImageCredentials,
  KubernetesCredentials,
  M365CertificateCredentials,
  M365ClientSecretCredentials,
  MongoDBAtlasCredentials,
  OCICredentials,
  OktaCredentials,
  OpenStackCredentials,
  ProviderType,
  VercelCredentials,
} from "@/types";

import { ProviderTitleDocs } from "../provider-title-docs";
import {
  AlibabaCloudRoleCredentialsForm,
  AlibabaCloudStaticCredentialsForm,
} from "./select-credentials-type/alibabacloud/credentials-type";
import { AWSStaticCredentialsForm } from "./select-credentials-type/aws/credentials-type";
import { AWSRoleCredentialsForm } from "./select-credentials-type/aws/credentials-type/aws-role-credentials-form";
import {
  CloudflareApiKeyCredentialsForm,
  CloudflareApiTokenCredentialsForm,
} from "./select-credentials-type/cloudflare";
import { GCPDefaultCredentialsForm } from "./select-credentials-type/gcp/credentials-type";
import { GCPServiceAccountKeyForm } from "./select-credentials-type/gcp/credentials-type/gcp-service-account-key-form";
import {
  M365CertificateCredentialsForm,
  M365ClientSecretCredentialsForm,
} from "./select-credentials-type/m365";
import { AzureCredentialsForm } from "./via-credentials/azure-credentials-form";
import { GitHubCredentialsForm } from "./via-credentials/github-credentials-form";
import { GoogleWorkspaceCredentialsForm } from "./via-credentials/googleworkspace-credentials-form";
import { IacCredentialsForm } from "./via-credentials/iac-credentials-form";
import { ImageCredentialsForm } from "./via-credentials/image-credentials-form";
import { KubernetesCredentialsForm } from "./via-credentials/k8s-credentials-form";
import { MongoDBAtlasCredentialsForm } from "./via-credentials/mongodbatlas-credentials-form";
import { OktaCredentialsForm } from "./via-credentials/okta-credentials-form";
import { OpenStackCredentialsForm } from "./via-credentials/openstack-credentials-form";
import { OracleCloudCredentialsForm } from "./via-credentials/oraclecloud-credentials-form";
import { VercelCredentialsForm } from "./via-credentials/vercel-credentials-form";

type BaseCredentialsFormProps = {
  providerType: ProviderType;
  providerId: string;
  providerUid?: string;
  onSubmit: (formData: FormData) => Promise<ApiResponse>;
  successNavigationUrl: string;
  via?: string | null;
  onSuccess?: () => void;
  onBack?: () => void;
  formId?: string;
  hideActions?: boolean;
  onLoadingChange?: (isLoading: boolean) => void;
  onValidityChange?: (isValid: boolean) => void;
  submitButtonText?: string;
  showBackButton?: boolean;
  validationMode?: "onSubmit" | "onChange";
};

export const BaseCredentialsForm = ({
  providerType,
  providerId,
  providerUid,
  onSubmit,
  successNavigationUrl,
  via,
  onSuccess,
  onBack,
  formId,
  hideActions = false,
  onLoadingChange,
  onValidityChange,
  submitButtonText = "Next",
  showBackButton = true,
  validationMode,
}: BaseCredentialsFormProps) => {
  const {
    form,
    isLoading,
    isValid,
    handleSubmit,
    handleBackStep,
    effectiveVia,
    externalId,
  } = useCredentialsForm({
    providerType,
    providerId,
    providerUid,
    onSubmit,
    successNavigationUrl,
    via,
    onSuccess,
    onBack,
    validationMode,
  });

  useEffect(() => {
    onLoadingChange?.(isLoading);
  }, [isLoading, onLoadingChange]);

  useEffect(() => {
    onValidityChange?.(isValid);
  }, [isValid, onValidityChange]);

  const templateLinks = getAWSCredentialsTemplateLinks(externalId);

  return (
    <Form {...form}>
      <form
        id={formId}
        onSubmit={form.handleSubmit(handleSubmit)}
        className="flex flex-col gap-4"
      >
        <input
          type="hidden"
          name={ProviderCredentialFields.PROVIDER_ID}
          value={providerId}
        />
        <input
          type="hidden"
          name={ProviderCredentialFields.PROVIDER_TYPE}
          value={providerType}
        />
        {providerUid && (
          <input
            type="hidden"
            name={ProviderCredentialFields.PROVIDER_UID}
            value={providerUid}
          />
        )}

        <ProviderTitleDocs providerType={providerType} />

        <Separator />

        {providerType === "aws" && effectiveVia === "role" && (
          <AWSRoleCredentialsForm
            control={form.control as unknown as Control<AWSCredentialsRole>}
            setValue={
              form.setValue as unknown as UseFormSetValue<AWSCredentialsRole>
            }
            externalId={externalId}
            templateLinks={templateLinks}
          />
        )}
        {providerType === "aws" && effectiveVia !== "role" && (
          <AWSStaticCredentialsForm
            control={form.control as unknown as Control<AWSCredentials>}
          />
        )}
        {providerType === "azure" && (
          <AzureCredentialsForm
            control={form.control as unknown as Control<AzureCredentials>}
          />
        )}
        {providerType === "m365" && effectiveVia === "app_client_secret" && (
          <M365ClientSecretCredentialsForm
            control={
              form.control as unknown as Control<M365ClientSecretCredentials>
            }
          />
        )}
        {providerType === "m365" && effectiveVia === "app_certificate" && (
          <M365CertificateCredentialsForm
            control={
              form.control as unknown as Control<M365CertificateCredentials>
            }
          />
        )}
        {providerType === "gcp" && effectiveVia === "service-account" && (
          <GCPServiceAccountKeyForm
            control={form.control as unknown as Control<GCPServiceAccountKey>}
          />
        )}
        {providerType === "gcp" && effectiveVia !== "service-account" && (
          <GCPDefaultCredentialsForm
            control={form.control as unknown as Control<GCPDefaultCredentials>}
          />
        )}
        {providerType === "kubernetes" && (
          <KubernetesCredentialsForm
            control={form.control as unknown as Control<KubernetesCredentials>}
          />
        )}
        {providerType === "github" && (
          <GitHubCredentialsForm
            control={form.control}
            credentialsType={effectiveVia || undefined}
          />
        )}
        {providerType === "iac" && (
          <IacCredentialsForm
            control={form.control as unknown as Control<IacCredentials>}
          />
        )}
        {providerType === "image" && (
          <ImageCredentialsForm
            control={form.control as unknown as Control<ImageCredentials>}
          />
        )}
        {providerType === "oraclecloud" && (
          <OracleCloudCredentialsForm
            control={form.control as unknown as Control<OCICredentials>}
          />
        )}
        {providerType === "mongodbatlas" && (
          <MongoDBAtlasCredentialsForm
            control={
              form.control as unknown as Control<MongoDBAtlasCredentials>
            }
          />
        )}
        {providerType === "alibabacloud" && effectiveVia === "role" && (
          <AlibabaCloudRoleCredentialsForm
            control={
              form.control as unknown as Control<AlibabaCloudCredentialsRole>
            }
          />
        )}
        {providerType === "alibabacloud" && effectiveVia !== "role" && (
          <AlibabaCloudStaticCredentialsForm
            control={
              form.control as unknown as Control<AlibabaCloudCredentials>
            }
          />
        )}
        {providerType === "cloudflare" && effectiveVia === "api_token" && (
          <CloudflareApiTokenCredentialsForm
            control={
              form.control as unknown as Control<CloudflareTokenCredentials>
            }
          />
        )}
        {providerType === "cloudflare" && effectiveVia === "api_key" && (
          <CloudflareApiKeyCredentialsForm
            control={
              form.control as unknown as Control<CloudflareApiKeyCredentials>
            }
          />
        )}
        {providerType === "openstack" && (
          <OpenStackCredentialsForm
            control={form.control as unknown as Control<OpenStackCredentials>}
          />
        )}
        {providerType === "googleworkspace" && (
          <GoogleWorkspaceCredentialsForm
            control={
              form.control as unknown as Control<GoogleWorkspaceCredentials>
            }
          />
        )}
        {providerType === "vercel" && (
          <VercelCredentialsForm
            control={form.control as unknown as Control<VercelCredentials>}
          />
        )}
        {providerType === "okta" && (
          <OktaCredentialsForm
            control={form.control as unknown as Control<OktaCredentials>}
          />
        )}

        {!hideActions && (
          <div className="flex w-full justify-end gap-4">
            {showBackButton && requiresBackButton(effectiveVia) && (
              <Button
                type="button"
                variant="ghost"
                size="lg"
                onClick={handleBackStep}
                disabled={isLoading}
              >
                {!isLoading && <ChevronLeftIcon size={24} />}
                Back
              </Button>
            )}
            <Button
              type="submit"
              variant="default"
              size="lg"
              disabled={isLoading}
            >
              {isLoading ? (
                <Loader2 className="animate-spin" />
              ) : (
                <ChevronRightIcon size={24} />
              )}
              {isLoading ? "Loading" : submitButtonText}
            </Button>
          </div>
        )}
      </form>
    </Form>
  );
};
