import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { RainbowButton } from '../../components/rainbow-button';
import { useState } from 'react';
import {
  CopyWithTooltip,
  Dialog,
  ExternalLink,
  InputError,
  Intent,
  Tooltip,
  TradingAnchorButton,
  TradingButton,
  VegaIcon,
  VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { DApp, TokenStaticLinks, useLinks } from '@vegaprotocol/environment';
import { ABOUT_REFERRAL_DOCS_LINK } from './constants';
import { useIsInReferralSet, useReferral } from './hooks/use-referral';
import { useT } from '../../lib/use-t';
import { Link, Navigate, useNavigate } from 'react-router-dom';
import { Links, Routes } from '../../lib/links';
import { useReferralProgram } from './hooks/use-referral-program';
import { useReferralSetTransaction } from '../../lib/hooks/use-referral-set-transaction';
import { Trans } from 'react-i18next';

export const CreateCodeContainer = () => {
  const t = useT();
  const { pubKey, isReadOnly } = useVegaWallet();
  const isInReferralSet = useIsInReferralSet(pubKey);
  const openWalletDialog = useVegaWalletDialogStore(
    (store) => store.openVegaWalletDialog
  );

  // Navigate to the index page when already in the referral set.
  if (isInReferralSet) {
    return <Navigate to={Routes.REFERRALS} />;
  }

  return (
    <div
      data-testid="referral-create-code-form"
      className="md:w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg"
    >
      <h3 className="mb-4 text-2xl text-center calt">
        {t('Create a referral code')}
      </h3>
      <p className="mb-4 text-center text-base">
        {t(
          'Generate a referral code to share with your friends and access the commission benefits of the current program.'
        )}
      </p>

      <div className="w-full flex flex-col gap-4 items-stretch">
        {pubKey ? (
          <CreateCodeForm />
        ) : (
          <RainbowButton
            variant="border"
            disabled={isReadOnly}
            onClick={openWalletDialog}
          >
            {t('Connect wallet')}
          </RainbowButton>
        )}
      </div>
    </div>
  );
};

export const CreateCodeForm = () => {
  const t = useT();
  const navigate = useNavigate();
  const [dialogOpen, setDialogOpen] = useState(false);
  const { isReadOnly } = useVegaWallet();

  return (
    <>
      <Tooltip
        description={t(
          'Create a simple referral code to enjoy the referrer commission outlined in the current referral program'
        )}
      >
        <span>
          <RainbowButton
            variant="border"
            disabled={isReadOnly}
            onClick={() => setDialogOpen(true)}
            className="w-full"
          >
            {t('Create a referral code')}
          </RainbowButton>
        </span>
      </Tooltip>
      <Tooltip
        description={
          <Trans
            i18nKey={
              'Make your referral code a Team to compete in Competitions with your friends, appear in leaderboards on the <0>Competitions Homepage</0>, and earn rewards'
            }
            components={[
              <Link
                key="homepage-link"
                to={Links.COMPETITIONS()}
                className="underline"
              >
                Compeitionts Homepage
              </Link>,
            ]}
          />
        }
      >
        <span>
          <RainbowButton
            role="link"
            variant="border"
            disabled={isReadOnly}
            onClick={() => navigate(Links.COMPETITIONS_CREATE_TEAM())}
            className="w-full"
          >
            {t('Create a team')}
          </RainbowButton>
        </span>
      </Tooltip>
      <p className="text-xs">
        <Link className="underline" to={Links.COMPETITIONS()}>
          {t('Go to competitions')}
        </Link>
      </p>
      <Dialog
        title={t('Create a referral code')}
        open={dialogOpen}
        onChange={() => setDialogOpen(false)}
        size="small"
      >
        <CreateCodeDialog setDialogOpen={setDialogOpen} />
      </Dialog>
    </>
  );
};

const CreateCodeDialog = ({
  setDialogOpen,
}: {
  setDialogOpen: (open: boolean) => void;
}) => {
  const t = useT();
  const createLink = useLinks(DApp.Governance);
  const { pubKey } = useVegaWallet();
  const { refetch } = useReferral({ pubKey, role: 'referrer' });
  const {
    err,
    code,
    status,
    stakeAvailable: currentStakeAvailable,
    requiredStake,
    onSubmit,
  } = useReferralSetTransaction();

  const { details: programDetails } = useReferralProgram();

  const getButtonProps = () => {
    if (status === 'idle') {
      return {
        children: t('Generate code'),
        onClick: () => onSubmit({ createReferralSet: { isTeam: false } }),
      };
    }

    if (status === 'requested') {
      return {
        children: t('Confirm in wallet...'),
        disabled: true,
      };
    }

    if (status === 'pending') {
      return {
        children: t('Waiting for transaction...'),
        disabled: true,
      };
    }

    if (status === 'confirmed') {
      return {
        children: t('Close'),
        intent: Intent.Success,
        onClick: () => {
          refetch();
          setDialogOpen(false);
        },
      };
    }
  };

  if (!pubKey || currentStakeAvailable == null || requiredStake == null) {
    return (
      <div className="flex flex-col gap-4">
        <p>{t('You must be connected to the Vega wallet.')}</p>
        <TradingButton
          intent={Intent.Primary}
          onClick={() => setDialogOpen(false)}
        >
          {t('Close')}
        </TradingButton>
      </div>
    );
  }

  if (currentStakeAvailable < requiredStake) {
    return (
      <div className="flex flex-col gap-4">
        <p>
          {t(
            'You need at least {{requiredStake}} VEGA staked to generate a referral code and participate in the referral program.',
            {
              requiredStake: addDecimalsFormatNumber(
                requiredStake.toString(),
                18
              ),
            }
          )}
        </p>
        <TradingAnchorButton
          href={createLink(TokenStaticLinks.ASSOCIATE)}
          intent={Intent.Primary}
          target="_blank"
        >
          {t('Stake some $VEGA now')}
        </TradingAnchorButton>
      </div>
    );
  }

  if (!programDetails) {
    return (
      <div className="flex flex-col gap-4">
        {(status === 'idle' ||
          status === 'requested' ||
          status === 'pending' ||
          err) && (
          <>
            {
              <p>
                {t(
                  'There is currently no referral program active, are you sure you want to create a code?'
                )}
              </p>
            }
          </>
        )}
        {status === 'confirmed' && code && (
          <div className="flex items-center gap-2">
            <div className="flex-1 min-w-0 p-2 text-sm rounded bg-vega-clight-700 dark:bg-vega-cdark-700">
              <p className="overflow-hidden whitespace-nowrap text-ellipsis">
                {code}
              </p>
            </div>
            <CopyWithTooltip text={code}>
              <TradingButton
                className="text-sm no-underline"
                icon={<VegaIcon name={VegaIconNames.COPY} />}
              >
                <span>{t('Copy')}</span>
              </TradingButton>
            </CopyWithTooltip>
          </div>
        )}
        <TradingButton
          fill={true}
          intent={Intent.Primary}
          onClick={() => onSubmit({ createReferralSet: { isTeam: false } })}
          {...getButtonProps()}
        >
          {t('Yes')}
        </TradingButton>
        {status === 'idle' && (
          <TradingButton
            fill={true}
            intent={Intent.Primary}
            onClick={() => {
              refetch();
              setDialogOpen(false);
            }}
          >
            {t('No')}
          </TradingButton>
        )}
        {err && <InputError>{err}</InputError>}
        <div className="flex justify-center pt-5 mt-2 text-sm border-t gap-4 text-default border-default">
          <ExternalLink href={ABOUT_REFERRAL_DOCS_LINK}>
            {t('About the referral program')}
          </ExternalLink>
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      {(status === 'idle' ||
        status === 'requested' ||
        status === 'pending' ||
        err) && (
        <p>
          {t(
            'Generate a referral code to share with your friends and access the commission benefits of the current program.'
          )}
        </p>
      )}
      {status === 'confirmed' && code && (
        <div className="flex items-center gap-2">
          <div className="flex-1 min-w-0 p-2 text-sm rounded bg-vega-clight-700 dark:bg-vega-cdark-700">
            <p className="overflow-hidden whitespace-nowrap text-ellipsis">
              {code}
            </p>
          </div>
          <CopyWithTooltip text={code}>
            <TradingButton
              className="text-sm no-underline"
              icon={<VegaIcon name={VegaIconNames.COPY} />}
            >
              <span>{t('Copy')}</span>
            </TradingButton>
          </CopyWithTooltip>
        </div>
      )}
      <TradingButton
        fill={true}
        intent={Intent.Primary}
        {...getButtonProps()}
      />
      {err && <InputError>{err}</InputError>}
      <div className="flex justify-center pt-5 mt-2 text-sm border-t gap-4 text-default border-default">
        <ExternalLink href={ABOUT_REFERRAL_DOCS_LINK}>
          {t('About the referral program')}
        </ExternalLink>
      </div>
    </div>
  );
};