import { Button } from "@/components/ui/button";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";

import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { useToast } from "@/components/ui/use-toast";

import {
  SSLProvider as SSLProviderType,
  SSLProviderSetting,
  Setting,
} from "@/domain/settings";
import { getErrMessage } from "@/lib/error";
import { cn } from "@/lib/utils";

import { getSetting, update } from "@/repository/settings";
import { zodResolver } from "@hookform/resolvers/zod";

import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";

import { z } from "zod";

const SSLProvider = () => {
  const { t } = useTranslation();

  const formSchema = z.object({
    provider: z.enum(["letsencrypt", "zerossl"], {
      message: t("setting.ca.not.empty"),
    }),
    eabKid: z.string().optional(),
    eabHmacKey: z.string().optional(),
  });

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      provider: "letsencrypt",
    },
  });

  const [provider, setProvider] = useState("letsencrypt");

  const [config, setConfig] = useState<Setting>();

  const { toast } = useToast();

  useEffect(() => {
    const fetchData = async () => {
      const setting = await getSetting("ssl-provider");

      if (setting) {
        setConfig(setting);
        const content = setting.content as SSLProviderSetting;

        form.setValue("provider", content.provider);
        form.setValue("eabKid", content.config[content.provider].eabKid);
        form.setValue(
          "eabHmacKey",
          content.config[content.provider].eabHmacKey
        );
        setProvider(content.provider);
      } else {
        form.setValue("provider", "letsencrypt");
        setProvider("letsencrypt");
      }
    };
    fetchData();
  }, []);

  const getOptionCls = (val: string) => {
    if (provider === val) {
      return "border-primary";
    }

    return "";
  };

  const onSubmit = async (values: z.infer<typeof formSchema>) => {
    if (values.provider === "zerossl") {
      if (!values.eabKid) {
        form.setError("eabKid", {
          message: t("setting.ca.eab_kid_hmac_key.not.empty"),
        });
      }
      if (!values.eabHmacKey) {
        form.setError("eabHmacKey", {
          message: t("setting.ca.eab_kid_hmac_key.not.empty"),
        });
      }
      if (!values.eabKid || !values.eabHmacKey) {
        return;
      }
    }

    const setting: Setting = {
      id: config?.id,
      name: "ssl-provider",
      content: {
        provider: values.provider,
        config: {
          letsencrypt: {},
          zerossl: {
            eabKid: values.eabKid ?? "",
            eabHmacKey: values.eabHmacKey ?? "",
          },
        },
      },
    };

    try {
      await update(setting);
      toast({
        title: t("update.succeed"),
        description: t("update.succeed"),
      });
    } catch (e) {
      const message = getErrMessage(e);
      toast({
        title: t("update.failed"),
        description: message,
        variant: "destructive",
      });
    }
  };

  return (
    <>
      <div className="w-full md:max-w-[35em]">
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onSubmit)}
            className="space-y-8 dark:text-stone-200"
          >
            <FormField
              control={form.control}
              name="provider"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{t("ca")}</FormLabel>
                  <FormControl>
                    <RadioGroup
                      {...field}
                      className="flex"
                      onValueChange={(val) => {
                        setProvider(val);
                        form.setValue("provider", val as SSLProviderType);
                      }}
                      value={provider}
                    >
                      <div className="flex items-center space-x-2">
                        <RadioGroupItem value="letsencrypt" id="letsencrypt" />
                        <Label htmlFor="letsencrypt">
                          <div
                            className={cn(
                              "flex items-center space-x-2 border p-2 rounded cursor-pointer",
                              getOptionCls("letsencrypt")
                            )}
                          >
                            <img
                              src={"/imgs/providers/letsencrypt.svg"}
                              className="h-6"
                            />
                            <div>{"Let's Encrypt"}</div>
                          </div>
                        </Label>
                      </div>
                      <div className="flex items-center space-x-2">
                        <RadioGroupItem value="zerossl" id="zerossl" />
                        <Label htmlFor="zerossl">
                          <div
                            className={cn(
                              "flex items-center space-x-2 border p-2 rounded cursor-pointer",
                              getOptionCls("zerossl")
                            )}
                          >
                            <img
                              src={"/imgs/providers/zerossl.svg"}
                              className="h-6"
                            />
                            <div>{"ZeroSSL"}</div>
                          </div>
                        </Label>
                      </div>
                    </RadioGroup>
                  </FormControl>

                  <FormField
                    control={form.control}
                    name="eabKid"
                    render={({ field }) => (
                      <FormItem hidden={provider !== "zerossl"}>
                        <FormLabel>EAB_KID</FormLabel>
                        <FormControl>
                          <Input
                            placeholder={t("setting.ca.eab_kid.not.empty")}
                            {...field}
                            type="text"
                          />
                        </FormControl>

                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="eabHmacKey"
                    render={({ field }) => (
                      <FormItem hidden={provider !== "zerossl"}>
                        <FormLabel>EAB_HMAC_KEY</FormLabel>
                        <FormControl>
                          <Input
                            placeholder={t("setting.ca.eab_hmac_key.not.empty")}
                            {...field}
                            type="text"
                          />
                        </FormControl>

                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="flex justify-end">
              <Button type="submit">{t("setting.submit")}</Button>
            </div>
          </form>
        </Form>
      </div>
    </>
  );
};

export default SSLProvider;
