"""Shared corptools fixtures for shop tests."""

from allianceauth.authentication.models import CharacterOwnership
from allianceauth.tests.auth_utils import AuthUtils
from corptools.models import CharacterAsset, CharacterAudit


def make_owner_character(username="owner", char_id=1001):
    """A user owning one EveCharacter with a corptools CharacterAudit. Returns
    (user, character_audit)."""
    user = AuthUtils.create_user(username)
    eve_char = AuthUtils.add_main_character_2(
        user, username, char_id, corp_id=2001, disconnect_signals=True
    )
    CharacterOwnership.objects.create(
        user=user, character=eve_char, owner_hash=f"oh-{char_id}"
    )
    audit = CharacterAudit.objects.create(character=eve_char)
    return user, audit


def make_asset(
    audit,
    *,
    type_id,
    item_id,
    location_id,
    quantity=1,
    location_flag="Hangar",
    location_type="station",
    blueprint_copy=False,
    name=None,
    type_name=None,
):
    """Create a corptools CharacterAsset owned by `audit`."""
    return CharacterAsset.objects.create(
        character=audit,
        type_id=type_id,
        item_id=item_id,
        location_id=location_id,
        location_flag=location_flag,
        location_type=location_type,
        quantity=quantity,
        singleton=True,
        blueprint_copy=blueprint_copy,
        name=name,
        type_name=type_name,
    )


def make_ship_sde_type(type_id=671, category_id=6, group_id=30):
    """Create an eve_sde ItemType under a given category (default Ship=6), for
    tests that exercise category-based logic. Returns the ItemType."""
    from eve_sde.models import ItemCategory, ItemGroup, ItemType

    cat, _ = ItemCategory.objects.get_or_create(
        id=category_id, defaults={"name": f"cat{category_id}", "published": True}
    )
    grp, _ = ItemGroup.objects.get_or_create(
        id=group_id,
        defaults={"name": f"grp{group_id}", "category": cat, "published": True},
    )
    it, _ = ItemType.objects.get_or_create(
        id=type_id, defaults={"name": f"type{type_id}", "group": grp, "published": True}
    )
    return it


def make_ship_type(
    type_id=671,
    name="Erebus",
    group_id=30,
    group_name="Titan",
    category_id=6,
    category_name="Ship",
):
    """An eveuniverse EveType under a ship group (for stored listing types)."""
    from eveuniverse.models import EveCategory, EveGroup, EveType

    cat, _ = EveCategory.objects.get_or_create(
        id=category_id, defaults={"name": category_name, "published": True}
    )
    grp, _ = EveGroup.objects.get_or_create(
        id=group_id,
        defaults={"name": group_name, "eve_category": cat, "published": True},
    )
    et, _ = EveType.objects.get_or_create(
        id=type_id, defaults={"name": name, "eve_group": grp, "published": True}
    )
    return et


def make_container_type(type_id=11488, name="Giant Secure Container", group_id=448):
    """An eveuniverse EveType OUTSIDE the ship category (Celestial=2)."""
    return make_ship_type(
        type_id=type_id,
        name=name,
        group_id=group_id,
        group_name="Cargo Container",
        category_id=2,
        category_name="Celestial",
    )


def make_corp_owner(username="corpowner", char_id=1101, corp_id=2001):
    """A user with a director-role character in `corp_id`, plus that corp's
    CorporationAudit, so ``CorporationAudit.objects.visible_to(user)`` returns it.
    Returns (user, corporation_audit)."""
    from allianceauth.eveonline.models import EveCorporationInfo
    from corptools.models import CharacterRoles, CorporationAudit

    user = AuthUtils.create_user(username)
    eve_char = AuthUtils.add_main_character_2(
        user, username, char_id, corp_id=corp_id, disconnect_signals=True
    )
    CharacterOwnership.objects.create(
        user=user, character=eve_char, owner_hash=f"oh-{char_id}"
    )
    char_audit = CharacterAudit.objects.create(character=eve_char)
    CharacterRoles.objects.create(character=char_audit, director=True)
    AuthUtils.add_permission_to_user_by_name("corptools.show_if_director", user)

    corp = EveCorporationInfo.objects.filter(corporation_id=corp_id).first()
    if corp is None:
        corp = EveCorporationInfo.objects.create(
            corporation_id=corp_id,
            corporation_name=f"Corp {corp_id}",
            corporation_ticker="CORP",
            member_count=1,
        )
    corp_audit = CorporationAudit.objects.create(corporation=corp)

    from django.contrib.auth.models import User

    return User.objects.get(pk=user.pk), corp_audit  # refresh perm cache


def make_corp_division(corp_audit, *, location_id, name="Jita IV > Division 1"):
    """A synthetic managed division EveLocation (mirrors corptools' rewrite).
    `location_id` should be negative, matching corptools' convention."""
    from corptools.models import EveLocation

    return EveLocation.objects.create(
        location_id=location_id,
        location_name=name,
        managed=True,
        managed_corp=corp_audit,
    )


def make_corp_asset(
    corp_audit,
    *,
    type_id,
    item_id,
    location_id,
    division_location_id=None,
    quantity=1,
    location_flag="CorpSAG1",
    location_type="station",
    singleton=False,
    blueprint_copy=False,
    name=None,
    type_name=None,
):
    """Create a corptools CorpAsset owned by `corp_audit`. `division_location_id`
    sets the synthetic-division FK (``location_name_id``) the way corptools does for
    assets held directly in a division; leave None for assets inside a container."""
    from corptools.models import CorpAsset

    return CorpAsset.objects.create(
        corporation=corp_audit,
        type_id=type_id,
        item_id=item_id,
        location_id=location_id,
        location_flag=location_flag,
        location_type=location_type,
        quantity=quantity,
        singleton=singleton,
        blueprint_copy=blueprint_copy,
        name=name,
        type_name=type_name,
        location_name_id=division_location_id,
    )


def make_corp_blueprint(corp_audit, *, item_id, type_id, me, te, runs, quantity=1):
    """A CorporationBlueprint mirror row (the ESI-sourced ME/TE/runs for a copy)."""
    from shop.models import CorporationBlueprint

    return CorporationBlueprint.objects.create(
        corporation_audit=corp_audit,
        item_id=item_id,
        type_id=type_id,
        me=me,
        te=te,
        runs=runs,
        quantity=quantity,
    )
