"""Seed database with insurance companies, demo agency, and admin user."""
import sys
from datetime import date, timedelta
from decimal import Decimal
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))

from app.core.config import get_settings
from app.core.security import get_password_hash
from app.db.session import SessionLocal
from app.models.agency import Agency
from app.models.customer import Customer
from app.models.enums import PaymentMode, PaymentStatus, PolicyCoverageType, PolicyStatus, UserRole
from app.models.insurance_company import InsuranceCompany
from app.models.policy import Policy
from app.models.policy_payment import PolicyPayment
from app.models.user import User
from app.models.vehicle import Vehicle

INSURANCE_COMPANIES = [
    ("ICICI Lombard", "icici_lombard", "icici_lombard"),
    ("HDFC ERGO", "hdfc_ergo", "hdfc_ergo"),
    ("Bajaj Allianz", "bajaj_allianz", "bajaj_allianz"),
    ("TATA AIG", "tata_aig", "tata_aig"),
    ("Go Digit", "go_digit", "go_digit"),
    ("Reliance General", "reliance_general", "reliance_general"),
    ("SBI General", "sbi_general", "sbi_general"),
    ("IFFCO Tokio", "iffco_tokio", "iffco_tokio"),
    ("Oriental Insurance", "oriental", "oriental"),
    ("United India", "united_india", "united_india"),
    ("National Insurance", "national", "national"),
    ("New India Assurance", "new_india", "new_india"),
    ("Future Generali", "future_generali", "future_generali"),
    ("Liberty General", "liberty", "liberty"),
    ("ACKO", "acko", "acko"),
    ("Unknown Company", "unknown", "generic"),
]


def seed_insurance_companies(db) -> None:
    from app.services.scan_keyword_service import ScanKeywordService

    keyword_service = ScanKeywordService(db)
    for name, code, parser_key in INSURANCE_COMPANIES:
        exists = db.query(InsuranceCompany).filter(InsuranceCompany.code == code).first()
        if not exists:
            row = InsuranceCompany(name=name, code=code, parser_key=parser_key, is_active=True)
            db.add(row)
            db.flush()
            keyword_service.sync_primary_for_company(row)
        else:
            keyword_service.sync_primary_for_company(exists)
    db.flush()


def seed_agency_and_users(db, settings) -> Agency:
    agency = db.query(Agency).filter(Agency.name == settings.seed_agency_name).first()
    if not agency:
        agency = Agency(
            name=settings.seed_agency_name,
            phone="9876543210",
            email="agency@demo.local",
            address="Mumbai, Maharashtra",
        )
        db.add(agency)
        db.flush()

    admin = db.query(User).filter(User.email == settings.seed_admin_email).first()
    if not admin:
        legacy_admin = db.query(User).filter(User.email == "admin@agent.local").first()
        if legacy_admin:
            legacy_admin.email = settings.seed_admin_email
            admin = legacy_admin
        else:
            db.add(
                User(
                    agency_id=agency.id,
                    email=settings.seed_admin_email,
                    full_name="Demo Admin",
                    hashed_password=get_password_hash(settings.seed_admin_password),
                    role=UserRole.ADMIN,
                    is_active=True,
                )
            )

    agent_email = "agent@demo.com"
    agent = db.query(User).filter(User.email == agent_email).first()
    if not agent:
        legacy_agent = db.query(User).filter(User.email == "agent@agent.local").first()
        if legacy_agent:
            legacy_agent.email = agent_email
        else:
            db.add(
                User(
                    agency_id=agency.id,
                    email=agent_email,
                    full_name="Demo Agent",
                    hashed_password=get_password_hash("Agent@123"),
                    role=UserRole.AGENT,
                    is_active=True,
                )
            )

    db.flush()
    return agency


def seed_platform_super_admin(db, settings) -> None:
    platform = db.query(Agency).filter(Agency.name == settings.seed_platform_agency_name).first()
    if not platform:
        platform = Agency(
            name=settings.seed_platform_agency_name,
            phone="9999999998",
            email="platform@demo.local",
            address="Platform operations",
        )
        db.add(platform)
        db.flush()

    super_admin = db.query(User).filter(User.email == settings.seed_super_admin_email).first()
    if not super_admin:
        db.add(
            User(
                agency_id=platform.id,
                email=settings.seed_super_admin_email,
                full_name="Platform Super Admin",
                hashed_password=get_password_hash(settings.seed_super_admin_password),
                role=UserRole.SUPER_ADMIN,
                is_active=True,
            )
        )
    db.flush()


def seed_sample_data(db, agency: Agency) -> None:
    if db.query(Customer).filter(Customer.agency_id == agency.id).first():
        return

    icici = db.query(InsuranceCompany).filter(InsuranceCompany.code == "icici_lombard").first()
    hdfc = db.query(InsuranceCompany).filter(InsuranceCompany.code == "hdfc_ergo").first()

    customer1 = Customer(
        agency_id=agency.id,
        name="Rahul Sharma",
        mobile="9876543210",
        email="rahul@example.com",
        city="Mumbai",
        state="Maharashtra",
        pincode="400001",
    )
    customer2 = Customer(
        agency_id=agency.id,
        name="Priya Patel",
        mobile="9123456780",
        email="priya@example.com",
        city="Ahmedabad",
        state="Gujarat",
        pincode="380001",
    )
    db.add_all([customer1, customer2])
    db.flush()

    vehicle1 = Vehicle(
        customer_id=customer1.id,
        registration_number="MH01AB1234",
        make="Maruti",
        model="Swift",
        fuel_type="Petrol",
        manufacturing_year=2020,
    )
    vehicle2 = Vehicle(
        customer_id=customer2.id,
        registration_number="GJ01CD5678",
        make="Hyundai",
        model="Creta",
        fuel_type="Diesel",
        manufacturing_year=2021,
    )
    db.add_all([vehicle1, vehicle2])
    db.flush()

    today = date.today()
    policy1 = Policy(
        agency_id=agency.id,
        customer_id=customer1.id,
        vehicle_id=vehicle1.id,
        insurance_company_id=icici.id if icici else None,
        policy_number="POL-ICICI-001",
        policy_type="Motor",
        coverage_type=PolicyCoverageType.COMPREHENSIVE,
        policy_start_date=today - timedelta(days=335),
        policy_end_date=today + timedelta(days=30),
        premium_amount=Decimal("12500.00"),
        total_commission=Decimal("1500.00"),
        total_paid=Decimal("1000.00"),
        pending_amount=Decimal("500.00"),
        payment_status=PaymentStatus.PARTIAL,
        status=PolicyStatus.EXPIRING_SOON,
    )
    policy2 = Policy(
        agency_id=agency.id,
        customer_id=customer2.id,
        vehicle_id=vehicle2.id,
        insurance_company_id=hdfc.id if hdfc else None,
        policy_number="POL-HDFC-002",
        policy_type="Motor",
        coverage_type=PolicyCoverageType.COMPREHENSIVE,
        policy_start_date=today - timedelta(days=300),
        policy_end_date=today + timedelta(days=5),
        premium_amount=Decimal("18000.00"),
        total_commission=Decimal("2000.00"),
        total_paid=Decimal("0.00"),
        pending_amount=Decimal("2000.00"),
        payment_status=PaymentStatus.PENDING,
        status=PolicyStatus.EXPIRING_SOON,
    )
    db.add_all([policy1, policy2])
    db.flush()

    admin = db.query(User).filter(User.email == get_settings().seed_admin_email).first()
    db.add(
        PolicyPayment(
            policy_id=policy1.id,
            amount=Decimal("1000.00"),
            payment_date=today - timedelta(days=10),
            payment_mode=PaymentMode.UPI,
            reference_number="UPI123456",
            created_by=admin.id if admin else None,
        )
    )


def run_seed(include_sample: bool = True) -> None:
    settings = get_settings()
    db = SessionLocal()
    try:
        seed_insurance_companies(db)
        agency = seed_agency_and_users(db, settings)
        seed_platform_super_admin(db, settings)
        if include_sample:
            seed_sample_data(db, agency)
        db.commit()
        print("Seed completed successfully.")
        print(f"  Admin login: {settings.seed_admin_email} / {settings.seed_admin_password}")
        print("  Agent login: agent@demo.com / Agent@123")
        print(f"  Super admin login: {settings.seed_super_admin_email} / {settings.seed_super_admin_password}")
    except Exception:
        db.rollback()
        raise
    finally:
        db.close()


if __name__ == "__main__":
    include_sample = "--no-sample" not in sys.argv
    run_seed(include_sample=include_sample)
