from typing import Iterable, Any, Union, Tuple
from vector import *
from sys import path
from os.path import abspath, dirname

path.append(dirname(abspath("")))

from Scalar import Scalar


# the_2D 矩阵类
class Matrix2D:
    """二维矩阵类（2x2）"""

    def __init__(self, data: Iterable[Vector2D] = None) -> None:
        if data is None:
            # 使用基向量初始化单位矩阵
            data_list = [base_vector2D_i, base_vector2D_j]
        else:
            data_list = list(data)
            if len(data_list) != 2 or not all(isinstance(v, Vector2D) for v in data_list):
                raise TypeError('data必须是包含两个Vector2D实例的可迭代对象')
        self.rows = data_list  # 存储两行向量

    @property
    def i(self) -> Vector2D:
        return self.rows[0]

    @property
    def j(self) -> Vector2D:
        return self.rows[1]

    def det(self) -> Scalar:
        """计算矩阵行列式"""
        return self.i.x * self.j.y - self.i.y * self.j.x

    def __mul__(self, other: 'Matrix2D') -> 'Matrix2D':
        if not isinstance(other, Matrix2D):
            raise TypeError("只能与Matrix2D类型相乘")
        # 矩阵乘法：行×列
        row1 = Vector2D(
            self.i.x * other.i.x + self.i.y * other.j.x,
            self.i.x * other.i.y + self.i.y * other.j.y
        )
        row2 = Vector2D(
            self.j.x * other.i.x + self.j.y * other.j.x,
            self.j.x * other.i.y + self.j.y * other.j.y
        )
        return Matrix2D([row1, row2])

    def __str__(self) -> str:
        return f"Matrix2D({self.i}, {self.j})"

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

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

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

    def transpose(self) -> 'Matrix2D':
        """矩阵转置"""
        return Matrix2D([
            Vector2D(self.i.x, self.j.x),
            Vector2D(self.i.y, self.j.y)
        ])

    def multiply_vector(self, vec: Vector2D) -> Vector2D:
        """矩阵与向量相乘"""
        if not isinstance(vec, Vector2D):
            raise TypeError("只能与Vector2D类型相乘")
        return Vector2D(
            self.i.x * vec.x + self.j.x * vec.y,
            self.i.y * vec.x + self.j.y * vec.y
        )

    def __iter__(self):
        yield from self.rows


# the_2D 单位矩阵
base_Matrix2D = Matrix2D()


def create_matrix2D(rows: Union[Tuple[Vector2D, Vector2D], Tuple[Scalar, Scalar, Scalar, Scalar]]) -> Matrix2D:
    """创建二维矩阵的工厂函数"""
    if isinstance(rows[0], Vector2D) and isinstance(rows[1], Vector2D):
        return Matrix2D(rows)
    elif len(rows) == 4 and all(isinstance(x, Scalar) for x in rows):
        return Matrix2D([
            Vector2D(rows[0], rows[1]),
            Vector2D(rows[2], rows[3])
        ])
    else:
        raise TypeError("输入必须是两个Vector2D或四个Scalar的元组")