import math

def solve_isolated_footing(inputs):
    try:
        Pv = float(inputs.get('P', 0))
        Mv = float(inputs.get('M', 0))
        sbcv = float(inputs.get('sbc', 150))
        colBv = float(inputs.get('colB', 300))
        colDv = float(inputs.get('colD', 300))
        fck = float(inputs.get('fck', 0))
        fy = float(inputs.get('fy', 0))
        barDia = float(inputs.get('barDia', 12))

        if Pv == 0 or fck == 0 or fy == 0 or sbcv == 0:
            return {'error': 'Invalid input parameters'}

        totalP = Pv * 1.1
        Areq = totalP / sbcv
        sideReq = math.sqrt(Areq)

        # Round up to nearest 50mm
        B = math.ceil(sideReq * 1000 / 50) * 50
        L = B
        Afoot = (B / 1000) * (L / 1000)

        qu = (1.5 * Pv) / Afoot

        actualPressure = totalP / Afoot
        sbcOk = actualPressure <= sbcv

        e = Mv / Pv if Pv > 0 else 0
        eMax = L / 6000

        cantilever = (B - colBv) / 2
        tauC = 0.25 * math.sqrt(fck)

        d = max(cantilever * 0.4, 200)

        for _ in range(5):
            Vu = qu * (B / 1000) * ((cantilever - d) / 1000)
            if d > 0:
                vu = (Vu * 1000) / (B * d)
                if vu > tauC:
                    d = d * 1.2
            else:
                 d = 100 # safe default

        d = math.ceil(d / 25) * 25
        Dtotal = d + 50 + barDia

        bo = 2 * ((colBv + d) + (colDv + d))
        punchArea = Afoot - ((colBv + d) * (colDv + d)) / 1e6
        Vpu = qu * punchArea
        vpu = (Vpu * 1000) / (bo * d) if d > 0 else 0
        vpuAllow = 0.25 * math.sqrt(fck)
        punchOk = vpu <= vpuAllow

        MuFoot = qu * (B / 1000) * (cantilever / 1000)**2 / 2
        MuNmm = MuFoot * 1e6
        bw = 1000
        
        term = 1 - (4.598 * MuNmm) / (fck * bw * d * d)
        
        if term > 0:
            Ast = (0.5 * fck / fy) * (1 - math.sqrt(term)) * bw * d
        else:
            Ast = -1

        AstMin = 0.0012 * bw * Dtotal
        if Ast != -1 and Ast < AstMin:
            Ast = AstMin

        areaOneBar = math.pi * barDia**2 / 4
        spacing = 0
        if Ast > 0:
             spacing = min(math.floor((areaOneBar / Ast) * 1000 / 5) * 5, 300)

        volume = (B / 1000) * (L / 1000) * (Dtotal / 1000)

        return {
            'result': {
                'B': B, 'L': L, 'Dtotal': Dtotal, 'd': d, 'Areq': Areq, 'Afoot': Afoot,
                'qu': qu, 'actualPressure': actualPressure, 'sbcOk': sbcOk,
                'MuFoot': MuFoot, 'Ast': Ast, 'AstMin': AstMin, 'spacing': spacing,
                'vpu': vpu, 'vpuAllow': vpuAllow, 'punchOk': punchOk, 'bo': bo,
                'e': e, 'eMax': eMax, 'cantilever': cantilever,
                'volume': volume, 'tauC': tauC
            }
        }
    except Exception as e:
        return {'error': str(e)}
