"""
Seed script for Farmer Lifecycle Management sample data.
Run: python -m scripts.seed_farmer_data
"""
import uuid
import sys
import os
from datetime import date, timedelta, datetime
from random import choice, randint, uniform

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.database import SessionLocal, engine
from app.models.customer import Customer
from app.models.farmer import FarmerProfile
from app.models.farm import Farm, FarmField
from app.models.passport import PlantPassport, PassportTimelineEvent
from app.models.plant_activation import PlantActivation, PlantOwnershipHistory, PlantCostRecord
from app.models.plant_lifecycle import (
    PlantGrowthRecord, PlantTreatmentRecord, PlantHealthRecord,
    PlantHarvestRecord, PlantCareRecord, PlantCareSchedule
)
from app.models.plant import Plant, PlantVariety, PlantCategory
from app.models.production import ProductionBatch
from app.models.branch import Branch
from app.models.user import User
from app.services.auth import hash_password


def gen_uuid():
    return str(uuid.uuid4())


def seed():
    db = SessionLocal()
    try:
        # Check if data exists
        if db.query(Customer).filter(Customer.is_farmer == True).count() > 0:
            print("Farmer data already exists. Skipping.")
            return

        print("Seeding farmer lifecycle sample data...")

        # Get or create branch
        branch = db.query(Branch).first()
        if not branch:
            branch = Branch(id=gen_uuid(), code="BR-001", name="Main Branch", address="Head Office", is_active=True)
            db.add(branch)
            db.flush()

        # Get admin user
        admin = db.query(User).first()
        if not admin:
            admin = User(
                id=gen_uuid(), username="admin", email="admin@nursery.com",
                password_hash=hash_password("admin123"), full_name="System Administrator", is_active=True
            )
            db.add(admin)
            db.flush()

        # --- Categories & Varieties ---
        categories_data = [
            ("Fruit Trees", "তরমুজ"),
            ("Flowering Plants", "ফুলের গাছ"),
            ("Vegetables", "সবজি"),
            ("Herbs", "ভেষজ"),
            ("Ornamental", "প্রজাপতি"),
        ]
        categories = {}
        for name_en, name_bn in categories_data:
            cat = db.query(PlantCategory).filter(PlantCategory.name == name_en).first()
            if not cat:
                cat = PlantCategory(id=gen_uuid(), name=name_en, description=name_bn)
                db.add(cat)
                db.flush()
            categories[name_en] = cat

        varieties_data = [
            ("Grafted Mango", "Fruit Trees", "Mangifera indica"),
            ("Lemon", "Fruit Trees", "Citrus limon"),
            ("Guava", "Fruit Trees", "Psidium guajava"),
            ("Hibiscus", "Flowering Plants", "Hibiscus rosa-sinensis"),
            ("Marigold", "Flowering Plants", "Tagetes erecta"),
            ("Rose", "Flowering Plants", "Rosa"),
            ("Tomato", "Vegetables", "Solanum lycopersicum"),
            ("Chili", "Vegetables", "Capsicum annuum"),
            ("Lemon Grass", "Herbs", "Cymbopogon citratus"),
            ("Aloe Vera", "Ornamental", "Aloe barbadensis"),
        ]
        varieties = {}
        for name, cat_name, sci in varieties_data:
            var = db.query(PlantVariety).filter(PlantVariety.name == name).first()
            if not var:
                var = PlantVariety(
                    id=gen_uuid(), name=name,
                    category_id=categories[cat_name].id, plant_type="Outdoor",
                )
                db.add(var)
                db.flush()
            varieties[name] = var

        # --- Plants ---
        plants_data = [
            ("Mango Grafted", "Mango", "Fruit Trees", "Grafted Mango"),
            ("Lemon Improved", "Lemon", "Fruit Trees", "Lemon"),
            ("Guava Lal Patti", "Guava", "Fruit Trees", "Guava"),
            ("Hibiscus Red", "Hibiscus", "Flowering Plants", "Hibiscus"),
            ("Marigold Yellow", "Marigold", "Flowering Plants", "Marigold"),
            ("Rose Pink", "Rose", "Flowering Plants", "Rose"),
            ("Tomato Hybrid", "Tomato", "Vegetables", "Tomato"),
            ("Chili BK", "Chili", "Vegetables", "Chili"),
            ("Lemon Grass", "Lemon Grass", "Herbs", "Lemon Grass"),
            ("Aloe Vera Green", "Aloe Vera", "Ornamental", "Aloe Vera"),
        ]
        plants = {}
        for scientific, local, cat_name, var_name in plants_data:
            plant = db.query(Plant).filter(Plant.scientific_name == scientific).first()
            if not plant:
                plant = Plant(
                    id=gen_uuid(), code=f"PLT-{scientific[:3].upper()}-{len(plants)+1:04d}",
                    name=local, scientific_name=scientific,
                    local_name=local, category_id=categories[cat_name].id,
                    description=f"{local} seedling"
                )
                db.add(plant)
                db.flush()
            plants[scientific] = plant

        # --- Production Batches ---
        batches = []
        batch_data = [
            ("BATCH-2026-001", "Mango Grafted", 500, date(2026, 1, 15)),
            ("BATCH-2026-002", "Lemon Improved", 300, date(2026, 2, 1)),
            ("BATCH-2026-003", "Guava Lal Patti", 400, date(2026, 2, 15)),
            ("BATCH-2026-004", "Tomato Hybrid", 600, date(2026, 3, 1)),
            ("BATCH-2026-005", "Chili BK", 350, date(2026, 3, 10)),
        ]
        for b_num, plant_name, qty, sowing in batch_data:
            batch = db.query(ProductionBatch).filter(ProductionBatch.batch_number == b_num).first()
            if not batch:
                batch = ProductionBatch(
                    id=gen_uuid(), batch_number=b_num,
                    plant_id=plants[plant_name].id,
                    variety_id=varieties[plant_name].id if plant_name in varieties else None,
                    sowing_date=sowing, sown_quantity=qty, current_quantity=qty,
                    status="growing", branch_id=branch.id,
                )
                db.add(batch)
                db.flush()
            batches.append(batch)

        # --- Plant Passports ---
        passports = []
        for i, batch in enumerate(batches):
            existing = db.query(PlantPassport).filter(PlantPassport.batch_id == batch.id).first()
            if existing:
                passports.append(existing)
                continue
            plant = db.query(Plant).filter(Plant.id == batch.plant_id).first()
            variety = db.query(PlantVariety).filter(PlantVariety.id == batch.variety_id).first() if batch.variety_id else None
            cat = db.query(PlantCategory).filter(PlantCategory.id == plant.category_id).first() if plant else None
            passport = PlantPassport(
                id=gen_uuid(),
                passport_id=f"CHR-PLT-2026-{i+1:06d}",
                batch_id=batch.id,
                plant_id=batch.plant_id,
                variety_id=batch.variety_id,
                category_id=plant.category_id if plant else None,
                branch_id=branch.id,
                plant_name=plant.name if plant else "Unknown",
                scientific_name=plant.scientific_name if plant else "",
                variety_name=variety.name if variety else "",
                category_name=cat.name if cat else "",
                batch_number=batch.batch_number,
                seed_lot_number=f"SL-2026-{i+1:04d}",
                seed_supplier="Chara Nursery",
                sowing_date=batch.sowing_date,
                germination_date=batch.sowing_date + timedelta(days=randint(5, 10)),
                germination_rate=round(uniform(80, 95), 1),
                transplant_date=batch.sowing_date + timedelta(days=randint(20, 30)),
                current_growth_stage="ready",
                current_stock=batch.current_quantity,
                nursery_zone=choice(["Zone A", "Zone B", "Zone C"]),
                greenhouse=choice(["GH-1", "GH-2", ""]),
                production_cost=round(uniform(50, 200), 2),
                selling_price=round(uniform(150, 500), 2),
                health_status="healthy",
                health_score=round(uniform(85, 98), 1),
                is_active=True,
            )
            db.add(passport)
            db.flush()
            passports.append(passport)

        # --- Customers & Farmer Profiles ---
        farmers_data = [
            ("Rahman Farm", "Abdul Rahman", "01712345678", "Rahman Organic Farm", 5.2, "Dhaka", "Tangail", "Ghatail", "Organic", "Loamy", "Drip"),
            ("Karim Gardens", "Mohammad Karim", "01812345679", "Karim Fruit Garden", 3.8, "Dhaka", "Manikganj", "Saturia", "Mixed", "Clay", "Sprinkler"),
            ("Begum Farms", "Fatema Begum", "01912345680", "Begum Green House", 2.5, "Rajshahi", "Natore", "Natore Sadar", "Conventional", "Loamy", "Manual"),
            ("Hossain Agro", "Kamal Hossain", "01612345681", "Hossain Agro Farm", 8.0, "Chittagong", "Comilla", "Comilla Sadar", "Organic", "Sandy", "Drip"),
            ("Akter Nursery", "Rashida Akter", "01512345682", "Akter Nursery Farm", 1.5, "Sylhet", "Habiganj", "Habiganj Sadar", "Mixed", "Loamy", "Rainfed"),
        ]

        farmer_profiles = []
        for i, (farm_name, cust_name, phone, full_farm, area, div, dist, upa, f_type, soil, irr) in enumerate(farmers_data):
            # Customer
            cust = Customer(
                id=gen_uuid(), code=f"CUST-FARM-{i+1:04d}",
                name=cust_name, customer_type="Farmer",
                phone=phone, email=f"{cust_name.split()[0].lower()}@farm.com",
                address=f"{upa}, {dist}", city=dist,
                is_farmer=True, total_purchases=round(uniform(5000, 25000), 2),
                outstanding=round(uniform(0, 2000), 2),
            )
            db.add(cust)
            db.flush()

            # Farmer Profile
            fp = FarmerProfile(
                id=gen_uuid(), customer_id=cust.id,
                farm_name=full_farm, farm_area=area, land_area=area * 0.8,
                division=div, district=dist, upazila=upa,
                village=f"{upa} Village",
                farming_type=f_type, soil_type=soil, irrigation_type=irr,
                latitude=round(uniform(23.5, 24.5), 6),
                longitude=round(uniform(89.5, 91.5), 6),
                is_verified=True,
            )
            db.add(fp)
            db.flush()

            # Farm
            farm = Farm(
                id=gen_uuid(), farmer_id=fp.id,
                name=full_farm, area=area,
                address=f"{upa}, {dist}",
                soil_type=soil, irrigation_type=irr, farming_type=f_type,
                latitude=fp.latitude, longitude=fp.longitude,
            )
            db.add(farm)
            db.flush()

            # Fields
            fields = []
            for j in range(randint(1, 3)):
                field = FarmField(
                    id=gen_uuid(), farm_id=farm.id,
                    name=f"Field {chr(65+j)}", area=round(area / (j+2), 2),
                    crop_type=choice(["Mango", "Lemon", "Guava", "Tomato", "Chili", "Mixed"]),
                    plant_count=randint(50, 200),
                    soil_type=soil, irrigation_type=irr,
                    planting_date=date.today() - timedelta(days=randint(30, 120)),
                    status="active",
                )
                db.add(field)
                fields.append(field)
            db.flush()

            farmer_profiles.append((fp, cust, farm, fields))

        # --- Plant Activations & Lifecycle ---
        stages = ["seedling", "vegetative", "flowering", "fruiting", "mature"]
        for i, (fp, cust, farm, fields) in enumerate(farmer_profiles):
            # Each farmer gets 2-4 plants
            num_plants = randint(2, 4)
            available_passports = [p for p in passports if not db.query(PlantActivation).filter(PlantActivation.passport_id == p.id).first()]
            if not available_passports:
                available_passports = passports[:num_plants]

            for j in range(min(num_plants, len(available_passports))):
                passport = available_passports[j]
                activation_date = date.today() - timedelta(days=randint(10, 90))
                planting_date = activation_date + timedelta(days=randint(1, 5))
                field = choice(fields) if fields else None

                activation = PlantActivation(
                    id=gen_uuid(),
                    activation_id=f"FAR-2026-{i*4+j+1:06d}",
                    passport_id=passport.id,
                    farmer_id=fp.id,
                    farm_id=farm.id,
                    field_id=field.id if field else None,
                    purchase_date=activation_date - timedelta(days=randint(1, 3)),
                    activation_date=activation_date,
                    planting_date=planting_date,
                    initial_condition=choice(["Excellent", "Good", "Fair"]),
                    gps_latitude=fp.latitude + uniform(-0.01, 0.01),
                    gps_longitude=fp.longitude + uniform(-0.01, 0.01),
                    status=choice(["activated", "growing", "flowering", "fruiting"]),
                )
                db.add(activation)
                db.flush()

                # Ownership history
                ownership = PlantOwnershipHistory(
                    id=gen_uuid(), passport_id=passport.id, activation_id=activation.id,
                    from_owner_type="nursery", to_owner_type="farmer",
                    to_owner_id=fp.id, transfer_date=activation_date,
                    transfer_reason="Sale", authorized_by=admin.id,
                )
                db.add(ownership)

                # Update passport
                passport.owner_id = cust.id
                passport.activation_status = "activated"

                # --- Growth Records (3-6 per plant) ---
                for k in range(randint(3, 6)):
                    record_date = planting_date + timedelta(days=k * 7 + randint(0, 3))
                    if record_date > date.today():
                        continue
                    stage = stages[min(k, len(stages)-1)]
                    growth = PlantGrowthRecord(
                        id=gen_uuid(), activation_id=activation.id,
                        record_date=record_date,
                        plant_height_cm=round(uniform(10, 100) + k * 15, 1),
                        stem_diameter_mm=round(uniform(3, 15) + k * 2, 1),
                        canopy_size_cm=round(uniform(10, 50) + k * 8, 1),
                        leaf_count=randint(8, 60) + k * 10,
                        flower_count=randint(0, 20) if k >= 2 else 0,
                        fruit_count=randint(0, 10) if k >= 3 else 0,
                        health_score=round(uniform(70, 98), 1),
                        growth_stage=stage,
                        general_health=choice(["Excellent", "Good", "Fair"]),
                        recorded_by=admin.id,
                    )
                    db.add(growth)

                # --- Treatment Records (1-3 per plant) ---
                for k in range(randint(1, 3)):
                    treatment = PlantTreatmentRecord(
                        id=gen_uuid(),
                        record_number=f"PTR-2026-{i*4+j*3+k+1:06d}",
                        activation_id=activation.id,
                        treatment_date=planting_date + timedelta(days=randint(5, 60)),
                        treatment_type=choice(["Fertilizer", "Pesticide", "Fungicide", "Watering"]),
                        product_name=choice(["NPK 20-20-20", "Imidacloprid", "Mancozeb", "Organic Compost", "Neem Oil"]),
                        dosage=choice(["2g/L", "1mL/L", "3g/L", "500mL"]),
                        quantity=round(uniform(0.5, 5), 2),
                        unit=choice(["kg", "L"]),
                        cost=round(uniform(50, 300), 2),
                        notes=f"Routine {choice(['preventive', 'corrective', 'scheduled'])} treatment",
                        recorded_by=admin.id,
                    )
                    db.add(treatment)

                # --- Health Records (2-4 per plant) ---
                for k in range(randint(2, 4)):
                    health = PlantHealthRecord(
                        id=gen_uuid(), activation_id=activation.id,
                        record_date=planting_date + timedelta(days=k * 10 + randint(0, 5)),
                        health_score=round(uniform(75, 98), 1),
                        plant_height_cm=round(uniform(20, 80), 1),
                        leaf_count=randint(15, 50),
                        stem_thickness_mm=round(uniform(5, 12), 1),
                        plant_color=choice(["Deep Green", "Light Green", "Yellowish"]),
                        root_status=choice(["Healthy", "Good", "Fair"]),
                        moisture_level=round(uniform(40, 80), 1),
                        mortality_rate=0.0,
                        recorded_by=admin.id,
                    )
                    db.add(health)

                # --- Harvest Records (1-3 per plant) ---
                for k in range(randint(1, 3)):
                    harvest = PlantHarvestRecord(
                        id=gen_uuid(),
                        harvest_number=f"HRV-2026-{i*4+j*3+k+1:06d}",
                        activation_id=activation.id,
                        harvest_date=planting_date + timedelta(days=randint(60, 120)),
                        quantity=round(uniform(2, 20), 2),
                        unit=choice(["kg", "pcs", "dozen"]),
                        grade=choice(["A", "B", "C"]),
                        selling_price=round(uniform(80, 300), 2),
                        buyer=choice(["Local Market", "Wholesale", "Direct", "Online"]),
                        revenue=round(uniform(500, 5000), 2),
                        notes=f"Harvest grade {choice(['A', 'B'])} quality",
                        recorded_by=admin.id,
                    )
                    db.add(harvest)

                # --- Cost Records (2-4 per plant) ---
                cost_types = [
                    ("Fertilizer", 200, "NPK fertilizer for growth"),
                    ("Pesticide", 150, "Neem oil spray"),
                    ("Labor", 500, "Planting and maintenance"),
                    ("Transport", 100, "Delivery from nursery"),
                    ("Water", 50, "Irrigation cost"),
                ]
                for k in range(randint(2, 4)):
                    ct = choice(cost_types)
                    cost = PlantCostRecord(
                        id=gen_uuid(), activation_id=activation.id,
                        cost_type=ct[0], amount=ct[1] + round(uniform(-50, 100), 2),
                        description=ct[2],
                        date=planting_date + timedelta(days=randint(1, 60)),
                        notes=f"Regular {ct[0].lower()} expense",
                    )
                    db.add(cost)

                # --- Care Schedules ---
                schedules = [
                    ("watering", 1, "07:00", "Water early morning"),
                    ("fertilizing", 14, "08:00", "NPK fertilizer application"),
                    ("inspection", 7, "09:00", "Weekly plant health check"),
                ]
                for care_type, freq, time, notes in schedules:
                    schedule = PlantCareSchedule(
                        id=gen_uuid(), activation_id=activation.id,
                        care_type=care_type, frequency_days=freq,
                        next_due_date=date.today() + timedelta(days=randint(-2, 5)),
                        reminder_time=time, notes=notes,
                    )
                    db.add(schedule)

                # --- Care Records (2-3 per plant) ---
                for k in range(randint(2, 3)):
                    care = PlantCareRecord(
                        id=gen_uuid(), activation_id=activation.id,
                        care_type=choice(["watering", "fertilizing", "pruning", "inspection"]),
                        care_date=planting_date + timedelta(days=k * 5 + randint(0, 5)),
                        quantity=round(uniform(1, 10), 2),
                        unit=choice(["L", "kg", "times"]),
                        cost=round(uniform(20, 200), 2),
                        notes=f"Regular {choice(['watering', 'feeding', 'inspection'])}",
                        recorded_by=admin.id,
                    )
                    db.add(care)

        db.commit()
        print(f"✓ Created {len(farmer_profiles)} farmer profiles with farms & fields")
        print(f"✓ Created {len(passports)} plant passports")
        print("✓ Created activations with full lifecycle data")
        print("✓ Growth, treatment, health, harvest, cost records added")
        print("✓ Care schedules and records added")
        print("Done!")

    except Exception as e:
        db.rollback()
        print(f"Error: {e}")
        import traceback
        traceback.print_exc()
    finally:
        db.close()


if __name__ == "__main__":
    seed()
