# SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
#
# SPDX-License-Identifier: AGPL-3.0-or-later

import unittest
import json

from app import app
from ki.models import User
from ki.test.ApiTest import ApiTest


class TestProfileEndpoint(ApiTest):
    maxDiff = None

    def test_update_profile_unauthorised(self):
        login_data = {"username": "klaus", "password": "jutta"}
        login_response = self.client.post("/users/login", data=json.dumps(login_data), content_type="application/json")

        self.assertEqual(login_response.status_code, 200)
        self.assertIn("token", login_response.json)

        babsi = User.query.filter(User.auth_id == "babsi1").first()
        response = self.client.post(f"/users/{babsi.id}/profile",
                                    data=json.dumps({}),
                                    content_type="application/json",
                                    headers={"Authorization": "Bearer " + login_response.json["token"]})

        self.assertEqual(response.status_code, 403)

    def test_update_profile(self):
        token = self.login("peter", "geheim")["token"]

        data = {
            "nickname": "Hebbert",
            "pronouns": "Monsieur",
            "volunteerwork": "ja",
            "availability_status": False,
            "availability_text": "Nie",
            "availability_hours_per_week": "23",
            "freetext": "Hallo",
            "visible": True,
            "address": {
                "name": "Peeeda",
                "street": "Bachstraße",
                "house_number": "42x",
                "additional": "oben",
                "postcode": "23232",
                "city": "Travemünde",
                "country": "Deutschland"
            },
            "contacts": [{
                "id": 1,
                "contacttype": {
                    "id": 4,
                    "name": "Matrix"
                },
                "content": "@peeda:wtf-eg.de"
            }, {
                "contacttype": {
                    "name": "Rohrpost"
                },
                "content": "Ausgang 2"
            }],
            "skills": [{
                "id": 1,
                "skill": {
                    "id": 3,
                    "name": "Python"
                },
                "level": 4
            }, {
                "skill": {
                    "name": "Tschunkproduktion"
                },
                "level": 5
            }],
            "searchtopics": [{
                "profile_id": 1,
                "skill": {
                    "id": 3,
                    "name": "Python",
                    "icon_url": "/skills/3/icon"
                }
            }, {
                "profile_id": 1,
                "skill": {
                    "name": "Assembler"
                }
            }],
            "languages": [{
                "id": 1,
                "language": {
                    "id": "de",
                    "name": "Deutsch"
                },
                "level": 4
            }, {
                "language": {
                    "id": "es",
                    "name": "Spanisch"
                },
                "level": 2
            }]
        }
        peter = User.query.filter(User.auth_id == "peter").first()
        response = self.client.post(f"/users/{peter.id}/profile",
                                    data=json.dumps(data),
                                    content_type="application/json",
                                    headers={"Authorization": "Bearer " + token})

        self.assertEqual(response.status_code, 200)
        with app.app_context():
            user = User.query.filter(User.id == peter.id).first()
            profile = user.profile
            self.assertEqual("Hebbert", profile.nickname)
            self.assertEqual("Monsieur", profile.pronouns)
            self.assertEqual("ja", profile.volunteerwork)
            self.assertEqual(False, profile.availability_status)
            self.assertEqual("Nie", profile.availability_text)
            self.assertEqual(23, profile.availability_hours_per_week)
            self.assertEqual("Hallo", profile.freetext)
            self.assertTrue(profile.visible)

            address = profile.address
            self.assertEqual(address.name, "Peeeda")
            self.assertEqual(address.street, "Bachstraße")
            self.assertEqual(address.house_number, "42x")
            self.assertEqual(address.additional, "oben")
            self.assertEqual(address.postcode, "23232")
            self.assertEqual(address.city, "Travemünde")
            self.assertEqual(address.country, "Deutschland")

            contacts = profile.contacts
            self.assertEqual(len(contacts), 2)

            first_contact = contacts[0]
            self.assertEqual(first_contact.contacttype.name, "Matrix")
            self.assertEqual(first_contact.content, "@peeda:wtf-eg.de")

            second_contact = contacts[1]
            self.assertEqual(second_contact.contacttype.name, "Rohrpost")
            self.assertEqual(second_contact.content, "Ausgang 2")

            skills = profile.skills
            self.assertEqual(len(skills), 2)

            first_skill = skills[0]
            self.assertEqual(first_skill.skill.id, 3)
            self.assertEqual(first_skill.skill.name, "Python")
            self.assertEqual(first_skill.level, 4)

            second_skill = skills[1]
            self.assertEqual(second_skill.skill.id, self.max_skill_id + 1)
            self.assertEqual(second_skill.skill.name, "Tschunkproduktion")
            self.assertEqual(second_skill.level, 5)

            searchtopics = profile.searchtopics
            self.assertEqual(len(searchtopics), 2)

            first_searchtopic = searchtopics[0]
            self.assertEqual(first_searchtopic.skill.id, 3)
            self.assertEqual(first_searchtopic.skill.name, "Python")

            second_searchtopic = searchtopics[1]
            self.assertEqual(second_searchtopic.skill.id, self.max_skill_id + 2)
            self.assertEqual(second_searchtopic.skill.name, "Assembler")

            languages = profile.languages
            self.assertEqual(len(languages), 2)

            first_language = languages[0]
            self.assertEqual(first_language.language_id, "de")
            self.assertEqual(first_language.level, 4)

            second_language = languages[1]
            self.assertEqual(second_language.language_id, "es")
            self.assertEqual(second_language.level, 2)

    def test_get_profile_unauthorised(self):

        response = self.client.get("/users/1/profile")
        self.assertEqual(response.status_code, 401)

    def test_get_visible_proifle(self):
        token = self.login("peter", "geheim")["token"]

        babsi = User.query.filter(User.auth_id == "babsi1").first()
        response = self.client.get(f"/users/{babsi.id}/profile", headers={"Authorization": f"Bearer {token}"})

        self.assertEqual(response.status_code, 200)

    def test_get_own_profile(self):
        login_data = {"username": "peter", "password": "geheim"}
        login_response = self.client.post("/users/login", data=json.dumps(login_data), content_type="application/json")

        self.assertEqual(login_response.status_code, 200)
        self.assertIn("token", login_response.json)

        peter = User.query.filter(User.auth_id == "peter").first()
        response = self.client.get(f"/users/{peter.id}/profile",
                                   headers={"Authorization": "Bearer " + login_response.json["token"]})
        profile_id = peter.profile.id
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(
            response.json, {
                "profile": {
                    "user_id": peter.id,
                    "nickname": "peternichtlustig",
                    "pronouns": "Herr Dr. Dr.",
                    "availability_status": True,
                    "availability_hours_per_week": 42,
                    "availability_text": "Immer",
                    "freetext": "Ich mag Kaffee",
                    "volunteerwork": "Gartenverein",
                    "visible": False,
                    "address": {
                        "additional": "Hinterhaus",
                        "city": "Bielefeld",
                        "country": "Deutschland",
                        "house_number": "23i",
                        "id": 1,
                        "name": "Peter Nichtlustig",
                        "postcode": "13337",
                        "profile_id": profile_id,
                        "street": "Waldweg"
                    },
                    "contacts": [{
                        "id": 1,
                        "profile_id": profile_id,
                        "contacttype": {
                            "id": 4,
                            "name": "Matrix"
                        },
                        "content": "@peter:wtf-eg.de"
                    }, {
                        "id": 2,
                        "profile_id": profile_id,
                        "contacttype": {
                            "id": 1,
                            "name": "E-Mail"
                        },
                        "content": "peter@wtf-eg.de"
                    }],
                    "skills": [{
                        "profile_id": profile_id,
                        "skill": {
                            "id": 1,
                            "name": "PHP",
                            "icon_url": "/skills/1/icon"
                        },
                        "level": 5
                    }, {
                        "profile_id": profile_id,
                        "skill": {
                            "id": 3,
                            "name": "Python",
                            "icon_url": "/skills/3/icon"
                        },
                        "level": 3
                    }],
                    "searchtopics": [{
                        "profile_id": profile_id,
                        "skill": {
                            "id": 1,
                            "name": "PHP",
                            "icon_url": "/skills/1/icon"
                        }
                    }, {
                        "profile_id": profile_id,
                        "skill": {
                            "id": 3,
                            "name": "Python",
                            "icon_url": "/skills/3/icon"
                        }
                    }],
                    "languages": [{
                        "profile_id": profile_id,
                        "language": {
                            "id": "de",
                            "name": "Deutsch",
                            "icon_url": "/languages/de/icon"
                        },
                        "level": 5
                    }, {
                        "profile_id": profile_id,
                        "language": {
                            "id": "fr",
                            "name": "Französisch",
                            "icon_url": "/languages/fr/icon"
                        },
                        "level": 3
                    }]
                }
            })


if __name__ == "main":
    unittest.main()