import os
import pytest
from datetime import date
from app import create_app
from app.extensions import db
from app.models import User, SavingsPlanType, Cashier, SavingsPlanMember, Loan
from app.services.credit_service import add_credit


@pytest.fixture()
def app():
    os.environ["DB_CONNECTION"] = "sqlite"
    os.environ["DB_DATABASE"] = ":memory:"
    app = create_app("development")
    app.config.update({"TESTING": True})
    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()


@pytest.fixture()
def session(app):
    with app.app_context():
        yield db.session


def seed_member(session):
    user = User(username="u1", email="u1@example.com", full_name="User One", mobile_number="1234567890")
    user.set_password("pass")
    session.add(user)
    session.commit()

    cashier = Cashier(name="Cashier", user_id=user.id)
    plan = SavingsPlanType(name="Plan", min_period=1, monthly_saving_amount=100, charity_amount=10)
    session.add_all([cashier, plan])
    session.commit()

    member = SavingsPlanMember(
        member_id="M001",
        member_short_name="M1",
        user_id=user.id,
        plan_type_id=plan.id,
        cashier_id=cashier.id,
        effective_date=date.today(),
        status="active",
    )
    session.add(member)
    session.commit()
    return member, user, cashier


def test_duplicate_savings_block(session):
    member, user, cashier = seed_member(session)

    data = {
        "member_id": member.member_id,
        "transaction_type": "savings",
        "total_amount": 100,
        "savings_amount": 90,
        "charity_amount": 10,
        "transaction_date": date.today().strftime("%Y-%m-%d"),
    }
    credit, error, _ = add_credit(data, cashier_id=cashier.id, actor_user_id=user.id)
    assert error is None

    credit2, error2, _ = add_credit(data, cashier_id=cashier.id, actor_user_id=user.id)
    assert credit2 is None
    assert "already exists" in error2


def test_flexi_stored_as_savings(session):
    member, user, cashier = seed_member(session)

    data = {
        "member_id": member.member_id,
        "transaction_type": "flexi",
        "total_amount": 50,
        "savings_amount": 50,
        "charity_amount": 0,
        "transaction_date": date.today().strftime("%Y-%m-%d"),
    }
    credit, error, _ = add_credit(data, cashier_id=cashier.id, actor_user_id=user.id)
    assert error is None
    assert credit.transaction_type == "savings"


def test_emi_closes_loan(session):
    member, user, cashier = seed_member(session)

    loan = Loan(
        loan_id="L001",
        member_id=member.member_id,
        request_id="LR1",
        amount=200,
        term_months=12,
        status="active",
    )
    session.add(loan)
    session.commit()

    data = {
        "member_id": member.member_id,
        "transaction_type": "emi",
        "total_amount": 200,
        "transaction_date": date.today().strftime("%Y-%m-%d"),
        "loan_id": loan.loan_id,
    }
    credit, error, _ = add_credit(data, cashier_id=cashier.id, actor_user_id=user.id)
    assert error is None

    session.refresh(loan)
    assert loan.status == "closed"
