import json

from rest_framework.exceptions import ValidationError
from rest_framework import status

from api.models import TtActivityTemplateStaff, TtActivityStaffPreset, TtActivityTemplateLocation, \
    TtActivityTemplateLocationSuitability, TtActivityTemplateStaffSuitability, TtActivityStaffSuitability, \
    TtActivityLocationPreset, TtActivityLocationSuitability
from api.models.role import Role
from api.models.tt_academic_term import TtAcademicTerm
from api.models.tt_activity import TtActivity
from api.models.tt_activity_template import TtActivityTemplate
from api.models.tt_activity_type import TtActivityType
from api.models.tt_availability import TtAvailability
from api.models.tt_department import TtDepartment
from api.models.tt_location import TtLocation
from api.models.tt_module import TtModule
from api.models.tt_module_group import TtModuleGroup
from api.models.tt_pathway import TtPathway
from api.models.tt_pos import TtPos
from api.models.tt_setting import TtSetting
from api.models.tt_staff import TtStaff
from api.models.tt_start_preference import TtStartPreference
from api.models.tt_student_set import TtStudentSet
from api.models.tt_student import TtStudent
from api.models.tt_suitability import TtSuitability
from api.models.tt_tag import TtTag
from api.models.tt_usage_preference import TtUsagePreference
from api.models.tt_week_pattern import TtWeekPattern
from api.models.tt_zone import TtZone
from api.models.user import User
from api.translation import __
from api.utils import log_critical_error, get_exception_detail
from api.validator import BaseValidator
from api.views.admin.base import AdminApiBase
from api.translation import __

class ImportGetInformation(AdminApiBase):
    def validate_request(self,request, import_tables):
        detination_string = ",".join(str(v) for v in import_tables)
        rules = {
            "destination": "nullable|in:"+detination_string,
        }
        # if need rename field, can put here
        attribute = {
            # "email": __("attr.email"),
        }
        # validate id first, cause need get pos by id, if wrong id direct return error
        validator = BaseValidator(request.data,rules,attribute)
        error = validator.validate()
        if error:
            raise ValidationError(error)

    def post(self, request):
        setting = TtSetting.objects.get(param="import_tables")
        if setting and setting.value:
            import_tables = json.loads(setting.value)
        else:
            return self.api_response(error="no importable tables",code=status.HTTP_400_BAD_REQUEST)

        return_data = []
        if request.data.get("destination"):
            # got destination, get rules for specific table
            self.validate_request(request, import_tables)
            destination = request.data.get("destination")

            model_map = {
                "tt_pos": TtPos,
                "tt_student_set": TtStudentSet,
                "tt_module": TtModule,
                "tt_activity_template": TtActivityTemplate,
                "tt_activity": TtActivity,
                "tt_staff": TtStaff,
                "tt_location": TtLocation,
                "tt_department": TtDepartment,
                "tt_zone": TtZone,
                "tt_suitability": TtSuitability,
                "tt_activity_type": TtActivityType,
                "tt_student": TtStudent,
                "tt_activity_template_staff": TtActivityTemplateStaff,
                "tt_activity_template_staff_s": TtActivityTemplateStaffSuitability,# using _s for suitability, cause excel sheets name got limit for 31 char only
                "tt_activity_template_location": TtActivityTemplateLocation,
                "tt_activity_template_location_s": TtActivityTemplateLocationSuitability,# using _s for suitability, cause excel sheets name got limit for 31 char only
                "tt_activity_staff_preset": TtActivityStaffPreset,
                "tt_activity_staff_s": TtActivityStaffSuitability,# using _s for suitability, cause excel sheets name got limit for 31 char only
                "tt_activity_location_preset": TtActivityLocationPreset,
                "tt_activity_location_s": TtActivityLocationSuitability,# using _s for suitability, cause excel sheets name got limit for 31 char only

                # sub import rules use parent model
                "tt_student_set_module": TtStudentSet,
                "tt_pos_module_group": TtPos,
                "tt_suitability_staff": TtSuitability,
                "tt_suitability_location": TtSuitability,
                "tt_student_set_activity": TtStudentSet,
                "tt_module_group_module": TtPos,
                "tt_booking": TtActivity,
                "tt_student_academic_term": TtStudent,
                "tt_student_pos": TtStudent,
                "tt_student_pos_module": TtStudent,
                "tt_student_set_student": TtStudent,
            }

            sub_model_map = {
                "tt_student_set_module": "STUDENT_SET_MODULE",
                "tt_pos_module_group": "POS_MODULE_GROUP",
                "tt_suitability_staff": "SUITABILITY_STAFF",
                "tt_suitability_location": "SUITABILITY_LOCATION",
                "tt_student_set_activity": "STUDENT_SET_ACTIVITY",
                "tt_module_group_module": "MODULE_GROUP_MODULE",
                "tt_booking": "BOOKING",
                "tt_student_academic_term": "STUDENT_ACADEMIC_TERM",
                "tt_student_pos": "STUDENT_POS",
                "tt_student_pos_module": "STUDENT_POS_MODULE",
                "tt_student_set_student": "STUDENT_SET_STUDENT",
            }

            table = model_map.get(destination)

            if not table:
                return self.api_response(data={}) #Response({"error": "Invalid destination"}, status=400)
            name_prefix = "import_attr."
            if destination in sub_model_map:
                config_name = sub_model_map[destination]
                import_config = getattr(table, config_name, {})
                rules = import_config.get("IMPORT_RULES", {})
            else:
                rules = getattr(table, "IMPORT_RULES", {})

            for key, value in rules.items():
                return_data.append(
                    {
                        "id": key,
                        "name": __(name_prefix + key),
                        "rules": value,
                    }
                )

        else:
            # get importable tables from setting
            setting = TtSetting.objects.get(param="import_tables")

            if setting and setting.value:
                import_tables = json.loads(setting.value)

                for table in import_tables:
                    return_data.append(
                        {
                            "table": table,
                            "name": __("db_table_name."+table)
                        }
                    )
                return_data.sort(key=lambda x: str(x["name"]))

        response = {
            "data": return_data
        }
        return self.api_response(data=response)
