#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango

def bmi_category(bmi):
    if bmi < 18.5: return 'Underweight', '#3399ff'
    if bmi < 25.0: return 'Normal weight', '#33cc33'
    if bmi < 30.0: return 'Overweight', '#ff9900'
    return 'Obese', '#cc3300'

class App(Gtk.Window):
    def __init__(self):
        super().__init__(title='BMI Calculator')
        self.set_default_size(360, 300)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        vbox.set_margin_top(20); vbox.set_margin_bottom(20)
        vbox.set_margin_start(20); vbox.set_margin_end(20)
        self.add(vbox)
        grid = Gtk.Grid(column_spacing=12, row_spacing=10)
        grid.attach(Gtk.Label(label='Weight (kg):', xalign=0), 0, 0, 1, 1)
        self.weight = Gtk.SpinButton.new_with_range(1, 300, 0.5)
        self.weight.set_value(70)
        grid.attach(self.weight, 1, 0, 1, 1)
        grid.attach(Gtk.Label(label='Height (cm):', xalign=0), 0, 1, 1, 1)
        self.height = Gtk.SpinButton.new_with_range(50, 250, 0.5)
        self.height.set_value(170)
        grid.attach(self.height, 1, 1, 1, 1)
        vbox.pack_start(grid, False, False, 0)
        btn = Gtk.Button(label='Calculate BMI')
        btn.connect('clicked', self.calculate)
        vbox.pack_start(btn, False, False, 0)
        self.bmi_lbl = Gtk.Label()
        self.bmi_lbl.override_font(Pango.FontDescription('Bold 28'))
        vbox.pack_start(self.bmi_lbl, False, False, 0)
        self.cat_lbl = Gtk.Label()
        self.cat_lbl.override_font(Pango.FontDescription('18'))
        vbox.pack_start(self.cat_lbl, False, False, 0)
        self.prog = Gtk.ProgressBar()
        self.prog.set_show_text(False)
        vbox.pack_start(self.prog, False, False, 0)
        ref_lbl = Gtk.Label(label='<18.5 Underweight | 18.5-24.9 Normal | 25-29.9 Overweight | ≥30 Obese')
        ref_lbl.set_line_wrap(True)
        ref_lbl.set_markup('<span size="small"><18.5 Underweight | 18.5–24.9 Normal | 25–29.9 Overweight | ≥30 Obese</span>')
        vbox.pack_start(ref_lbl, False, False, 0)
    def calculate(self, *_):
        w = self.weight.get_value()
        h = self.height.get_value() / 100
        bmi = w / (h * h)
        cat, color = bmi_category(bmi)
        self.bmi_lbl.set_markup(f'<span foreground="{color}">BMI: {bmi:.1f}</span>')
        self.cat_lbl.set_markup(f'<span foreground="{color}" weight="bold">{cat}</span>')
        frac = min(1.0, (bmi - 10) / 30)
        self.prog.set_fraction(frac)
        css = f'progressbar progress {{ background-color: {color}; }}'
        prov = Gtk.CssProvider(); prov.load_from_data(css.encode())
        self.prog.get_style_context().add_provider(prov, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

win = App()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
