from the_2D.vector import Vector2D
from the_2D.matrix import Matrix2D
from Scalar import Scalar
from the_3D.vector import Vector3D
from the_3D.matrix import Matrix3D
from typing import Any

# 1x2 矩阵类 (1行2列)
class Matrix1x2:
    """1x2矩阵类（1行2列）"""

    def __init__(self, data: Vector2D = None) -> None:
        if data is None:
            # 初始化零矩阵
            self.row = Vector2D(Scalar(0), Scalar(0))
        else:
            if not isinstance(data, Vector2D):
                raise TypeError('data必须是Vector2D实例')
            self.row = data

        self.rows = 1
        self.cols = 2

    def __mul__(self, scalar: Scalar) -> 'Matrix1x2':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix1x2(self.row * scalar)

    def __rmul__(self, scalar: Scalar) -> 'Matrix1x2':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix1x2') -> 'Matrix1x2':
        """矩阵加法"""
        if not isinstance(other, Matrix1x2):
            raise TypeError("只能与Matrix1x2类型相加")
        return Matrix1x2(self.row + other.row)

    def __sub__(self, other: 'Matrix1x2') -> 'Matrix1x2':
        """矩阵减法"""
        if not isinstance(other, Matrix1x2):
            raise TypeError("只能与Matrix1x2类型相减")
        return Matrix1x2(self.row - other.row)

    def transpose(self) -> 'Matrix2x1':
        """矩阵转置（1x2 → 2x1）"""
        return Matrix2x1(
            Vector2D(self.row.x, Scalar(0)).x,  # 取x分量作为第一行
            Vector2D(self.row.y, Scalar(0)).x  # 取y分量作为第二行
        )

    def multiply_matrix(self, other: Matrix2D) -> 'Matrix1x2':
        """与2x2矩阵相乘（1x2 × 2x2 → 1x2）"""
        if not isinstance(other, Matrix2D):
            raise TypeError("只能与Matrix2D（2x2）类型相乘")
        return Matrix1x2(other.multiply_vector(self.row))

    def multiply_vector(self, vec: Vector2D) -> Scalar:
        """与2D向量相乘（点积）"""
        if not isinstance(vec, Vector2D):
            raise TypeError("只能与Vector2D类型相乘")
        return self.row.dot(vec)

    def __str__(self) -> str:
        return f"Matrix1x2({self.row.x}, {self.row.y})"

    def __repr__(self) -> str:
        return f"Matrix1x2(row={self.row!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix1x2):
            return False
        return self.row == other.row

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 1x3 矩阵类 (1行3列)
class Matrix1x3:
    """1x3矩阵类（1行3列）"""

    def __init__(self, data: Vector3D = None) -> None:
        if data is None:
            # 初始化零矩阵
            self.row = Vector3D(Scalar(0), Scalar(0), Scalar(0))
        else:
            if not isinstance(data, Vector3D):
                raise TypeError('data必须是Vector3D实例')
            self.row = data

        self.rows = 1
        self.cols = 3

    def __mul__(self, scalar: Scalar) -> 'Matrix1x3':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix1x3(self.row * scalar)

    def __rmul__(self, scalar: Scalar) -> 'Matrix1x3':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix1x3') -> 'Matrix1x3':
        """矩阵加法"""
        if not isinstance(other, Matrix1x3):
            raise TypeError("只能与Matrix1x3类型相加")
        return Matrix1x3(self.row + other.row)

    def __sub__(self, other: 'Matrix1x3') -> 'Matrix1x3':
        """矩阵减法"""
        if not isinstance(other, Matrix1x3):
            raise TypeError("只能与Matrix1x3类型相减")
        return Matrix1x3(self.row - other.row)

    def transpose(self) -> 'Matrix3x1':
        """矩阵转置（1x3 → 3x1）"""
        return Matrix3x1(
            Vector3D(self.row.x, Scalar(0), Scalar(0)).x,
            Vector3D(self.row.y, Scalar(0), Scalar(0)).x,
            Vector3D(self.row.z, Scalar(0), Scalar(0)).x
        )

    def multiply_matrix(self, other: 'Matrix3D') -> 'Matrix1x3':
        """与3x3矩阵相乘（1x3 × 3x3 → 1x3）"""
        if not isinstance(other, Matrix3D):
            raise TypeError("只能与Matrix3D（3x3）类型相乘")
        return Matrix1x3(other.multiply_vector(self.row))

    def multiply_vector(self, vec: Vector3D) -> Scalar:
        """与3D向量相乘（点积）"""
        if not isinstance(vec, Vector3D):
            raise TypeError("只能与Vector3D类型相乘")
        return self.row.dot(vec)

    def __str__(self) -> str:
        return f"Matrix1x3({self.row.x}, {self.row.y}, {self.row.z})"

    def __repr__(self) -> str:
        return f"Matrix1x3(row={self.row!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix1x3):
            return False
        return self.row == other.row

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 2x1 矩阵类 (2行1列)
class Matrix2x1:
    """2x1矩阵类（2行1列）"""

    def __init__(self, scalar1: Scalar, scalar2: Scalar) -> None:
        if not (isinstance(scalar1, Scalar) and isinstance(scalar2, Scalar)):
            raise TypeError("矩阵元素必须是Scalar类型")
        self.rows = [
            Vector2D(scalar1, Scalar(0)),  # 存储为Vector2D便于计算，只使用x分量
            Vector2D(scalar2, Scalar(0))
        ]
        self.rows_count = 2
        self.cols_count = 1

    def __mul__(self, scalar: Scalar) -> 'Matrix2x1':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix2x1(
            self.rows[0].x * scalar,
            self.rows[1].x * scalar
        )

    def __rmul__(self, scalar: Scalar) -> 'Matrix2x1':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix2x1') -> 'Matrix2x1':
        """矩阵加法"""
        if not isinstance(other, Matrix2x1):
            raise TypeError("只能与Matrix2x1类型相加")
        return Matrix2x1(
            self.rows[0].x + other.rows[0].x,
            self.rows[1].x + other.rows[1].x
        )

    def __sub__(self, other: 'Matrix2x1') -> 'Matrix2x1':
        """矩阵减法"""
        if not isinstance(other, Matrix2x1):
            raise TypeError("只能与Matrix2x1类型相减")
        return Matrix2x1(
            self.rows[0].x - other.rows[0].x,
            self.rows[1].x - other.rows[1].x
        )

    def transpose(self) -> 'Matrix1x2':
        """矩阵转置（2x1 → 1x2）"""
        return Matrix1x2(Vector2D(
            self.rows[0].x,
            self.rows[1].x
        ))

    def multiply_matrix(self, other: 'Matrix1x2') -> 'Matrix2D':
        """与1x2矩阵相乘（2x1 × 1x2 → 2x2）"""
        if not isinstance(other, Matrix1x2):
            raise TypeError("只能与Matrix1x2类型相乘")
        row1 = Vector2D(
            self.rows[0].x * other.row.x,
            self.rows[0].x * other.row.y
        )
        row2 = Vector2D(
            self.rows[1].x * other.row.x,
            self.rows[1].x * other.row.y
        )
        return Matrix2D([row1, row2])

    def __str__(self) -> str:
        return f"Matrix2x1(\n  {self.rows[0].x},\n  {self.rows[1].x}\n)"

    def __repr__(self) -> str:
        return f"Matrix2x1(rows={[r.x for r in self.rows]!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix2x1):
            return False
        return (self.rows[0].x == other.rows[0].x and
                self.rows[1].x == other.rows[1].x)

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 2x3 矩阵类 (2行3列)
class Matrix2x3:
    """2x3矩阵类（2行3列）"""

    def __init__(self, row1: Vector3D, row2: Vector3D) -> None:
        if not (isinstance(row1, Vector3D) and isinstance(row2, Vector3D)):
            raise TypeError("矩阵行必须是Vector3D实例")
        self.rows = [row1, row2]
        self.rows_count = 2
        self.cols_count = 3

    def __mul__(self, scalar: Scalar) -> 'Matrix2x3':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix2x3(
            self.rows[0] * scalar,
            self.rows[1] * scalar
        )

    def __rmul__(self, scalar: Scalar) -> 'Matrix2x3':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix2x3') -> 'Matrix2x3':
        """矩阵加法"""
        if not isinstance(other, Matrix2x3):
            raise TypeError("只能与Matrix2x3类型相加")
        return Matrix2x3(
            self.rows[0] + other.rows[0],
            self.rows[1] + other.rows[1]
        )

    def __sub__(self, other: 'Matrix2x3') -> 'Matrix2x3':
        """矩阵减法"""
        if not isinstance(other, Matrix2x3):
            raise TypeError("只能与Matrix2x3类型相减")
        return Matrix2x3(
            self.rows[0] - other.rows[0],
            self.rows[1] - other.rows[1]
        )

    def transpose(self) -> 'Matrix3x2':
        """矩阵转置（2x3 → 3x2）"""
        return Matrix3x2(
            Vector2D(self.rows[0].x, self.rows[1].x),
            Vector2D(self.rows[0].y, self.rows[1].y),
            Vector2D(self.rows[0].z, self.rows[1].z)
        )

    def multiply_matrix(self, other: 'Matrix3D') -> 'Matrix2x3':
        """与3x3矩阵相乘（2x3 × 3x3 → 2x3）"""
        if not isinstance(other, Matrix3D):
            raise TypeError("只能与Matrix3D（3x3）类型相乘")
        return Matrix2x3(
            other.multiply_vector(self.rows[0]),
            other.multiply_vector(self.rows[1])
        )

    def multiply_vector(self, vec: Vector3D) -> Vector2D:
        """与3D向量相乘（2x3 × 3x1 → 2x1向量）"""
        if not isinstance(vec, Vector3D):
            raise TypeError("只能与Vector3D类型相乘")
        return Vector2D(
            self.rows[0].dot(vec),
            self.rows[1].dot(vec)
        )

    def __str__(self) -> str:
        return f"Matrix2x3(\n  {self.rows[0]},\n  {self.rows[1]}\n)"

    def __repr__(self) -> str:
        return f"Matrix2x3(rows={self.rows!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix2x3):
            return False
        return self.rows == other.rows

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 3x1 矩阵类 (3行1列)
class Matrix3x1:
    """3x1矩阵类（3行1列）"""

    def __init__(self, scalar1: Scalar, scalar2: Scalar, scalar3: Scalar) -> None:
        if not (isinstance(scalar1, Scalar) and
                isinstance(scalar2, Scalar) and
                isinstance(scalar3, Scalar)):
            raise TypeError("矩阵元素必须是Scalar类型")
        self.rows = [
            Vector3D(scalar1, Scalar(0), Scalar(0)),  # 存储为Vector3D便于计算，只使用x分量
            Vector3D(scalar2, Scalar(0), Scalar(0)),
            Vector3D(scalar3, Scalar(0), Scalar(0))
        ]
        self.rows_count = 3
        self.cols_count = 1

    def __mul__(self, scalar: Scalar) -> 'Matrix3x1':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix3x1(
            self.rows[0].x * scalar,
            self.rows[1].x * scalar,
            self.rows[2].x * scalar
        )

    def __rmul__(self, scalar: Scalar) -> 'Matrix3x1':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix3x1') -> 'Matrix3x1':
        """矩阵加法"""
        if not isinstance(other, Matrix3x1):
            raise TypeError("只能与Matrix3x1类型相加")
        return Matrix3x1(
            self.rows[0].x + other.rows[0].x,
            self.rows[1].x + other.rows[1].x,
            self.rows[2].x + other.rows[2].x
        )

    def __sub__(self, other: 'Matrix3x1') -> 'Matrix3x1':
        """矩阵减法"""
        if not isinstance(other, Matrix3x1):
            raise TypeError("只能与Matrix3x1类型相减")
        return Matrix3x1(
            self.rows[0].x - other.rows[0].x,
            self.rows[1].x - other.rows[1].x,
            self.rows[2].x - other.rows[2].x
        )

    def transpose(self) -> 'Matrix1x3':
        """矩阵转置（3x1 → 1x3）"""
        return Matrix1x3(Vector3D(
            self.rows[0].x,
            self.rows[1].x,
            self.rows[2].x
        ))

    def multiply_matrix(self, other: 'Matrix1x3') -> 'Matrix3D':
        """与1x3矩阵相乘（3x1 × 1x3 → 3x3）"""
        if not isinstance(other, Matrix1x3):
            raise TypeError("只能与Matrix1x3类型相乘")
        row1 = Vector3D(
            self.rows[0].x * other.row.x,
            self.rows[0].x * other.row.y,
            self.rows[0].x * other.row.z
        )
        row2 = Vector3D(
            self.rows[1].x * other.row.x,
            self.rows[1].x * other.row.y,
            self.rows[1].x * other.row.z
        )
        row3 = Vector3D(
            self.rows[2].x * other.row.x,
            self.rows[2].x * other.row.y,
            self.rows[2].x * other.row.z
        )
        return Matrix3D([row1, row2, row3])

    def __str__(self) -> str:
        return f"Matrix3x1(\n  {self.rows[0].x},\n  {self.rows[1].x},\n  {self.rows[2].x}\n)"

    def __repr__(self) -> str:
        return f"Matrix3x1(rows={[r.x for r in self.rows]!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix3x1):
            return False
        return (self.rows[0].x == other.rows[0].x and
                self.rows[1].x == other.rows[1].x and
                self.rows[2].x == other.rows[2].x)

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 3x2 矩阵类 (3行2列)
class Matrix3x2:
    """3x2矩阵类（3行2列）"""

    def __init__(self, row1: Vector2D, row2: Vector2D, row3: Vector2D) -> None:
        if not (isinstance(row1, Vector2D) and
                isinstance(row2, Vector2D) and
                isinstance(row3, Vector2D)):
            raise TypeError("矩阵行必须是Vector2D实例")
        self.rows = [row1, row2, row3]
        self.rows_count = 3
        self.cols_count = 2

    def __mul__(self, scalar: Scalar) -> 'Matrix3x2':
        """矩阵与标量相乘"""
        if not isinstance(scalar, Scalar):
            raise TypeError("只能与Scalar类型相乘")
        return Matrix3x2(
            self.rows[0] * scalar,
            self.rows[1] * scalar,
            self.rows[2] * scalar
        )

    def __rmul__(self, scalar: Scalar) -> 'Matrix3x2':
        return self.__mul__(scalar)

    def __add__(self, other: 'Matrix3x2') -> 'Matrix3x2':
        """矩阵加法"""
        if not isinstance(other, Matrix3x2):
            raise TypeError("只能与Matrix3x2类型相加")
        return Matrix3x2(
            self.rows[0] + other.rows[0],
            self.rows[1] + other.rows[1],
            self.rows[2] + other.rows[2]
        )

    def __sub__(self, other: 'Matrix3x2') -> 'Matrix3x2':
        """矩阵减法"""
        if not isinstance(other, Matrix3x2):
            raise TypeError("只能与Matrix3x2类型相减")
        return Matrix3x2(
            self.rows[0] - other.rows[0],
            self.rows[1] - other.rows[1],
            self.rows[2] - other.rows[2]
        )

    def transpose(self) -> 'Matrix2x3':
        """矩阵转置（3x2 → 2x3）"""
        return Matrix2x3(
            Vector3D(self.rows[0].x, self.rows[1].x, self.rows[2].x),
            Vector3D(self.rows[0].y, self.rows[1].y, self.rows[2].y)
        )

    def multiply_matrix(self, other: 'Matrix2D') -> 'Matrix3x2':
        """与2x2矩阵相乘（3x2 × 2x2 → 3x2）"""
        if not isinstance(other, Matrix2D):
            raise TypeError("只能与Matrix2D（2x2）类型相乘")
        return Matrix3x2(
            other.multiply_vector(self.rows[0]),
            other.multiply_vector(self.rows[1]),
            other.multiply_vector(self.rows[2])
        )

    def multiply_vector(self, vec: Vector2D) -> Vector3D:
        """与2D向量相乘（3x2 × 2x1 → 3x1向量）"""
        if not isinstance(vec, Vector2D):
            raise TypeError("只能与Vector2D类型相乘")
        return Vector3D(
            self.rows[0].dot(vec),
            self.rows[1].dot(vec),
            self.rows[2].dot(vec)
        )

    def __str__(self) -> str:
        return f"Matrix3x2(\n  {self.rows[0]},\n  {self.rows[1]},\n  {self.rows[2]}\n)"

    def __repr__(self) -> str:
        return f"Matrix3x2(rows={self.rows!r})"

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, Matrix3x2):
            return False
        return self.rows == other.rows

    def __ne__(self, other: Any) -> bool:
        return not self.__eq__(other)


# 工厂函数：创建各种类型的矩阵
def create_matrix1x2(x: Scalar, y: Scalar) -> Matrix1x2:
    """创建1x2矩阵的工厂函数"""
    return Matrix1x2(Vector2D(x, y))


def create_matrix1x3(x: Scalar, y: Scalar, z: Scalar) -> Matrix1x3:
    """创建1x3矩阵的工厂函数"""
    return Matrix1x3(Vector3D(x, y, z))


def create_matrix2x1(a: Scalar, b: Scalar) -> Matrix2x1:
    """创建2x1矩阵的工厂函数"""
    return Matrix2x1(a, b)


def create_matrix2x3(row1: Vector3D, row2: Vector3D) -> Matrix2x3:
    """创建2x3矩阵的工厂函数"""
    return Matrix2x3(row1, row2)


def create_matrix3x1(a: Scalar, b: Scalar, c: Scalar) -> Matrix3x1:
    """创建3x1矩阵的工厂函数"""
    return Matrix3x1(a, b, c)


def create_matrix3x2(row1: Vector2D, row2: Vector2D, row3: Vector2D) -> Matrix3x2:
    """创建3x2矩阵的工厂函数"""
    return Matrix3x2(row1, row2, row3)