import React, { useState } from 'react';
import { connect } from 'react-redux';

import Component from '@reactions/component';
import { css } from 'glamor';

import { rolloverBudget } from 'loot-core/src/client/queries';
import * as monthUtils from 'loot-core/src/shared/months';

import * as actions from '../../../../../loot-core/src/client/actions';
import { colors, styles } from '../../../style';
import DotsHorizontalTriple from '../../../svg/v1/DotsHorizontalTriple';
import ArrowButtonDown1 from '../../../svg/v2/ArrowButtonDown1';
import ArrowButtonUp1 from '../../../svg/v2/ArrowButtonUp1';
import {
  View,
  Block,
  Button,
  Tooltip,
  Menu,
  HoverTarget,
  AlignedText
} from '../../common';
import NotesButton from '../../NotesButton';
import CellValue from '../../spreadsheet/CellValue';
import format from '../../spreadsheet/format';
import NamespaceContext from '../../spreadsheet/NamespaceContext';
import SheetValue from '../../spreadsheet/SheetValue';
import { MONTH_BOX_SHADOW } from '../constants';

import HoldTooltip from './HoldTooltip';
import { useRollover } from './RolloverContext';
import TransferTooltip from './TransferTooltip';

function TotalsList({ prevMonthName, collapsed }) {
  return (
    <View
      style={[
        {
          flexDirection: 'row',
          lineHeight: 1.5,
          justifyContent: 'center'
        },
        !collapsed && {
          padding: '5px 0',
          marginTop: 17,
          backgroundColor: colors.n11,
          borderTopWidth: 1,
          borderBottomWidth: 1,
          borderColor: colors.n9
        },
        collapsed && {
          padding: 7
        },
        styles.smallText
      ]}
    >
      <View
        style={{
          textAlign: 'right',
          marginRight: 10,
          minWidth: 50
        }}
      >
        <HoverTarget
          style={{ flexShrink: 0 }}
          renderContent={() => (
            <Tooltip
              width={200}
              style={{ lineHeight: 1.5, padding: '6px 10px' }}
            >
              <AlignedText
                left="Income:"
                right={
                  <CellValue
                    binding={rolloverBudget.totalIncome}
                    type="financial"
                  />
                }
              />
              <AlignedText
                left="From Last Month:"
                right={
                  <CellValue
                    binding={rolloverBudget.fromLastMonth}
                    type="financial"
                  />
                }
              />
            </Tooltip>
          )}
        >
          <CellValue
            binding={rolloverBudget.incomeAvailable}
            type="financial"
            style={{ fontWeight: 600 }}
          />
        </HoverTarget>

        <CellValue
          binding={rolloverBudget.lastMonthOverspent}
          formatter={value => {
            let v = format(value, 'financial');
            return value > 0 ? '+' + v : value === 0 ? '-' + v : v;
          }}
          style={[{ fontWeight: 600 }, styles.tnum]}
        />

        <CellValue
          binding={rolloverBudget.totalBudgeted}
          formatter={value => {
            let v = format(value, 'financial');
            return value > 0 ? '+' + v : value === 0 ? '-' + v : v;
          }}
          style={[{ fontWeight: 600 }, styles.tnum]}
        />

        <CellValue
          binding={rolloverBudget.forNextMonth}
          formatter={value => {
            let n = parseInt(value) || 0;
            let v = format(Math.abs(n), 'financial');
            return n >= 0 ? '-' + v : '+' + v;
          }}
          style={[{ fontWeight: 600 }, styles.tnum]}
        />
      </View>

      <View>
        <Block>Available Funds</Block>
        <Block>Overspent in {prevMonthName}</Block>
        <Block>Budgeted</Block>
        <Block>For Next Month</Block>
      </View>
    </View>
  );
}

function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
  return (
    <SheetValue binding={rolloverBudget.toBudget} initialValue={0}>
      {node => {
        const availableValue = parseInt(node.value);
        const num = isNaN(availableValue) ? 0 : availableValue;
        const isNegative = num < 0;

        return (
          <View style={{ alignItems: 'center' }}>
            <Block>{isNegative ? 'Overbudgeted:' : 'To Budget:'}</Block>
            <Component initialState={{ menuOpen: null }}>
              {({ state, setState }) => (
                <View>
                  <HoverTarget
                    disabled={!collapsed || state.menuOpen}
                    renderContent={() => (
                      <Tooltip position="bottom-center">
                        <TotalsList
                          collapsed={true}
                          prevMonthName={prevMonthName}
                        />
                      </Tooltip>
                    )}
                  >
                    <Block
                      onClick={() => setState({ menuOpen: 'actions' })}
                      data-cellname={node.name}
                      {...css([
                        styles.veryLargeText,
                        {
                          fontWeight: 400,
                          userSelect: 'none',
                          cursor: 'pointer',
                          color: isNegative ? colors.r4 : colors.p5,
                          marginBottom: -1,
                          borderBottom: '1px solid transparent',
                          ':hover': {
                            borderColor: isNegative ? colors.r4 : colors.p5
                          }
                        }
                      ])}
                    >
                      {format(num, 'financial')}
                    </Block>
                  </HoverTarget>
                  {state.menuOpen === 'actions' && (
                    <Tooltip
                      position="bottom-center"
                      width={200}
                      style={{ padding: 0 }}
                      onClose={() => setState({ menuOpen: null })}
                    >
                      <Menu
                        onMenuSelect={type => {
                          if (type === 'reset-buffer') {
                            onBudgetAction(month, 'reset-hold');
                            setState({ menuOpen: null });
                          } else {
                            setState({ menuOpen: type });
                          }
                        }}
                        items={[
                          {
                            name: 'transfer',
                            text: 'Move to a category'
                          },
                          {
                            name: 'buffer',
                            text: 'Hold for next month'
                          },
                          {
                            name: 'reset-buffer',
                            text: "Reset next month's buffer"
                          }
                        ]}
                      />
                    </Tooltip>
                  )}
                  {state.menuOpen === 'buffer' && (
                    <HoldTooltip
                      onClose={() => setState({ menuOpen: null })}
                      onSubmit={amount => {
                        onBudgetAction(month, 'hold', { amount });
                      }}
                    />
                  )}
                  {state.menuOpen === 'transfer' && (
                    <TransferTooltip
                      initialAmount={availableValue}
                      onClose={() => setState({ menuOpen: null })}
                      onSubmit={(amount, category) => {
                        onBudgetAction(month, 'transfer-available', {
                          amount,
                          category
                        });
                      }}
                    />
                  )}
                </View>
              )}
            </Component>
          </View>
        );
      }}
    </SheetValue>
  );
}

function BudgetSummary({ month, localPrefs }) {
  let {
    currentMonth,
    summaryCollapsed: collapsed,
    onBudgetAction,
    onToggleSummaryCollapse
  } = useRollover();

  let [menuOpen, setMenuOpen] = useState(false);
  function onMenuOpen(e) {
    setMenuOpen(true);
  }

  function onMenuClose(bag) {
    setMenuOpen(false);
  }

  let prevMonthName = monthUtils.format(monthUtils.prevMonth(month), 'MMM');

  let ExpandOrCollapseIcon = collapsed ? ArrowButtonDown1 : ArrowButtonUp1;

  let goalTemplatesEnabled = localPrefs['flags.goalTemplatesEnabled'];

  return (
    <View
      style={{
        backgroundColor: 'white',
        boxShadow: MONTH_BOX_SHADOW,
        borderRadius: 6,
        marginLeft: 0,
        marginRight: 0,
        marginTop: 5,
        flex: 1,
        cursor: 'default',
        marginBottom: 5,
        overflow: 'hidden',
        '& .hover-visible': {
          opacity: 0,
          transition: 'opacity .25s'
        },
        '&:hover .hover-visible': {
          opacity: 1
        }
      }}
    >
      <NamespaceContext.Provider value={monthUtils.sheetForMonth(month)}>
        <View
          style={[
            { padding: '0 13px' },
            collapsed ? { margin: '10px 0' } : { marginTop: 16 }
          ]}
        >
          <View
            style={{
              position: 'absolute',
              left: 10,
              top: 0
            }}
          >
            <Button
              className="hover-visible"
              bare
              onClick={onToggleSummaryCollapse}
            >
              <ExpandOrCollapseIcon
                width={13}
                height={13}
                // The margin is to make it the exact same size as the dots button
                style={{ color: colors.n6, margin: 1 }}
              />
            </Button>
          </View>

          <div
            {...css([
              {
                textAlign: 'center',
                marginTop: 3,
                fontSize: 18,
                fontWeight: 500,
                textDecorationSkip: 'ink'
              },
              currentMonth === month && { textDecoration: 'underline' }
            ])}
          >
            {monthUtils.format(month, 'MMMM')}
          </div>

          <View
            style={{
              position: 'absolute',
              right: 10,
              top: 0,
              flexDirection: 'row',
              alignItems: 'center'
            }}
          >
            <View>
              <NotesButton
                id={`budget-${month}`}
                width={15}
                height={15}
                tooltipPosition="bottom-right"
                defaultColor={colors.n6}
              />
            </View>
            <View style={{ userSelect: 'none', marginLeft: 2 }}>
              <Button bare onClick={onMenuOpen}>
                <DotsHorizontalTriple
                  width={15}
                  height={15}
                  style={{ color: colors.n5 }}
                />
              </Button>
              {menuOpen && (
                <Tooltip
                  position="bottom-right"
                  width={200}
                  style={{ padding: 0 }}
                  onClose={onMenuClose}
                >
                  <Menu
                    onMenuSelect={type => {
                      onMenuClose();
                      onBudgetAction(month, type);
                    }}
                    items={[
                      { name: 'copy-last', text: "Copy last month's budget" },
                      { name: 'set-zero', text: 'Set budgets to zero' },
                      {
                        name: 'set-3-avg',
                        text: 'Set budgets to 3 month avg'
                      },
                      goalTemplatesEnabled && {
                        name: 'apply-goal-template',
                        text: 'Apply budget template'
                      },
                      goalTemplatesEnabled && {
                        name: 'overwrite-goal-template',
                        text: 'Overwrite with budget template'
                      }
                    ]}
                  />
                </Tooltip>
              )}
            </View>
          </View>
        </View>

        {collapsed ? (
          <View
            style={{
              alignItems: 'center',
              padding: '10px 20px',
              justifyContent: 'space-between',
              backgroundColor: colors.n11,
              borderTop: '1px solid ' + colors.n10
            }}
          >
            <ToBudget
              collapsed={collapsed}
              prevMonthName={prevMonthName}
              month={month}
              onBudgetAction={onBudgetAction}
            />
          </View>
        ) : (
          <>
            <TotalsList prevMonthName={prevMonthName} />
            <View style={{ margin: '23px 0' }}>
              <ToBudget month={month} onBudgetAction={onBudgetAction} />
            </View>
          </>
        )}
      </NamespaceContext.Provider>
    </View>
  );
}

export default connect(
  state => ({ localPrefs: state.prefs.local }),
  actions
)(BudgetSummary);