"""Phaxor — Matrix Engine (Python port)"""
import math

def solve_matrix(inputs: dict) -> dict | None:
    """Matrix Calculator."""
    op = inputs.get('operation', 'det')
    mat_a = inputs.get('matA', [])
    mat_b = inputs.get('matB', [])
    scalar = float(inputs.get('scalar', 1))

    if not mat_a: return {'error': 'Matrix A required'}

    def make_mat(r, c): return [[0]*c for _ in range(r)]

    try:
        r_a, c_a = len(mat_a), len(mat_a[0])
        
        if op == 'add':
            if not mat_b or len(mat_b) != r_a or len(mat_b[0]) != c_a: return {'error': 'Dim mismatch'}
            return {'matrix': [[mat_a[i][j] + mat_b[i][j] for j in range(c_a)] for i in range(r_a)]}
        
        if op == 'sub':
            if not mat_b or len(mat_b) != r_a or len(mat_b[0]) != c_a: return {'error': 'Dim mismatch'}
            return {'matrix': [[mat_a[i][j] - mat_b[i][j] for j in range(c_a)] for i in range(r_a)]}

        if op == 'mul':
            if not mat_b: return {'error': 'Matrix B required'}
            r_b, c_b = len(mat_b), len(mat_b[0])
            if c_a != r_b: return {'error': 'Dim mismatch for mult'}
            res = make_mat(r_a, c_b)
            for i in range(r_a):
                for j in range(c_b):
                    for k in range(c_a):
                        res[i][j] += mat_a[i][k] * mat_b[k][j]
            return {'matrix': res}

        if op == 'det':
            if r_a != c_a: return {'error': 'Must be square'}
            
            def det_rec(m):
                n = len(m)
                if n == 1: return m[0][0]
                if n == 2: return m[0][0]*m[1][1] - m[0][1]*m[1][0]
                d = 0
                for c in range(n):
                    sub = [row[:c] + row[c+1:] for row in m[1:]]
                    d += (1 if c%2==0 else -1) * m[0][c] * det_rec(sub)
                return d
            
            return {'scalar': det_rec(mat_a)}

        if op == 'transpose':
            return {'matrix': [[mat_a[j][i] for j in range(r_a)] for i in range(c_a)]}

        if op == 'rank':
            # Simple rank via Gaussian
            A = [row[:] for row in mat_a]
            rows, cols = len(A), len(A[0])
            rank = 0
            for c in range(cols):
                if rank >= rows: break
                pivot = rank
                while pivot < rows and abs(A[pivot][c]) < 1e-10: pivot += 1
                if pivot >= rows: continue
                
                A[rank], A[pivot] = A[pivot], A[rank]
                val = A[rank][c]
                A[rank] = [x/val for x in A[rank]]
                
                for i in range(rows):
                    if i != rank:
                        fac = A[i][c]
                        A[i] = [A[i][x] - fac * A[rank][x] for x in range(cols)]
                rank += 1
            return {'rank': rank}

    except Exception as e:
        return {'error': str(e)}
    
    return None
