import { zodResolver } from '@hookform/resolvers/zod'
import { useParams } from 'common'
import { useEffect } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
  Button,
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogSection,
  DialogTitle,
  Form,
  FormControl,
  FormField,
  Input,
  Separator,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import * as z from 'zod'

import { InlineLink } from '@/components/ui/InlineLink'
import { useCreateThirdPartyAuthIntegrationMutation } from '@/data/third-party-auth/integration-create-mutation'

interface CreateClerkAuthIntegrationProps {
  visible: boolean
  prod?: boolean
  onClose: () => void
  // TODO: Remove this if this Dialog is only used for creating.
  onDelete: () => void
}

const FORM_ID = 'create-firebase-auth-integration-form'

const FormSchema = z
  .object({
    enabled: z.boolean(),
    domain: z.string(),
  })
  .superRefine((val, ctx) => {
    if (
      !val.domain.match(/https:\/\/clerk([.][a-z0-9-]+){2,}\/?/) &&
      !val.domain.match(/https:\/\/[a-z0-9-]+[.]clerk[.]accounts[.]dev\/?$/)
    ) {
      ctx.addIssue({
        code: z.ZodIssueCode.invalid_string,
        path: ['domain'],
        message:
          'Production Clerk domains use HTTPS and start with the clerk subdomain (https://clerk.example.com). Development Clerk domains use HTTPS and end with .clerk.accounts.dev (https://example.clerk.accounts.dev).',
        validation: 'regex',
      })
    }
  })

export const CreateClerkAuthIntegrationDialog = ({
  visible,
  onClose,
}: CreateClerkAuthIntegrationProps) => {
  const { ref: projectRef } = useParams()
  const { mutate: createAuthIntegration, isPending } = useCreateThirdPartyAuthIntegrationMutation({
    onSuccess: () => {
      toast.success(`Successfully created a new Clerk integration.`)
      onClose()
    },
  })

  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema as any),
    defaultValues: {
      enabled: true,
      domain: '',
    },
  })

  useEffect(() => {
    if (visible) {
      form.reset({
        enabled: true,
        domain: '',
      })
      // the form input doesn't exist when the form is reset
      setTimeout(() => {
        form.setFocus('domain')
      }, 25)
    }
  }, [visible])

  const onSubmit: SubmitHandler<z.infer<typeof FormSchema>> = async (values) => {
    createAuthIntegration({
      projectRef: projectRef!,
      oidcIssuerUrl: values.domain,
    })
  }

  return (
    <Dialog open={visible} onOpenChange={() => onClose()}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle className="truncate">Add new Clerk connection</DialogTitle>
        </DialogHeader>

        <Separator />
        <DialogSection>
          <Form {...form}>
            <form id={FORM_ID} onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
              <p className="text-sm text-foreground-light">
                Register your Clerk domain. Visit{' '}
                <InlineLink
                  href="https://dashboard.clerk.com/setup/briven"
                  target="_blank"
                  rel="noopener"
                >
                  Clerk's Connect with Briven page
                </InlineLink>{' '}
                to configure your Clerk instance.
              </p>
              <FormField
                key="domain"
                control={form.control}
                name="domain"
                render={({ field }) => (
                  <FormItemLayout label="Clerk Domain">
                    <FormControl>
                      <Input
                        {...field}
                        placeholder={
                          'https://clerk.example.com or https://example.clerk.accounts.dev'
                        }
                      />
                    </FormControl>
                  </FormItemLayout>
                )}
              />
            </form>
          </Form>
        </DialogSection>
        <DialogFooter>
          <Button disabled={isPending} type="default" onClick={() => onClose()}>
            Cancel
          </Button>
          <Button form={FORM_ID} htmlType="submit" disabled={isPending} loading={isPending}>
            Create connection
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
