import React, { Component, Fragment } from 'react'
import PropTypes from 'prop-types'
import copyTextToClipboard from 'copy-text-to-clipboard'

import { Link } from 'react-router-dom'
import { format } from 'date-fns'
import { observer, inject } from 'mobx-react'
import {
  Avatar,
  Button,
  Divider,
  Popconfirm,
  Table,
  Tooltip,
  notification
} from 'lib/antd'

import { Section } from '../Section'

import API from 'lib/api'
import theme from 'lib/theme'

import styles from './styles.module.css'

@inject('auth')
@observer
export class ProfileSection extends Component {
  static propTypes = {
    auth: PropTypes.object.isRequired
  }

  state = {
    copiedTextToClipboard: false,
    isLoadingUnsubscribe: false,
    isLoadingRefreshAuthToken: false
  }

  componentWillUnmount() {
    if (this._copyTimeout) {
      clearTimeout(this._copyTimeout)
      this._copyTimeout = null
    }
  }

  render() {
    const { auth, ...rest } = this.props

    const {
      copiedTextToClipboard,
      isLoadingUnsubscribe,
      isLoadingRefreshAuthToken
    } = this.state

    const hasSubscription =
      auth.consumer &&
      auth.consumer.enabled &&
      auth.consumer.plan &&
      auth.consumer.plan !== 'free'

    const columns = [
      {
        title: 'Avatar',
        dataIndex: 'image',
        render: (image) =>
          image ? (
            <Avatar src={image} className={theme(styles, 'avatar')} />
          ) : (
            <Avatar icon='user' className={theme(styles, 'avatar')} />
          )
      },
      {
        title: 'Username',
        dataIndex: 'username'
      },
      {
        title: 'Email',
        dataIndex: 'email'
      },
      {
        title: 'Joined',
        dataIndex: 'joined',
        render: (date) => format(new Date(date), 'MM/dd/yyyy')
      },
      {
        title: 'Subscription',
        dataIndex: 'subscription',
        render: (subscription) => <Link to='/pricing'>{subscription}</Link>
      },
      /*
      hasSubscription && {
        title: 'Subscribed',
        dataIndex: 'subscribed',
        render: (date) => (
          date ? format(new Date(date), 'MM/dd/yyyy') : ''
        )
      },
      */
      {
        title: 'Auth Token',
        key: 'token',
        render: (token) =>
          auth.consumer?.enabled &&
          auth.consumer?.token && (
            <Tooltip
              placement='top'
              title={copiedTextToClipboard ? 'Copied!' : 'Copy to clipboard'}
            >
              <Button type='primary' ghost onClick={this._onClickCopyToken}>
                {`${auth.consumer.token.substr(0, 8)} ...`}
              </Button>
            </Tooltip>
          )
      },
      {
        title: 'Actions',
        key: 'actions',
        render: (token) => (
          <Fragment>
            {auth.consumer?.enabled && auth.consumer?.token && (
              <Fragment>
                <Button
                  type='ghost'
                  icon='reload'
                  loading={isLoadingRefreshAuthToken}
                  onClick={this._onClickRefreshAuthToken}
                  block
                >
                  Refresh Token
                </Button>

                <Divider
                  type='horizontal'
                  style={{ marginTop: 8, marginBottom: 8 }}
                />
              </Fragment>
            )}

            {hasSubscription ? (
              <Popconfirm
                placement='top'
                title='Are you sure you want to cancel your subscription?'
                okText='Yes'
                cancelText='No'
                onConfirm={this._onConfirmUnsubscribe}
              >
                <Button type='default' loading={isLoadingUnsubscribe} block>
                  Cancel
                </Button>
              </Popconfirm>
            ) : (
              <Button type='primary' href='/pricing' block>
                Upgrade
              </Button>
            )}
          </Fragment>
        )
      }
    ].filter(Boolean)

    const dataSource = [
      {
        id: auth.user.id,
        username: auth.user.username,
        email: auth.user.email,
        image: auth.user.image,
        joined: auth.user.createdAt,
        subscription: hasSubscription
          ? auth.consumer.plan
          : auth.consumer && auth.consumer.enabled && auth.consumer.plan
          ? auth.consumer.plan
          : 'none',
        subscribed: auth.consumer?.createdAt
      }
    ]

    return (
      <Section id='profile' title='Profile' {...rest}>
        <div className={theme(styles, 'body')}>
          <Table
            columns={columns}
            rowKey={(record) => record.id}
            dataSource={dataSource}
            pagination={false}
          />
        </div>
      </Section>
    )
  }

  _onClickCopyToken = () => {
    const { token } = this.props.auth.consumer
    copyTextToClipboard(token)

    this.setState({ copiedTextToClipboard: true })
    this._clearCopyTimeout()
    this._copyTimeout = setTimeout(this._onCopyTimeout, 3000)
  }

  _onCopyTimeout = () => {
    this._clearCopyTimeout()
    this.setState({ copiedTextToClipboard: false })
  }

  _clearCopyTimeout = () => {
    if (this._copyTimeout) {
      clearTimeout(this._copyTimeout)
      this._copyTimeout = null
    }
  }

  _onConfirmUnsubscribe = () => {
    this.setState({ isLoadingUnsubscribe: true })

    API.removeConsumer(this.props.auth.consumer).then(
      () => {
        this.props.auth.consumer = null

        notification.success({
          message: 'Subscription canceled',
          duration: 0,
          description: (
            <span>
              <p>
                Your subscription has been canceled. If you have any pending
                charges, they will be billed at the end of the current billing
                cycle.
              </p>

              <p>It may take a few minutes for this change to take effect.</p>
            </span>
          )
        })

        this.setState({ isLoadingUnsubscribe: false })
      },
      (err) => {
        console.warn(err)

        notification.error({
          message: 'Error canceling subscription',
          description: err?.response?.data?.error || err.error?.message,
          duration: 0
        })

        this.setState({ isLoadingUnsubscribe: false })
      }
    )
  }

  _onClickRefreshAuthToken = () => {
    this.setState({ isLoadingRefreshAuthToken: true })

    API.updateConsumer(this.props.auth.consumer).then(
      (consumer) => {
        this.props.auth.consumer = consumer

        notification.success({
          message: 'Auth token refreshed',
          description: (
            <span>
              <p>
                Your auth token has been refreshed. Your old token is now
                invalid.
              </p>

              <p>It may take a few minutes for this change to take effect.</p>
            </span>
          )
        })

        this.setState({ isLoadingRefreshAuthToken: false })
      },
      (err) => {
        console.warn(err)

        notification.error({
          message: 'Error refreshing auth token',
          description: err?.response?.data?.error || err.error?.message,
          duration: 0
        })

        this.setState({ isLoadingRefreshAuthToken: false })
      }
    )
  }
}
