from flask import Flask, request, jsonify
import joblib
import traceback

app = Flask(__name__)

# =========================
# Load Models & Encoders
# =========================
income_model = joblib.load("income_model.pkl")
risk_model = joblib.load("risk_model.pkl")
encoders = joblib.load("encoders.pkl")

# =========================
# Normalization Maps
# =========================
SOIL_MAP = {
    "Red": "Red Soil",
    "Red Soil": "Red Soil",
    "Black": "Black Soil",
    "Black Soil": "Black Soil",
    "Laterite": "Laterite Soil",
    "Laterite Soil": "Laterite Soil",
    "Alluvial": "Alluvial Soil",
    "Alluvial Soil": "Alluvial Soil",
    "Forest": "Forest Soil",
    "Forest Soil": "Forest Soil",
    "Arid": "Arid Soil",
    "Arid Soil": "Arid Soil"
}

IRRIGATION_MAP = {
    "Drip": "Drip Irrigation",
    "Drip Irrigation": "Drip Irrigation",
    "Canal": "Canal Irrigation",
    "Canal Irrigation": "Canal Irrigation",
    "Rainfed": "Rainfed",
    "Borewell": "Borewell",
    "Open Well": "Open Well",
    "Tank": "Tank Irrigation",
    "Tank Irrigation": "Tank Irrigation"
}

# =========================
# Utility Functions
# =========================
def normalize(value, mapping, field_name):
    if value not in mapping:
        raise ValueError(f"Invalid {field_name}: {value}")
    return mapping[value]

def safe_int(val, default=0):
    try:
        return int(val)
    except:
        return default

def safe_float(val, default=0.0):
    try:
        return float(val)
    except:
        return default

# =========================
# AI Planner API
# =========================
@app.route("/predict", methods=["POST"])
def predict():
    try:
        data = request.get_json(force=True)

        # -------------------------
        # Normalize categorical inputs
        # -------------------------
        soil_str = normalize(data["soil_type"], SOIL_MAP, "soil_type")
        irrigation_str = normalize(data["irrigation_type"], IRRIGATION_MAP, "irrigation_type")

        soil = encoders["soil_type"].transform([soil_str])[0]
        irrigation = encoders["irrigation_type"].transform([irrigation_str])[0]
        category = encoders["farmer_category"].transform([data["farmer_category"]])[0]

        # -------------------------
        # Numeric Inputs
        # -------------------------
        land_size = safe_float(data["land_size"])
        tree_age = safe_int(data["tree_age"])
        tree_count = safe_int(data["tree_count"])
        loan_amount = safe_float(data["loan_amount"])
        insurance = safe_int(data["insurance"])
        subsidy = safe_float(data["subsidy"])
        misconception_score = safe_float(data["misconception_score"])
        trust_index = safe_float(data["trust_index"])

        # -------------------------
        # Base Feature Vector
        # -------------------------
        base_features = [
            land_size,
            tree_age,
            tree_count,
            soil,
            irrigation,
            loan_amount,
            insurance,
            subsidy,
            misconception_score,
            trust_index
        ]

        # =========================
        # 0–25 YEAR INCOME PROJECTION
        # =========================
        yearly_plan = []
        yearly_numeric = []

        for year in range(0, 26):
            current_age = tree_age + year

            # Yield curve logic (domain-based)
            if current_age < 4:
                multiplier = 0.25
            elif current_age < 7:
                multiplier = 0.75
            elif current_age <= 15:
                multiplier = 1.0
            else:
                multiplier = 0.85

            features = base_features.copy()
            features[1] = current_age  # replace age

            predicted = income_model.predict([features])[0]
            adjusted_income = int(predicted * multiplier)

            yearly_numeric.append(adjusted_income)
            yearly_plan.append(f"Year {year}: ₹{adjusted_income:,}")

        # =========================
        # Risk Prediction
        # =========================
        risk_code = int(risk_model.predict([base_features])[0])
        risk_level = ["Low", "Medium", "High"][risk_code]

        # =========================
        # AI ADVISORY & RECOMMENDATIONS
        # =========================
        advisory = []

        if risk_level == "High":
            advisory.append("🚨 High financial risk detected.")
            advisory.append("• Avoid new loans for the next 2–3 years.")
            advisory.append("• Focus on reducing operational costs.")
        elif risk_level == "Medium":
            advisory.append("⚖️ Moderate financial risk.")
            advisory.append("• Control expenses carefully.")
            advisory.append("• Build emergency savings.")
        else:
            advisory.append("✅ Low financial risk.")
            advisory.append("• You may plan gradual farm expansion.")

        if insurance == 0:
            advisory.append("🛡️ Consider enrolling in crop insurance schemes.")

        if subsidy > 0:
            advisory.append("💰 Utilize government subsidy effectively.")

        advisory.append("🌴 Follow fertilizer & irrigation schedules strictly.")
        advisory.append("📍 Learn from nearby successful oil palm farmers.")

        # =========================
        # Final Response
        # =========================
        return jsonify({
            "status": "success",
            "current_year_income": yearly_numeric[0],
            "risk_level": risk_level,
            "yearly_income_plan": yearly_plan,
            "advisory": advisory
        })

    except Exception as e:
        return jsonify({
            "status": "error",
            "message": str(e),
            "trace": traceback.format_exc()
        }), 400


# =========================
# Health Check
# =========================
@app.route("/", methods=["GET"])
def health():
    return jsonify({"status": "AI Planner Running"})


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=False)
