from abc import ABC, abstractmethod
from decimal import Decimal
from enum import Enum
from typing import Any, Dict, List, Union
from datetime import datetime


class BaseBitableFieldType(ABC):
    @abstractmethod
    def escape_out(self, value: Any) -> Any:
        pass

    @abstractmethod
    def escape_in(self, value: Any) -> Any:
        pass


class TextBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: str) -> str:
        return value

    def escape_in(self, value: Any) -> str:
        if not isinstance(value, list) or len(value) == 0:
            raise ValueError("TextBitableFieldType escape_in value must be list")

        for item in value:
            if not isinstance(item, dict):
                continue
            return item.get("text", "")
        return ""


class StringBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: str) -> str:
        return value

    def escape_in(self, value: Any) -> str:
        if not isinstance(value, str):
            raise ValueError("StringBitableFieldType escape_in value must be str")
        return value


class DateBitableFieldType(BaseBitableFieldType):
    _date_formats = [
        "%Y-%m-%d",  # yyyy-MM-dd
        "%Y-%m-%d %H:%M:%S",  # yyyy-MM-dd HH:mm:ss
        "%Y-%m-%dT%H:%M:%S%z",  # ISO format with timezone
    ]

    def escape_out(self, value: str) -> int:
        if not isinstance(value, str):
            raise ValueError("DateBitableFieldType escape_out value must be str")

        for fmt in self._date_formats:
            try:
                dt = datetime.strptime(value, fmt)
                return int(dt.timestamp() * 1000)
            except ValueError:
                continue

        raise ValueError(
            f"DateBitableFieldType escape_out cannot parse date string: {value}"
        )

    def escape_in(self, value: Any) -> str:
        if not isinstance(value, int):
            raise ValueError("DateBitableFieldType escape_in value must be int")
        dt = datetime.fromtimestamp(value / 1000)
        return dt.strftime(self._date_formats[1])  # 使用 yyyy-mm-dd hh:mm:ss 格式


class UserBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: str) -> List[Dict[str, str]]:
        return [{"id": str(value)}]

    def escape_in(self, value: Any) -> str:
        if not isinstance(value, list) or len(value) == 0:
            raise ValueError("UserBitableFieldType escape_in value must be list")
        for item in value:
            if not isinstance(item, dict):
                continue
            return item.get("id", "")
        return ""


class IntBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: int) -> int:
        if not isinstance(value, int):
            raise ValueError("IntBitableFieldType escape_out value must be int")
        return value

    def escape_in(self, value: Any) -> int:
        if not isinstance(value, int):
            raise ValueError("IntBitableFieldType escape_in value must be int")
        return value


class FloatBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: float) -> float:
        if not isinstance(value, float):
            raise ValueError("FloatBitableFieldType escape_out value must be float")
        return value

    def escape_in(self, value: Any) -> float:
        if not isinstance(value, float):
            raise ValueError("FloatBitableFieldType escape_in value must be float")
        return value


class DecimalBitableFieldType(BaseBitableFieldType):
    def escape_out(self, value: Decimal) -> float:
        if not isinstance(value, Decimal):
            raise ValueError("DecimalBitableFieldType escape_out value must be Decimal")
        return float(value)

    def escape_in(self, value: float) -> Decimal:
        if not isinstance(value, (int, float, str)):
            raise ValueError(
                "DecimalBitableFieldType escape_in value must be number or string"
            )
        try:
            return Decimal(str(value))
        except:
            raise ValueError(
                "DecimalBitableFieldType escape_in value must be valid decimal"
            )


class BitableFieldType(Enum):
    """多维表格字段类型枚举

    TEXT: 文本类型，转出：string -> [{text, type}]，转入：[{text, link, type}] -> string
    STRING: 字符串类型，转出：string -> string，转入：string -> string
    INT: 整数类型，转出：int -> int，转入：int -> int
    FLOAT: 浮点数类型，转出：float -> float，转入：float -> float
    DECIMAL: 高精度数字类型，转出：str -> str，转入：str -> str
    DATE: 日期类型，转出：string -> timestamp_in_ms，转入：timestamp_in_ms -> string
    USER: 用户类型，转出：string -> [{user_id}]，转入：[{user_id}] -> string
    """

    TEXT = TextBitableFieldType()
    STRING = StringBitableFieldType()
    INT = IntBitableFieldType()
    FLOAT = FloatBitableFieldType()
    DECIMAL = DecimalBitableFieldType()
    DATE = DateBitableFieldType()
    USER = UserBitableFieldType()
