#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import re
import aiohttp

import LakshmiErrors
from contents.character.Investigator import Investigator, SkillSet
from contents.character.sitegetter.AbstractCharacterGetter import AbstractCharacterGetter

class VampireBloodNetGetter(AbstractCharacterGetter):
    DETECT_TARGET_URL = re.compile(r"^.*charasheet\.vampire\-blood\.net.*$", re.IGNORECASE)
    SKILL_TITLE_SPLIT = re.compile(r"^([^（【〔［《『「(\[）】〕］》』」)\]]+)([（【〔［《『「(\[]+)([^）】〕］》』」)\]]+)([）】〕］》』」)\]])?$", re.IGNORECASE)

    def __init__(self):
        pass

    @classmethod
    def get_site_title(self) -> str:
        return "キャラクター保管所 (charasheet.vampire-blood.net)"

    @classmethod
    def is_detect_url(self, site_url: str) -> bool:
        return (VampireBloodNetGetter.DETECT_TARGET_URL.search(site_url) != None)

    @classmethod
    def get_favicon_url(self) -> str:
        return "https://www.google.com/s2/favicons?domain=charasheet.vampire-blood.net"

    @classmethod
    async def request(self, site_url: str) -> Investigator:
        result = None
        response = None
        data = None
        try:
            # https://charasheet.vampire-blood.net/help/webif
            request_url = site_url + ".js"

            async with aiohttp.ClientSession() as session:
                async with session.get(request_url) as response:
                    if response.status == 200:
                        data = await response.json()
        except Exception as e:
            response = None

        if response:
            # COCのデータでなければ拒否する。
            if data["game"] != "coc":
                raise LakshmiErrors.NotCallOfCthulhuInvestigatorException()

            result = Investigator()
            result.unique_id = ""                                   # Key
            result.site_id1 = str(data["data_id"])                  # SiteId1
            result.site_id2 = str(data["phrase"])                   # SiteId2
            result.site_url = site_url                              # SiteUrl
            result.site_name = self.get_site_title()                # SiteName
            result.site_favicon_url = self.get_favicon_url()        # SiteFaviconUrl
            result.author_id = ""                                   # 所有者ID
            result.author_name = ""                                 # 所有者名
            result.active = False                                   # Active
            result.lost = False                                     # Lost
            result.tag = data["pc_tags"]                            # タグ
            result.image_url = ""                                   # 画像URL

            # パーソナルデータ
            result.personal_data.name = data["pc_name"]             # 名前
            result.personal_data.occupation = data["shuzoku"]       # 職業
            result.personal_data.age = data["age"]                  # 年齢
            result.personal_data.sex = data["sex"]                  # 性別
            result.personal_data.residence = ""                     # 居住地
            result.personal_data.birthplace = data["pc_kigen"]      # 出身地

            result.personal_data.height = data["pc_height"]         # 身長
            result.personal_data.weight = data["pc_weight"]         # 体重
            result.personal_data.hair_color = data["color_hair"]    # 髪の色
            result.personal_data.eye_color = data["color_eye"]      # 瞳の色
            result.personal_data.skin_color = data["color_skin"]    # 肌の色

            result.personal_data.backstory = data["pc_making_memo"] # その他メモ

            # 能力値
            result.characteristics["strength"].set_values(data["NA1"], data["NS1"], data["NM1"], data["NP1"])
            result.characteristics["constitution"].set_values(data["NA2"], data["NS2"], data["NM2"], data["NP2"])
            result.characteristics["power"].set_values(data["NA3"], data["NS3"], data["NM3"], data["NP3"])
            result.characteristics["dexterity"].set_values(data["NA4"], data["NS4"], data["NM4"], data["NP4"])
            result.characteristics["appearance"].set_values(data["NA5"], data["NS5"], data["NM5"], data["NP5"])
            result.characteristics["size"].set_values(data["NA6"], data["NS6"], data["NM6"], data["NP6"])
            result.characteristics["intelligence"].set_values(data["NA7"], data["NS7"], data["NM7"], data["NP7"])
            result.characteristics["education"].set_values(data["NA8"], data["NS8"], data["NM8"], data["NP8"])
            result.characteristics["hit_points"].set_values(data["NA9"], data["NS9"], data["NM9"], data["NP9"])
            result.characteristics["magic_points"].set_values(data["NA10"], data["NS10"], data["NM10"], data["NP10"])
            result.characteristics["initial_sanity"].set_values(data["NA11"], data["NS11"], data["NM11"], data["NP11"])
            result.characteristics["idea"].set_values(data["NA12"], data["NS12"], data["NM12"], data["NP12"])
            result.characteristics["luck"].set_values(data["NA13"], data["NS13"], data["NM13"], data["NP13"])
            result.characteristics["knowledge"].set_values(data["NA14"], data["NS14"], data["NM14"], data["NP14"])

            # SAN値
            result.sanity_points.current = data["SAN_Left"]
            result.sanity_points.max_insane = data["SAN_Max"]
            result.sanity_points.indef_insane = data["SAN_Danger"]

            # 技能
            result.skill_points.remaining_occupation = data["TS_Total"] # 残り職業ポイント
            result.skill_points.remaining_interest = data["TK_Total"]   # 残り興味ポイント
            result.skill_points.max_occupation = data["TS_Maximum"]     # 最大職業ポイント
            result.skill_points.max_interest = data["TK_Maximum"]       # 最大興味ポイント
            result.skill_points.additions_occupation = data["TS_Add"]   # 追加職業ポイント
            result.skill_points.additions_interest = data["TK_Add"]     # 追加興味ポイント

            # 戦闘技能
            keylists = ["dodge", "kick", "grapple", "fist_punch", "head_butt", "throw", "martial_arts", "handgun", "smg", "shotgun", "machine_gun", "rifle"]
            self.set_skills_values(result.combat_skills, keylists, data, "TBAU", "TBAD", "TBAS", "TBAK", "TBAA", "TBAO", "TBAP", "TBAName")

            # 探索技能
            keylists = ["first_aid", "locksmith", "conceal", "hide", "listen", "sneak", "photography", "psychoanalysis", "track", "climb", "library_use", "spot_hidden"]
            self.set_skills_values(result.search_skills, keylists, data, "TFAU", "TFAD", "TFAS", "TFAK", "TFAA", "TFAO", "TFAP", "TFAName")

            # 行動技能
            keylists = ["drive", "mech_repair", "opr_hvy_machine", "ride", "swim", "craft", "pilot", "jump", "electr_repair", "navigate", "disguise"]
            self.set_skills_values(result.behavioral_skills, keylists, data, "TAAU", "TAAD", "TAAS", "TAAK", "TAAA", "TAAO", "TAAP", "TAAName")

            result.behavioral_skills["drive"].skill_subname = str(data["unten_bunya"]).strip()
            result.behavioral_skills["craft"].skill_subname = str(data["seisaku_bunya"]).strip()
            result.behavioral_skills["pilot"].skill_subname = str(data["main_souju_norimono"]).strip()

            # 交渉技能
            keylists = ["fast_talk", "credit_rating", "persuade", "bargain", "own_language"]
            self.set_skills_values(result.negotiation_skills, keylists, data, "TCAU", "TCAD", "TCAS", "TCAK", "TCAA", "TCAO", "TCAP", "TCAName")

            result.negotiation_skills["own_language"].skill_subname = str(data["mylang_name"]).strip()

            # 知識技能
            keylists = ["medicine", "occult", "chemistry", "cthulhu_mythos", "art", "accounting", "archeology", "computer", "psychology",
                "anthropology", "biology", "geology", "electronics", "astronomy", "natural_history", "physics", "law", "pharmacy", "history"]
            self.set_skills_values(result.knowledge_skills, keylists, data, "TKAU", "TKAD", "TKAS", "TKAK", "TKAA", "TKAO", "TKAP", "TKAName")

            result.knowledge_skills["art"].skill_subname = str(data["geijutu_bunya"]).strip()

            # TODO:
            # 戦闘・武器・防具
            # 所持品・所持金

            # 最終更新日時
            #created_at セット済み
        return result

    @classmethod
    def set_skills_values(self, skills, defaultkeys, data, growth_checke_key, base_key, occupation_key, interest_key, growth_key, other_key, current_key, additions_name_key):
        # 配列数の取得
        skills_count = len(data[growth_checke_key])

        for index in range(skills_count):
            growth_check = (len(str(data[growth_checke_key][index]).strip()) >= 1)

            if index < len(defaultkeys):
                # デフォルトスキル
                key = defaultkeys[index]
            else:
                # 追加分スキル
                key = f'additions_{index}'

                additions_index = index - len(defaultkeys) - 1
                additions_title = str(data[additions_name_key][additions_index]).strip()

                # スキル名
                skill_name = ""
                skill_subname = ""
                match = VampireBloodNetGetter.SKILL_TITLE_SPLIT.search(additions_title)
                if match:
                    skill_name = str(match.group(1))
                    skill_subname = str(match.group(3))
                else:
                    skill_name = additions_title
                    skill_subname = ""

                skills[key] = SkillSet(skill_name, skill_subname)
                # スキルタイプ
                skills[key].skill_type = "additions"

            skills[key].set_values(
                # 成長チェック
                growth_check,
                # 初期値(基礎値)
                int(data[base_key][index] or 0),
                # 職業ポイント
                int(data[occupation_key][index] or 0),
                # 興味ポイント
                int(data[interest_key][index] or 0),
                # 成長分
                int(data[growth_key][index] or 0),
                # その他増加分
                int(data[other_key][index] or 0),
                # 現在値
                int(data[current_key][index] or 0),
            )
        return self
