"""Phaxor — Concrete Volume Engine (Python port)"""
import math

CONCRETE_GRADES = {
    'm10': {'name': 'M10', 'fck': 10, 'ratio': '1:3:6', 'cement': 220, 'sand': 660, 'aggregate': 1320, 'water': 150},
    'm15': {'name': 'M15', 'fck': 15, 'ratio': '1:2:4', 'cement': 310, 'sand': 620, 'aggregate': 1240, 'water': 155},
    'm20': {'name': 'M20', 'fck': 20, 'ratio': '1:1.5:3', 'cement': 395, 'sand': 593, 'aggregate': 1185, 'water': 158},
    'm25': {'name': 'M25', 'fck': 25, 'ratio': '1:1:2', 'cement': 440, 'sand': 440, 'aggregate': 880, 'water': 160},
    'm30': {'name': 'M30', 'fck': 30, 'ratio': 'Design Mix', 'cement': 450, 'sand': 500, 'aggregate': 1100, 'water': 162},
    'm35': {'name': 'M35', 'fck': 35, 'ratio': 'Design Mix', 'cement': 460, 'sand': 490, 'aggregate': 1080, 'water': 164},
    'm40': {'name': 'M40', 'fck': 40, 'ratio': 'Design Mix', 'cement': 480, 'sand': 470, 'aggregate': 1060, 'water': 165},
    'custom': {'name': 'Custom', 'fck': 25, 'ratio': 'Custom', 'cement': 440, 'sand': 440, 'aggregate': 880, 'water': 160},
}

def calc_raw_volume(shape: str, dims: dict) -> float:
    if shape == 'rectangular-slab':
        return dims.get('length', 0) * dims.get('width', 0) * dims.get('thickness', 0)
    elif shape == 'circular-slab':
        return math.pi * (dims.get('diameter', 0) / 2)**2 * dims.get('thickness', 0)
    elif shape == 'rectangular-column':
        return dims.get('b', 0) * dims.get('h', 0) * dims.get('height', 0)
    elif shape == 'circular-column':
        return math.pi * (dims.get('diameter', 0) / 2)**2 * dims.get('height', 0)
    elif shape == 'footing':
        return dims.get('length', 0) * dims.get('width', 0) * dims.get('depth', 0)
    elif shape == 'trapezoidal':
        a = dims.get('topWidth', 0)
        b = dims.get('bottomWidth', 0)
        return ((a + b) / 2) * dims.get('height', 0) * dims.get('length', 0)
    elif shape == 'staircase':
        steps = math.floor(dims.get('steps', 0))
        riser = dims.get('riser', 0)
        tread = dims.get('tread', 0)
        waist = dims.get('waist', 0)
        stairW = dims.get('stairWidth', 0)
        stepVol = steps * 0.5 * riser * tread * stairW
        flightLen = math.sqrt((steps * riser)**2 + (steps * tread)**2)
        waistVol = flightLen * waist * stairW
        return stepVol + waistVol
    return 0

def solve_concrete_volume(inputs: dict) -> dict:
    shape = inputs.get('shape', 'rectangular-slab')
    dims = inputs.get('dims', {})
    quantity = float(inputs.get('quantity', 1))
    grade_key = inputs.get('gradeKey', 'm20')
    rebar_pct = float(inputs.get('rebarPct', 0))
    wastage = float(inputs.get('wastage', 0))
    unit_cost = float(inputs.get('unitCost', 0))
    rebar_cost = float(inputs.get('rebarCost', 0))

    net_vol_per_unit = calc_raw_volume(shape, dims)
    if net_vol_per_unit <= 0:
        return {'error': "Invalid dimensions, volume is zero"}

    grade = CONCRETE_GRADES.get(grade_key, CONCRETE_GRADES['custom'])
    waste_multiplier = 1 + (wastage / 100)
    
    total_net_vol = net_vol_per_unit * quantity
    gross_vol = total_net_vol * waste_multiplier

    # Materials
    cement_kg = gross_vol * grade['cement']
    cement_bags = math.ceil(cement_kg / 50)
    sand_kg = gross_vol * grade['sand']
    aggregate_kg = gross_vol * grade['aggregate']
    water_liters = gross_vol * grade['water']

    # Rebar
    rebar_vol = total_net_vol * (rebar_pct / 100)
    rebar_weight = rebar_vol * 7850 # kg

    # Cost
    conc_cost = gross_vol * unit_cost
    rbar_cost_val = rebar_weight * rebar_cost
    total_cost = conc_cost + rbar_cost_val

    return {
        'result': {
            'netVolPerUnit': net_vol_per_unit,
            'totalNetVol': total_net_vol,
            'grossVol': gross_vol,
            'cementKg': cement_kg, 'cementBags': cement_bags,
            'sandKg': sand_kg, 'aggregateKg': aggregate_kg,
            'waterLiters': water_liters,
            'rebarWeight': rebar_weight,
            'concCost': conc_cost, 'rbarCost': rbar_cost_val,
            'totalCost': total_cost,
            'qty': quantity,
            'grade': grade
        }
    }
