import React, { useState } from 'react';
import { css, Box, HTMLCoralProps, Link } from 'coral-system';
import { Checkbox, Popconfirm, Tooltip } from 'antd';
import { CodeOutlined, CollapsePanel, ToggleButton } from '@music163/tango-ui';
import { isString } from '@music163/tango-helpers';
import { WarningOutlined } from '@ant-design/icons';

export interface FormControlProps extends Omit<FormLabelProps, 'type'> {
  visible: boolean;
  extra?: React.ReactNode;
  footer?: React.ReactNode;
  error?: string;
  children?: React.ReactNode;
}

export function FormControl({
  visible,
  label,
  note,
  tip,
  docs,
  extra,
  deprecated,
  footer,
  error,
  children,
  ...rest
}: FormControlProps) {
  return (
    <Box className="FormControl" display={visible ? 'block' : 'none'} {...rest}>
      <Box display="flex" justifyContent="space-between" alignItems="center" mb="s">
        <FormLabel label={label} note={note} tip={tip} docs={docs} deprecated={deprecated} />
        {extra}
      </Box>
      <Box>{children}</Box>
      {footer}
      {!!error && (
        <Box mt="m" color="red" fontSize="12px">
          {error}
        </Box>
      )}
    </Box>
  );
}

const formControlGroupContentStyle = css`
  > .FormControlGroup {
    border-style: solid;
    border-width: 1px;
  }
`;

export interface FormControlGroupProps extends FormLabelProps {
  error?: string;
  extra?: React.ReactNode;
  children?: React.ReactNode;
  /**
   * 勾选变化时的回调
   */
  onCheck?: (checked: boolean) => void;
  /**
   * 是否勾选
   */
  checked?: boolean;
}

export function FormControlGroup({
  label,
  note,
  tip,
  docs,
  error,
  extra,
  children,
  onCheck,
  checked,
}: FormControlGroupProps) {
  // 默认折叠
  const [collapsed, setCollapsed] = useState(true);
  return (
    <CollapsePanel
      collapsed={collapsed}
      onCollapse={setCollapsed}
      className="FormControlGroup"
      stickyHeader
      title={
        <Box display="flex" columnGap="s">
          <Checkbox
            checked={checked}
            onChange={(e) => {
              e.stopPropagation();
              const nextChecked = e.target.checked;
              setCollapsed(!nextChecked);
              onCheck?.(nextChecked);
            }}
          />
          <FormLabel label={label} note={note} tip={tip} docs={docs} />
        </Box>
      }
      extra={
        <Box flex="1" textAlign="right">
          {extra}
        </Box>
      }
      border="solid"
      borderColor="line.normal"
      headerProps={{
        bg: 'fill1',
        zIndex: 2,
      }}
    >
      <Box
        p="m"
        display="flex"
        flexDirection="column"
        rowGap="l"
        css={formControlGroupContentStyle}
      >
        {children}
      </Box>
      <Box color="red">{error}</Box>
    </CollapsePanel>
  );
}

const labelStyle = css`
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 160px;
  vertical-align: bottom;
  user-select: none;

  &.hasHelp {
    border-bottom: 1px dashed var(--tango-colors-text-normal);
  }
`;

const tipStyle = css`
  a {
    text-decoration: underline;
  }

  a:link {
    color: #fff;
  }
`;

interface FormLabelProps extends HTMLCoralProps<'div'> {
  /**
   * 标签
   */
  label?: string;
  /**
   * 备注
   */
  note?: string;
  /**
   * 冒泡信息
   */
  tip?: string;
  /**
   * 文档地址
   */
  docs?: string;
  /**
   * 是否显示废弃标记
   */
  // eslint-disable-next-line react/no-unused-prop-types
  deprecated?: boolean | string;
}

function FormLabel({ label, note, tip, docs, deprecated, ...rest }: FormLabelProps) {
  let help: React.ReactNode;
  if (deprecated || docs) {
    help = (
      <Box>
        <Box css={tipStyle}>
          {tip}
          {docs ? (
            <Link href={docs} isExternal ml="m">
              查看属性文档
            </Link>
          ) : null}
        </Box>
        {deprecated ? (
          <Box color="#faad14">
            <WarningOutlined /> 废弃提示：
            {isString(deprecated) ? deprecated : '该属性已废弃，请谨慎使用。'}
          </Box>
        ) : null}
      </Box>
    );
  } else {
    help = tip;
  }

  let labelNode = (
    <Box
      as="span"
      display="inline-block"
      color="text2"
      className={help ? 'hasHelp' : ''}
      css={labelStyle}
      title={isString(label) ? label : undefined}
    >
      {deprecated ? <WarningOutlined style={{ color: '#faad14', marginRight: 4 }} /> : null}
      {label}
    </Box>
  );

  if (help) {
    labelNode = <Tooltip title={help}>{labelNode}</Tooltip>;
  }

  return (
    <Box fontSize="14px" {...rest}>
      {labelNode}
      {note && (
        <Box as="i" display="inline-block" fontSize="12px" color="text3" ml="m">
          {note}
        </Box>
      )}
    </Box>
  );
}

interface FieldSetProps {
  title?: React.ReactNode;
  extra?: React.ReactNode;
  children?: React.ReactNode;
}

export function FieldSet({ title, extra, children }: FieldSetProps) {
  return (
    <CollapsePanel title={title} extra={extra}>
      <Box px="m">{children}</Box>
    </CollapsePanel>
  );
}

interface FormHeaderProps {
  title?: React.ReactNode;
  subTitle?: React.ReactNode;
  extra?: React.ReactNode;
}

export function FormHeader({ title, extra, subTitle }: FormHeaderProps) {
  return (
    <Box className="FormHeader">
      <Box display="flex" alignItems="center" className="FormHeaderMain">
        <Box flex="1" display="flex" alignItems="center" className="FormHeaderMainBody">
          <Box
            fontSize="16px"
            fontWeight="500"
            mr="s"
            whiteSpace="nowrap"
            className="FormHeaderTitle"
            textOverflow="ellipsis"
            overflow="hidden"
          >
            {title}
          </Box>
          {subTitle && <Box className="FormHeaderSubTitle">{subTitle}</Box>}
        </Box>
        {extra && <Box className="FormHeaderExtra">{extra}</Box>}
      </Box>
    </Box>
  );
}

export interface ToggleCodeButtonProps {
  /**
   * 在反选时是否需要用户确认操作
   */
  confirm?: boolean;
  selected: boolean;
  onToggle: () => void;
}

export function ToggleCodeButton({ confirm, selected, onToggle }: ToggleCodeButtonProps) {
  if (confirm && selected) {
    return (
      <Popconfirm
        title="当前代码在切换模式后可能会解析失败，是否确认切换？"
        color="#fff2f0"
        onConfirm={(e) => {
          e.stopPropagation();
          onToggle?.();
        }}
        onCancel={(e) => {
          e.stopPropagation();
        }}
      >
        <div
          onClick={(e) => {
            e.stopPropagation();
          }}
        >
          <ToggleButton
            borderRadius="s"
            size="s"
            shape="text"
            type="primary"
            tooltip={selected ? undefined : '使用 JS 表达式'}
            tooltipPlacement="left"
            selected={selected}
          >
            <CodeOutlined />
          </ToggleButton>
        </div>
      </Popconfirm>
    );
  }

  return (
    <ToggleButton
      borderRadius="s"
      size="s"
      shape="text"
      type="primary"
      tooltip={selected ? '关闭 JS 表达式' : '使用 JS 表达式'}
      tooltipPlacement="left"
      selected={selected}
      onClick={(e) => {
        e.stopPropagation();
        onToggle?.();
      }}
    >
      <CodeOutlined />
    </ToggleButton>
  );
}
