import { ESLintUtils } from '@typescript-eslint/utils'

const RE_HEX3 = /^#[0-9a-fA-F]{3}$/
const RE_HEX6 = /^#[0-9a-fA-F]{6}$/
const RE_HEX8 = /^#[0-9a-fA-F]{8}$/
const RE_RGB = /^rgb\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/
const RE_RGBA = /^rgba\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/
const RE_HSL = /^hsl\s*\(\s*\d+\s*,\s*[\d.]+%?\s*,\s*[\d.]+%?\s*\)$/

const ALLOWED_KEYWORDS = new Set([
  'inherit',
  'transparent',
  'currentColor',
  'none',
  'unset',
  'initial',
  'auto',
  'contain',
  'cover',
])

function isHardcodedColor(value) {
  if (typeof value !== 'string') return false

  const trimmed = value.trim()

  if (ALLOWED_KEYWORDS.has(trimmed.toLowerCase())) return false
  if (trimmed.startsWith('var(')) return false
  if (/^\d+(\.\d+)?px?$/.test(trimmed)) return false
  if (/^\d+(\.\d+)?\%$/.test(trimmed)) return false

  return (
    RE_HEX3.test(trimmed) ||
    RE_HEX6.test(trimmed) ||
    RE_HEX8.test(trimmed) ||
    RE_RGB.test(trimmed) ||
    RE_RGBA.test(trimmed) ||
    RE_HSL.test(trimmed)
  )
}

function extractStyleProperties(expression) {
  const properties = []

  if (expression.type === 'ObjectExpression' && expression.properties) {
    for (const styleProp of expression.properties) {
      if (
        styleProp.type === 'Property' &&
        styleProp.key?.type === 'Identifier' &&
        styleProp.value?.type === 'Literal' &&
        typeof styleProp.value.value === 'string'
      ) {
        properties.push({
          key: styleProp.key.name,
          value: styleProp.value.value,
          loc: styleProp.value.loc,
        })
      }
    }
  }

  return properties
}

export const RULE_NAME = 'no-hardcoded-color-in-style'

export default ESLintUtils.RuleCreator((name) => {
  return `https://eslint.dev/rules/#${name}`
})({
  name: 'no-hardcoded-color-in-style',
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow hardcoded color values in JSX style properties',
      recommended: false,
    },
    messages: {
      hardcodedColor:
        '硬编码的颜色值 "{{value}}" 不允许使用。请使用 TDesign CSS Token（如 var(--td-text-color-placeholder)）代替。',
    },
    schema: [],
  },
  create(context) {
    return {
      JSXAttribute(node) {
        if (
          node.name?.type === 'JSXIdentifier' &&
          node.name.name === 'style' &&
          node.value?.type === 'JSXExpressionContainer' &&
          node.value.expression
        ) {
          const styleProps = extractStyleProperties(node.value.expression)

          for (const prop of styleProps) {
            if (isHardcodedColor(prop.value)) {
              context.report({
                node: context.sourceCode.getLastToken(node),
                messageId: 'hardcodedColor',
                data: { value: prop.value },
              })
            }
          }
        }
      },
    }
  },
})
