from dungeonsheets import features as feats


class Background:
    name = "Generic background"
    owner = None
    skill_proficiencies = ()
    weapon_proficiencies = ()
    proficiencies_text = ()
    skill_choices = ()
    num_skill_choices = 0
    features = ()
    languages = ()

    def __init__(self, owner=None):
        self.owner = owner
        cls = type(self)
        self.features = tuple([f(owner=self.owner) for f in cls.features])

    def __str__(self):
        return self.name


class Acolyte(Background):
    name = "Acolyte"
    skill_proficiencies = ("insight", "religion")
    languages = ("[choose one]", "[choose one]")
    features = (feats.ShelterOfTheFaithful,)


class Charlatan(Background):
    name = "Charlatan"
    skill_proficiencies = ("deception", "sleight of hand")
    features = (feats.FalseIdentity,)


class Criminal(Background):
    name = "Criminal"
    skill_proficiencies = ("deception", "stealth")
    features = (feats.CriminalContact,)


class Spy(Criminal):
    name = "Spy"


class Entertainer(Background):
    name = "Entertainer"
    skill_proficiencies = ("acrobatics", "performance")
    features = (feats.ByPopularDemand,)


class Gladiator(Entertainer):
    name = "Gladiator"


class FolkHero(Background):
    name = "Folk Hero"
    skill_proficiencies = ("animal handling", "survival")
    features = (feats.RusticHospitality,)


class GuildArtisan(Background):
    name = "Guild Artisan"
    skill_proficiencies = ("insight", "persuasion")
    languages = ("[choose one]", "[choose one]")
    features = (feats.GuildMembership,)


class GuildMerchant(GuildArtisan):
    name = "Guild Merchant"


class Hermit(Background):
    name = "Hermit"
    skill_proficiencies = ("medicine", "religion")
    languages = ("[choose one]",)
    features = (feats.Discovery,)


class Noble(Background):
    name = "Noble"
    skill_proficiencies = ("history", "persuasion")
    languages = ("[choose one]",)
    features = (feats.PositionOfPrivilege,)


class Knight(Noble):
    name = "Knight"


class Outlander(Background):
    name = "Outlander"
    skill_proficiencies = ("athletics", "survival")
    languages = ("[choose one]",)
    features = (feats.Wanderer,)


class Sage(Background):
    name = "Sage"
    skill_proficiencies = ("arcana", "history")
    languages = ("[choose one]", "[choose one]")
    features = (feats.Researcher,)


class Sailor(Background):
    name = "Sailor"
    skill_proficiencies = ("athletics", "perception")
    features = (feats.ShipsPassage,)


class Pirate(Sailor):
    name = "Pirate"


class Soldier(Background):
    name = "Soldier"
    skill_proficiencies = ("athletics", "intimidation")
    features = (feats.MilitaryRank,)


class Urchin(Background):
    name = "Urchin"
    skill_proficiencies = ("sleight of hand", "stealth")
    features = (feats.CitySecrets,)


# Sword's Coast Adventurers Guide
class CityWatch(Background):
    name = "City Watch"
    skill_proficiencies = ("athletics", "insight")
    languages = ("[choose one]", "[choose one]")
    features = (feats.WatchersEye,)


class ClanCrafter(Background):
    name = "Clan Crafter"
    skill_proficiencies = ("history", "insight")
    languages = ("Dwarvish",)
    features = (feats.RespectOfTheStoutFolk,)


class CloisteredScholar(Background):
    name = "Cloistered Scholar"
    skill_proficiencies = ("history",)
    skill_choices = ("arcana", "nature", "religion")
    num_skill_choices = 1
    languages = ("[choose one]", "[choose one]")
    features = (feats.LibraryAccess,)


class Courtier(Background):
    name = "Courtier"
    skill_proficiencies = ("insight", "persuasion")
    languages = ("[choose one]", "[choose one]")
    features = (feats.CourtFunctionary,)


class FactionAgent(Background):
    name = "Faction Agent"
    skill_proficiencies = ("insight",)
    skill_choices = (
        "animal handling",
        "arcana",
        "deception",
        "history",
        "intimidation",
        "investigation",
        "medicine",
        "nature",
        "perception",
        "performance",
        "persuasion",
        "religion",
        "survival",
    )
    num_skill_choices = 1
    languages = ("[choose one]", "[choose one]")
    features = (feats.SafeHaven,)


class FarTraveler(Background):
    name = "Far Traveler"
    skill_proficiencies = ("insight", "perception")
    languages = ("[choose one]",)
    features = (feats.AllEyesOnYou,)


class Inheritor(Background):
    name = "Inheritor"
    skill_proficiencies = ("survival",)
    skill_choices = ("arcana", "history", "religion")
    num_skill_choices = 1
    languages = ("[choose one]",)
    features = (feats.Inheritance,)


class KnightOfTheOrder(Background):
    name = "Knight of the Order"
    skill_proficiencies = ("persuasion",)
    skill_choices = ("arcana", "history", "nature", "religion")
    num_skill_choices = 1
    languages = ("[choose one]",)
    features = (feats.KnightlyRegard,)


class MercenaryVeteran(Background):
    name = "Mercenary Veteran"
    skill_proficiencies = ("athletics", "persuasion")
    features = (feats.MercenaryLife,)


class UrbanBountyHunter(Background):
    name = "Urban Bounty Hunter"
    skill_proficiencies = ()
    skill_choices = ("Deception", "Insight", "Persuasion", "Stealth")
    num_skill_choices = 2
    features = (feats.EarToTheGround,)


class UthgardtTribeMember(Background):
    name = "Uthgardt Tribe Member"
    skill_profifiencies = ("athletics", "survival")
    languages = ("[choose one]",)
    features = (feats.UthgardtHeritage,)


class WaterdhavianNoble(Background):
    name = "Waterdhavian Noble"
    skill_proficiencies = ("history", "persuasion")
    languages = ("[choose one]",)
    features = (feats.KeptInStyle,)


PHB_backgrounds = [
    Acolyte,
    Charlatan,
    Criminal,
    Spy,
    Entertainer,
    Gladiator,
    FolkHero,
    GuildArtisan,
    GuildMerchant,
    Hermit,
    Noble,
    Knight,
    Outlander,
    Sage,
    Sailor,
    Pirate,
    Soldier,
    Urchin,
]

SCAG_backgrounds = [
    CityWatch,
    ClanCrafter,
    CloisteredScholar,
    Courtier,
    FactionAgent,
    FarTraveler,
    Inheritor,
    KnightOfTheOrder,
    MercenaryVeteran,
    UrbanBountyHunter,
    UthgardtTribeMember,
    WaterdhavianNoble,
]

available_backgrounds = PHB_backgrounds + SCAG_backgrounds

__all__ = tuple([b.name for b in available_backgrounds]) + (
    "PHB_backgrounds",
    "SCAG_backgrounds",
    "available_backgrounds",
)
