import { zodResolver } from '@hookform/resolvers/zod'
import { RadioGroupCard, RadioGroupCardItem } from '@ui/components/radio-group-card'
import { cn } from '@ui/lib/utils'
import { ChevronRight } from 'lucide-react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useMemo, useState } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
  Button,
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
  Form,
  FormField,
  Skeleton,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'

import { OrganizationCard } from '../OrganizationCard'
import AwsMarketplaceAutoRenewalWarning from './AwsMarketplaceAutoRenewalWarning'
import AwsMarketplaceOnboardingPlaceholder from './AwsMarketplaceOnboardingPlaceholder'
import AwsMarketplaceOnboardingSuccessModal from './AwsMarketplaceOnboardingSuccessModal'
import { useCloudMarketplaceOnboardingInfoQuery } from './cloud-marketplace-query'
import NewAwsMarketplaceOrgModal from './NewAwsMarketplaceOrgModal'
import {
  ScaffoldSection,
  ScaffoldSectionContent,
  ScaffoldSectionDetail,
} from '@/components/layouts/Scaffold'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import { useOrganizationLinkAwsMarketplaceMutation } from '@/data/organizations/organization-link-aws-marketplace-mutation'
import { DOCS_URL } from '@/lib/constants'
import type { Organization } from '@/types'

interface AwsMarketplaceLinkExistingOrgProps {
  organizations?: Organization[] | undefined
}

const FormSchema = z.object({
  orgSlug: z.string(),
})

type LinkExistingOrgForm = z.infer<typeof FormSchema>

export const AwsMarketplaceLinkExistingOrg = ({
  organizations,
}: AwsMarketplaceLinkExistingOrgProps) => {
  const router = useRouter()
  const {
    query: { buyer_id: buyerId },
  } = router

  const { data: onboardingInfo, isPending: isLoadingOnboardingInfo } =
    useCloudMarketplaceOnboardingInfoQuery({
      buyerId: buyerId as string,
    })

  const form = useForm<LinkExistingOrgForm>({
    resolver: zodResolver(FormSchema as any),
    defaultValues: {
      orgSlug: undefined,
    },
    mode: 'onBlur',
    reValidateMode: 'onChange',
  })

  const isDirty = !!Object.keys(form.formState.dirtyFields).length

  // Sort organizations by name ascending
  const sortedOrganizations = useMemo(() => {
    return organizations?.slice().sort((a, b) => a.name.localeCompare(b.name))
  }, [organizations])

  const { orgsLinkable, orgsNotLinkable } = useMemo(() => {
    const orgQualifiesForLinking = (org: Organization) => {
      const validationResult = onboardingInfo?.organization_linking_eligibility.find(
        (result) => result.slug === org.slug
      )

      return validationResult?.is_eligible ?? false
    }

    const linkable: Organization[] = []
    const notLinkable: Organization[] = []
    sortedOrganizations?.forEach((org) => {
      if (orgQualifiesForLinking(org)) {
        linkable.push(org)
      } else {
        notLinkable.push(org)
      }
    })
    return { orgsLinkable: linkable, orgsNotLinkable: notLinkable }
  }, [sortedOrganizations, onboardingInfo?.organization_linking_eligibility])

  const [isNotLinkableOrgListOpen, setIsNotLinkableOrgListOpen] = useState(false)
  const [orgLinkedSuccessfully, setOrgLinkedSuccessfully] = useState(false)
  const [showOrgCreationDialog, setShowOrgCreationDialog] = useState(false)
  const [orgToRedirectTo, setOrgToRedirectTo] = useState('')

  const { mutate: linkOrganization, isPending: isLinkingOrganization } =
    useOrganizationLinkAwsMarketplaceMutation({
      onSuccess: (_) => {
        //TODO(thomas): send tracking event?
        setOrgLinkedSuccessfully(true)
        setOrgToRedirectTo(form.getValues('orgSlug'))
      },
      onError: (res) => {
        toast.error(res.message, {
          duration: 7_000,
        })
      },
    })

  const onSubmit: SubmitHandler<LinkExistingOrgForm> = async (values) => {
    linkOrganization({ slug: values.orgSlug, buyerId: buyerId as string })
  }

  return (
    <>
      {onboardingInfo &&
        !onboardingInfo.aws_contract_auto_renewal &&
        !onboardingInfo.aws_contract_is_private_offer && (
          <AwsMarketplaceAutoRenewalWarning
            awsContractEndDate={onboardingInfo.aws_contract_end_date}
            awsContractSettingsUrl={onboardingInfo.aws_contract_settings_url}
          />
        )}
      {isLoadingOnboardingInfo ? (
        <AwsMarketplaceOnboardingPlaceholder />
      ) : (
        <ScaffoldSection>
          <ScaffoldSectionDetail className="text-base">
            <>
              <p>
                You’ve subscribed to the Briven{' '}
                {onboardingInfo?.plan_name_selected_on_marketplace} Plan via the AWS Marketplace. As
                a final step, you need to link a Briven organization to that subscription. Select
                the organization you want to be managed and billed through AWS.
              </p>

              <p>
                You can read more on billing through AWS in our {''}
                <Link
                  href={`${DOCS_URL}/guides/platform/aws-marketplace`}
                  target="_blank"
                  className="underline"
                >
                  Billing Docs.
                </Link>
              </p>

              <p className="mt-10">
                <span className="font-bold text-foreground-light">Want to start fresh?</span> Create
                a new organization and it will be linked automatically.
              </p>
              <Button
                size="tiny"
                htmlType="submit"
                type="primary"
                onClick={async (e) => {
                  e.preventDefault()
                  setShowOrgCreationDialog(true)
                }}
              >
                Create organization
              </Button>
            </>
          </ScaffoldSectionDetail>

          <ScaffoldSectionContent className="lg:ml-10">
            <Form {...form}>
              <form className="flex flex-col">
                <FormField
                  name="orgSlug"
                  control={form.control}
                  render={({ field }) => (
                    <RadioGroupCard
                      {...field}
                      defaultValue={field.value}
                      onValueChange={(value: string) => {
                        form.setValue('orgSlug', value, {
                          shouldDirty: true,
                          shouldValidate: false,
                        })
                      }}
                    >
                      <FormItemLayout id={field.name}>
                        <div className={'grid gap-4 grid-cols-1'}>
                          {isLoadingOnboardingInfo ? (
                            Array(3)
                              .fill(0)
                              .map((_, i) => (
                                <Skeleton key={i} className="w-full h-[110px] rounded-md" />
                              ))
                          ) : (
                            <>
                              <p className="font-bold text-foreground-light">
                                Organizations that can be linked
                              </p>
                              {orgsLinkable.length === 0 ? (
                                <p className="text-sm text-foreground-light">
                                  None of your organizations can be linked to your AWS Marketplace
                                  subscription at the moment.
                                </p>
                              ) : (
                                orgsLinkable.map((org) => (
                                  <RadioGroupCardItem
                                    id={org.slug}
                                    key={org.slug}
                                    showIndicator={false}
                                    value={org.slug}
                                    className={cn(
                                      'relative text-sm text-left flex flex-col gap-0 p-0 [&_label]:w-full group w-full'
                                    )}
                                    label={
                                      <OrganizationCard
                                        key={org.id}
                                        isLink={false}
                                        organization={org}
                                      />
                                    }
                                  />
                                ))
                              )}
                            </>
                          )}
                        </div>
                      </FormItemLayout>
                    </RadioGroupCard>
                  )}
                />
              </form>
            </Form>

            {orgsNotLinkable.length > 0 && !isLoadingOnboardingInfo && (
              <Collapsible
                className="-space-y-px"
                open={isNotLinkableOrgListOpen || orgsLinkable.length === 0}
                onOpenChange={() => setIsNotLinkableOrgListOpen((prev) => !prev)}
              >
                <CollapsibleTrigger className="py-2 w-full flex items-center group justify-between">
                  <p className="text-xs font-bold text-foreground-light">
                    Organizations that can't be linked
                  </p>
                  <ChevronRight
                    size={16}
                    className="text-foreground-lighter transition-all group-data-open:rotate-90"
                    strokeWidth={1}
                  />
                </CollapsibleTrigger>
                <CollapsibleContent
                  className={cn(
                    'flex flex-col gap-4 transition-all',
                    'data-closed:animate-collapsible-up data-open:animate-collapsible-down'
                  )}
                >
                  <p className="text-foreground-light text-xs">
                    The following organizations can’t be linked to your AWS Marketplace subscription
                    at the moment. This may be due to missing permissions, outstanding invoices, or
                    an existing marketplace link. If you'd like to link one of these organizations,
                    please review the organization settings. You need to be Owner or Administrator
                    of the organization to link it.
                  </p>
                  <div className="text-sm text-left flex flex-col gap-4 p-0 [&_label]:w-full group] w-full opacity-60">
                    {orgsNotLinkable.map((org) => (
                      <OrganizationCard
                        isLink={false}
                        key={org.id}
                        organization={org}
                        className="cursor-not-allowed"
                      />
                    ))}
                  </div>
                </CollapsibleContent>
              </Collapsible>
            )}

            <div className={cn('flex gap-3 justify-end')}>
              <ButtonTooltip
                size="medium"
                htmlType="submit"
                type="primary"
                onClick={async () => {
                  await onSubmit(form.getValues())
                }}
                loading={isLinkingOrganization}
                disabled={!isDirty || isLinkingOrganization || isLoadingOnboardingInfo}
                tooltip={{
                  content: {
                    side: 'top',
                    text: !isDirty ? 'No organization selected' : undefined,
                  },
                }}
              >
                Link organization
              </ButtonTooltip>
            </div>
          </ScaffoldSectionContent>
        </ScaffoldSection>
      )}

      <AwsMarketplaceOnboardingSuccessModal
        visible={orgLinkedSuccessfully}
        onClose={() => {
          setOrgLinkedSuccessfully(false)
          router.push(`/org/${orgToRedirectTo}`)
        }}
      />

      <NewAwsMarketplaceOrgModal
        visible={showOrgCreationDialog}
        onClose={() => setShowOrgCreationDialog(false)}
        buyerId={buyerId as string}
        onSuccess={(newlyCreatedOrgSlug) => {
          setShowOrgCreationDialog(false)
          setOrgToRedirectTo(newlyCreatedOrgSlug)
          setOrgLinkedSuccessfully(true)
        }}
      />
    </>
  )
}
