import { CopyToClipboard } from "react-copy-to-clipboard";
import { useFormState } from "react-use-form-state";
import { Flex } from "reflexbox/styled-components";
import React, { useState } from "react";
import styled from "styled-components";
import getConfig from "next/config";
import DatePicker from "react-datepicker";
import { switchProp, prop, ifProp } from "styled-tools";

import { useStoreActions, useStoreState } from "../store";
import { Checkbox, Select, TextInput } from "./Input";
import { Col, RowCenterH, RowCenter } from "./Layout";
import { useMessage, useCopy } from "../hooks";
import { removeProtocol } from "../utils";
import Text, { H1, Span } from "./Text";
import { Link } from "../store/links";
import Animation from "./Animation";
import { Colors } from "../consts";
import Icon from "./Icon";

const { publicRuntimeConfig } = getConfig();

const SubmitIconWrapper = styled.div`
  content: "";
  position: absolute;
  // top: 0;
  right: 12px;
  
  height: 70%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  padding: 10px;
  
  border-radius: 10px;

  background: ${switchProp(prop("color", "blue"), {
    // blue: "linear-gradient(to right, #42a5f5, #2979ff)",
    blue: "linear-gradient(to right, #8bc43f, #53a472)",
  })};

  svg {
    fill: white;
  }
  :hover svg {
    fill: #1b82a5;
  }
  @media only screen and (max-width: 448px) {
    right: 8px;
    width: 40px;
  }
`;

const ShortenedLink = styled(H1)`
  cursor: "pointer";
  border-bottom: 1px dotted ${Colors.StatsTotalUnderline};
  cursor: pointer;

  :hover {
    opacity: 0.8;
  }
`;

const Footnote = styled.small`
  margin-top: 5px;
  font-style: italic;
  opacity: 0.5;
`;

const DatePick = styled(DatePicker)`
  position: relative;
  box-sizing: border-box;
  letter-spacing: 0.05em;
  color: #444;
  background-color: white;
  box-shadow: 0 10px 35px hsla(200, 15%, 70%, 0.2);
  border: none;
  border-radius: 5px;
  transition: all 0.5s ease-out;
  width: 100%;
  height: 44px;
  padding-left: 24px;
  padding-right: 24px;
  font-size: 15px;

  :focus {
    outline: none;
    box-shadow: 0 20px 35px hsla(200, 15%, 70%, 0.4);
  }

  @media screen and (min-width: 52em) {
    letter-spacing: 0.1em;
    border-bottom-width: 6px;
  }
`;

interface Form {
  target: string;
  domain?: string;
  customurl?: string;
  password?: string;
  description?: string;
  expire_in?: string;
  showAdvanced?: boolean;
}

const defaultDomain = publicRuntimeConfig.DEFAULT_DOMAIN;

const Shortener = () => {
  const { isAuthenticated } = useStoreState(s => s.auth);
  const domains = useStoreState(s => s.settings.domains);
  const submit = useStoreActions(s => s.links.submit);
  const [link, setLink] = useState<Link | null>(null);
  const [message, setMessage] = useMessage(3000);
  const [loading, setLoading] = useState(false);
  const [copied, setCopied] = useCopy();
  var [startDate, setStartDate] = useState(null);
  const [formState, { raw, password, text, select, label }] = useFormState<
    Form
  >(
    { showAdvanced: false },
    {
      withIds: true,
      onChange(e, stateValues, nextStateValues) {
        if (stateValues.showAdvanced && !nextStateValues.showAdvanced) {
          formState.clear();
          formState.setField("target", stateValues.target);
          setStartDate(null);
        }
      }
    }
  );

  const submitLink = async (reCaptchaToken?: string) => {
    try {
      const link = await submit({ ...formState.values, reCaptchaToken });
      setLink(link);
      formState.clear();
    } catch (err) {
      setMessage(
        err?.response?.data?.error || "Couldn't create the short link."
      );
    }
    startDate = null;
    setLoading(false);
  };

  const onSubmit = async e => {
    e.preventDefault();
    if (loading) return;
    setCopied(false);
    setLoading(true);

    if (
      process.env.NODE_ENV === "production" &&
      !!publicRuntimeConfig.RECAPTCHA_SITE_KEY &&
      !isAuthenticated
    ) {
      window.grecaptcha.execute(window.captchaId);
      const getCaptchaToken = () => {
        setTimeout(() => {
          if (window.isCaptchaReady) {
            const reCaptchaToken = window.grecaptcha.getResponse(
              window.captchaId
            );
            window.isCaptchaReady = false;
            window.grecaptcha.reset(window.captchaId);
            return submitLink(reCaptchaToken);
          }
          return getCaptchaToken();
        }, 200);
      };
      return getCaptchaToken();
    }

    return submitLink();
  };

  const title = !link && (
    <H1 fontSize={[25, 27, 32]} light>
      Cut your links{" "}
      <Span style={{ borderBottom: "2px dotted #999" }} light>
        shorter
      </Span>
      .
    </H1>
  );

  const result = link && (
    <Animation
      as={RowCenter}
      offset="-20px"
      duration="0.4s"
      style={{ position: "relative" }}
    >
      {copied ? (
        <Animation offset="10px" duration="0.2s" alignItems="center">
          <Icon
            size={[30, 35]}
            py={0}
            px={0}
            mr={3}
            p={["4px", "5px"]}
            name="check"
            strokeWidth="3"
            stroke={Colors.CheckIcon}
          />
        </Animation>
      ) : (
        <Animation offset="-10px" duration="0.2s">
          <CopyToClipboard text={link.link} onCopy={setCopied}>
            <Icon
              as="button"
              py={0}
              px={0}
              mr={3}
              size={[30, 35]}
              p={["6px", "7px"]}
              name="copy"
              strokeWidth="2.5"
              stroke={Colors.CopyIcon}
              backgroundColor={Colors.CopyIconBg}
            />
          </CopyToClipboard>
        </Animation>
      )}
      <CopyToClipboard text={link.link} onCopy={setCopied}>
        <ShortenedLink fontSize={[24, 26, 30]} pb="2px" light>
          {removeProtocol(link.link)}
        </ShortenedLink>
      </CopyToClipboard>
    </Animation>
  );

  return (
    <Col width={800} maxWidth="100%" px={[3]} flex="0 0 auto" mt={4}>
      <RowCenterH mb={[4, 48]}>
        {title}
        {result}
      </RowCenterH>
      <Flex
        as="form"
        id="shortenerform"
        width={1}
        alignItems="center"
        justifyContent="center"
        style={{ position: "relative" }}
        onSubmit={onSubmit}
      >
        <TextInput
          {...text("target")}
          placeholder="Paste your long LINK"
          placeholderSize={[16, 17, 18]}
          fontSize={[18, 20, 22]}
          aria-label="target"
          width={1}
          height={[58, 64, 72]}
          px={0}
          pr={[48, 84]}
          pl={[32, 40]}
          autoFocus
          data-lpignore
        />
        <SubmitIconWrapper onClick={onSubmit} role="button" aria-label="submit">
          <Icon
            name={loading ? "spinner" : "scissor"}
            size={[12, 16, 18]}
            fill={loading ? "none" : "#aaa"}
            stroke={loading ? Colors.Spinner : "none"}
            mb={1}
            mr={1}
          />
          <Text color="white">SNIP</Text>
        </SubmitIconWrapper>
      </Flex>
      <Flex alignItems="center" mt={20}>
        <Text
          as="label"
          {...label("customurl")}
          fontSize={[16]}
          mr={1}
          mb={3}
          bold
        >
        {/* {formState.values.domain || defaultDomain}/{formState.values.customurl} */}
        {formState.values.domain || defaultDomain}/
        </Text>
        <Col mb={[3, 0]}>
          <TextInput
            {...text("customurl")}
            placeholder="Give it a custom name... or not"
            autocomplete="off"
            data-lpignore
            pl={[3, 24]}
            pr={[3, 24]}
            placeholderSize={[13, 14]}
            fontSize={[14, 15]}
            height={[40, 44]}
            width={[1, 210, 380]}
          />
          <Footnote>Leave empty to generate a simple, random URL</Footnote>
        </Col>
      </Flex>
      {message.text && (
        <Text color={message.color} mt={24} mb={1} textAlign="center">
          {message.text}
        </Text>
      )}
      <Checkbox
        {...raw({
          name: "showAdvanced",
          onChange: e => {
            if (!isAuthenticated) {
              setMessage(
                "You need to log in or sign up to use advanced options."
              );
              return false;
            }
            return !formState.values.showAdvanced;
          }
        })}
        checked={formState.values.showAdvanced}
        label="Show more customizable options"
        mt={[3, 24]}
        alignSelf="flex-start"
      />
      {formState.values.showAdvanced && (
        <div>
          <Footnote>The fields below are all optional</Footnote>
          <Flex mt={4} flexDirection={["column", "row"]}>
            <Col>
              <Text
                as="label"
                {...label("password")}
                fontSize={[14, 15]}
                mb={2}
                bold
              >
                Password:
              </Text>
              <TextInput
                {...password("password")}
                placeholder="Enter a Password..."
                autocomplete="off"
                data-lpignore
                pl={[3, 24]}
                pr={[3, 24]}
                placeholderSize={[13, 14]}
                fontSize={[14, 15]}
                height={[40, 44]}
                width={[1, 210, 240]}
              />
              <Footnote>Makes link password protected</Footnote>
            </Col>
            <Col mb={[3, 0]} ml={3}>
              <Text
                as="label"
                {...label("expire_in")}
                fontSize={[14, 15]}
                mb={2}
                bold
              >
                Expire on:
              </Text>
              <DatePick
                placeholder="2 minutes/hours/days"
                data-lpignore
                pl={[3, 24]}
                pr={[3, 24]}
                placeholderSize={[13, 14]}
                fontSize={[14, 15]}
                height={[40, 44]}
                width={[1, 210, 240]}
                maxWidth="100%"
                minDate={new Date()}
                selected={startDate}
                onChange={date => {setStartDate(date); formState.setField("expire_in", date);}}
                isClearable
              />
              <Footnote>Leave empty for no expiration</Footnote>
            </Col>
          </Flex>
          <Flex mt={[3]} flexDirection={["column", "row"]}>
            
            <Col width={[1, 2 / 3]}>
              <Text
                as="label"
                {...label("description")}
                fontSize={[14, 15]}
                mb={2}
                bold
              >
                Note:
              </Text>
              <TextInput
                {...text("description")}
                data-lpignore
                pl={[3, 24]}
                pr={[3, 24]}
                placeholderSize={[13, 14]}
                fontSize={[14, 15]}
                height={[40, 44]}
                width={1}
                maxWidth="100%"
              />
              <Footnote>For your personal reference</Footnote>
            </Col>
          </Flex>
        </div>
      )}
    </Col>
  );
};

export default Shortener;
