import random
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views import View

from config import settings
from .forms import LoginForm, PasswordEmailForm
from .EmailBackEnd import EmailBackEnd
from django.template.loader import render_to_string 
from django.utils.html import strip_tags 
from django.core.mail import send_mail, EmailMultiAlternatives
from django.contrib import messages
from django.contrib.auth import login, logout
from .models import Csr_Partners, Partner_Organizations, Permissions, User_Departments, User_Types, Users, Letter_Boxes
from django.contrib.auth.mixins import LoginRequiredMixin
from program_department.models import Program_Types, Projects
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

# Create your views here.

class AuthenticationViews(View):

    def get(self, request):
        return render(request, "login.html", {'form' : LoginForm})


    def post(self, request):
        form = LoginForm(request.POST)
        if form.is_valid():
            user = EmailBackEnd.authenticate(request, username = form.cleaned_data['email'], password=form.cleaned_data['password'])
            if user is not None:
                if user.user_type_id == 1:
                    login(request, user)
                    return redirect('adminDashboard')
                else: 
                    login(request, user)
                    return redirect('adminDashboard')
            else:
                return render(request, "login.html", {'form' : form, 'error' : "Invalid email id or password"})
        else:
            return render(request, "login.html", {'form' : form})



class LogoutView(View):

    def get(self, request):
        logout(request)
        return redirect('login')



class UserDepartmentView(LoginRequiredMixin, View):

    def get(self, request):
        user_types = User_Types.objects.all()
        user_departments = User_Departments.objects.all()
        program_types = Program_Types.objects.all()
        projects = Projects.objects.all()
        csr_partners = Csr_Partners.objects.all()
        partner_organizations = Partner_Organizations.objects.all()
        return render(request, "users.html", {'user_types' : user_types, 'user_departments' : user_departments, 'program_types' : program_types, 'projects' : projects, 'csr_partners' : csr_partners, 'partner_organizations' : partner_organizations})
    


class UserTypeView(LoginRequiredMixin, View):
    
    def post(self, request):
        user_type = User_Types()
        user_type.user_type = request.POST['user_type']
        user_type.save()
        if(user_type.id):
            permissions = Permissions()
            permissions.user_type = user_type
            permissions.save()
            messages.success(request, "User type added successfully.")
        return redirect('userDepartmentView')
    

    def get(self, request):
        try:
            user_type = User_Types.objects.get(id=request.GET['id'])
            user_type.delete()
            messages.success(request, "User type deleted successfully.")
            return redirect('userDepartmentView')
        except User_Types.DoesNotExist:
            messages.error(request, "User type doesn't exists.")
            return redirect('userDepartmentView')




class DepartmentView(LoginRequiredMixin, View):
    
    def post(self, request):
        user_department = User_Departments()
        user_department.user_department = request.POST['department']
        user_department.save()
        return redirect('userDepartmentView')
    

    def get(self, request):
        try:
            user_department = User_Departments.objects.get(id=request.GET['id'])
            user_department.delete()
            messages.success(request, "User department deleted successfully.")
            return redirect('userDepartmentView')
        except User_Types.DoesNotExist:
            messages.error(request, "User department doesn't exists.")
            return redirect('userDepartmentView')




class CsrPartnerView(LoginRequiredMixin, View):
    
    def post(self, request):
        user = Users()
        user.email = request.POST['email']
        user.set_password(request.POST['password'])
        user.mobile = request.POST['mobile']
        username = ''.join((random.choice('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)))
        user.username = 'user-' + username
        user.is_active = 1
        user.is_superuser = 0
        user.user_type_id = 2
        user.is_staff = 0
        user.save()
        if user.id:
            csr_partner = Csr_Partners()
            csr_partner.user = user
            csr_partner.company_name = request.POST['company_name']
            csr_partner.authorised_person_name = request.POST['authorised_person_name']
            csr_partner.designation = request.POST['designation']
            csr_partner.save()
            messages.success(request, "CSR Partner added successfully.")
        return redirect('userDepartmentView')
    

    def get(self, request):
        try:
            user = Users.objects.get(id=request.GET['id'])
            user.delete()
            messages.success(request, "CSR partner deleted successfully.")
            return redirect('userDepartmentView')
        except Users.DoesNotExist:
            messages.error(request, "CSR partner doesn't exists.")
            return redirect('userDepartmentView')



class PartnerOrganizationView(LoginRequiredMixin, View):
    
    def post(self, request):
        user = Users()
        user.email = request.POST['email']
        user.set_password(request.POST['password'])
        user.mobile = request.POST['mobile']
        username = ''.join((random.choice('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)))
        user.username = 'user-' + username
        user.is_active = 1
        user.is_superuser = 0
        user.user_type_id = 3
        user.is_staff = 0
        user.save()
        if user.id:
            partner_organization = Partner_Organizations()
            partner_organization.user = user
            partner_organization.company_name = request.POST['company_name']
            partner_organization.authorised_person_name = request.POST['authorised_person_name']
            partner_organization.designation = request.POST['designation']
            partner_organization.save()
            messages.success(request, "Partner Organization added successfully.")
        else:
            messages.error(request, "Failed to add Partner Organization. Please try again.")
        return redirect('userDepartmentView')
    

    def get(self, request):
        try:
            user = Users.objects.get(id=request.GET['id'])
            user.delete()
            messages.success(request, "Partner organization deleted successfully.")
            return redirect('userDepartmentView')
        except Users.DoesNotExist:
            messages.error(request, "Partner organization doesn't exists.")
            return redirect('userDepartmentView')


    

class UserPermissionsView(LoginRequiredMixin, View):

    def get(self, request, id=1):
        permission = Permissions.objects.get(user_type_id = int(id))
        user_types = User_Types.objects.all()
        return render(request, "permissions.html", {'permission' : permission, 'id' : id, 'user_types' : user_types})


    def post(self, request, id):
        try:
            print(request.POST)
            permissions = Permissions.objects.get(user_type_id=id)
            permissions.admin_department_user_type_view = request.POST.get('admin_department_user_type_view') if request.POST.get('admin_department_user_type_view') else 0
            permissions.admin_department_user_type_add = request.POST.get('admin_department_user_type_add') if request.POST.get('admin_department_user_type_add') else 0
            permissions.admin_department_user_type_delete = request.POST.get('admin_department_user_type_delete') if request.POST.get('admin_department_user_type_delete') else 0
            permissions.admin_department_user_department_view = request.POST.get('admin_department_user_department_view') if request.POST.get('admin_department_user_department_view') else 0
            permissions.admin_department_user_department_add = request.POST.get('admin_department_user_department_add') if request.POST.get('admin_department_user_department_add') else 0
            permissions.admin_department_user_department_delete = request.POST.get('admin_department_user_department_delete') if request.POST.get('admin_department_user_department_delete') else 0
            permissions.admin_department_program_view = request.POST.get('admin_department_program_view') if request.POST.get('admin_department_program_view') else 0
            permissions.admin_department_project_view = request.POST.get('admin_department_project_view') if request.POST.get('admin_department_project_view') else 0
            permissions.admin_department_project_add = request.POST.get('admin_department_project_add') if request.POST.get('admin_department_project_add') else 0
            permissions.admin_department_project_delete = request.POST.get('admin_department_project_delete') if request.POST.get('admin_department_project_delete') else 0
            permissions.admin_department_letter_box_view = request.POST.get('admin_department_letter_box_view') if request.POST.get('admin_department_letter_box_view') else 0
            permissions.admin_department_letter_box_add = request.POST.get('admin_department_letter_box_add') if request.POST.get('admin_department_letter_box_add') else 0
            permissions.admin_department_letter_box_edit = request.POST.get('admin_department_letter_box_edit') if request.POST.get('admin_department_letter_box_edit') else 0
            permissions.admin_department_letter_box_delete = request.POST.get('admin_department_letter_box_delete') if request.POST.get('admin_department_letter_box_delete') else 0

            permissions.program_department_program_view = request.POST.get('program_department_program_view') if request.POST.get('program_department_program_view') else 0
            permissions.program_department_program_add = request.POST.get('program_department_program_add') if request.POST.get('program_department_program_add') else 0
            permissions.program_department_program_edit = request.POST.get('program_department_program_edit') if request.POST.get('program_department_program_edit') else 0
            permissions.program_department_program_delete = request.POST.get('program_department_program_delete') if request.POST.get('program_department_program_delete') else 0
            permissions.program_department_program_import = request.POST.get('program_department_program_import') if request.POST.get('program_department_program_import') else 0
            permissions.program_department_program_export = request.POST.get('program_department_program_export') if request.POST.get('program_department_program_export') else 0
            permissions.program_department_deliverables_view = request.POST.get('program_department_deliverables_view') if request.POST.get('program_department_deliverables_view') else 0
            permissions.program_department_deliverables_import = request.POST.get('program_department_deliverables_import') if request.POST.get('program_department_deliverables_import') else 0
            permissions.program_department_deliverables_export = request.POST.get('program_department_deliverables_export') if request.POST.get('program_department_deliverables_export') else 0

            permissions.hr_department_team_registration_view = request.POST.get('hr_department_team_registration_view') if request.POST.get('hr_department_team_registration_view') else 0
            permissions.hr_department_team_registration_add = request.POST.get('hr_department_team_registration_add') if request.POST.get('hr_department_team_registration_add') else 0
            permissions.hr_department_team_registration_edit = request.POST.get('hr_department_team_registration_edit') if request.POST.get('hr_department_team_registration_edit') else 0
            permissions.hr_department_team_registration_delete = request.POST.get('hr_department_team_registration_delete') if request.POST.get('hr_department_team_registration_delete') else 0
            permissions.hr_department_attendance_view = request.POST.get('hr_department_attendance_view') if request.POST.get('hr_department_attendance_view') else 0
            permissions.hr_department_attendance_add = request.POST.get('hr_department_attendance_add') if request.POST.get('hr_department_attendance_add') else 0
            permissions.hr_department_attendance_delete = request.POST.get('hr_department_attendance_delete') if request.POST.get('hr_department_attendance_delete') else 0

            permissions.hr_department_vendor_registration_view = request.POST.get('hr_department_vendor_registration_view') if request.POST.get('hr_department_vendor_registration_view') else 0
            permissions.hr_department_vendor_registration_add = request.POST.get('hr_department_vendor_registration_add') if request.POST.get('hr_department_vendor_registration_add') else 0
            permissions.hr_department_vendor_registration_edit = request.POST.get('hr_department_vendor_registration_edit') if request.POST.get('hr_department_vendor_registration_edit') else 0
            permissions.hr_department_vendor_registration_delete = request.POST.get('hr_department_vendor_registration_delete') if request.POST.get('hr_department_vendor_registration_delete') else 0

            permissions.finance_department_income_view = request.POST.get('finance_department_income_view') if request.POST.get('finance_department_income_view') else 0
            permissions.finance_department_income_add = request.POST.get('finance_department_income_add') if request.POST.get('finance_department_income_add') else 0
            permissions.finance_department_income_edit = request.POST.get('finance_department_income_edit') if request.POST.get('finance_department_income_edit') else 0
            permissions.finance_department_income_delete = request.POST.get('finance_department_income_delete') if request.POST.get('finance_department_income_delete') else 0
            permissions.finance_department_income_export = request.POST.get('finance_department_income_export') if request.POST.get('finance_department_income_export') else 0
            permissions.finance_department_expenditure_view = request.POST.get('finance_department_expenditure_view') if request.POST.get('finance_department_expenditure_view') else 0
            permissions.finance_department_expenditure_add = request.POST.get('finance_department_expenditure_add') if request.POST.get('finance_department_expenditure_add') else 0
            permissions.finance_department_expenditure_edit = request.POST.get('finance_department_expenditure_edit') if request.POST.get('finance_department_expenditure_edit') else 0
            permissions.finance_department_expenditure_delete = request.POST.get('finance_department_expenditure_delete') if request.POST.get('finance_department_expenditure_delete') else 0
            permissions.finance_department_expenditure_export = request.POST.get('finance_department_expenditure_export') if request.POST.get('finance_department_expenditure_export') else 0

            permissions.save()
            messages.success(request, "Permissions updated successfully.")
            return redirect('userPermissions', id=id)
        except Permissions.DoesNotExist:
            messages.error(request, "Permissions for this user type do not exist.")
            return redirect('userPermissions', id=id)        



class LetterBoxView(LoginRequiredMixin, View):

    def get(self, request):
        user_departments = User_Departments.objects.all()
        letter_box = Letter_Boxes.objects.all()
        return render(request, "letter-box.html", {'user_departments' : user_departments, 'letter_box' : letter_box})

    def post(self, request):
        letter_box = Letter_Boxes()
        letter_box.receipt_type = request.POST['receipt_type']
        letter_box.date = request.POST['date']
        letter_box.letter_box = request.POST.get('letter_box')
        letter_box.name = request.POST.get('name')
        letter_box.department_id = request.POST.get('department')
        letter_box.reference_no = request.POST.get('reference_no')
        letter_box.letter_type = request.POST.get('letter_type')
        letter_box.subject = request.POST.get('subject')
        letter_box.description = request.POST.get('description')
        letter_box.pdf = request.FILES.get('pdf')
        letter_box.save()
        messages.success(request, "Letter Box entry added successfully.")
        return redirect('letterBox')



class LetterView(LoginRequiredMixin, View):

    def get(self, request, id):
        try:
            letter = Letter_Boxes.objects.get(id = id)
            letter.delete()
            messages.success(request, "Letter Box entry deleted successfully.")
            return redirect('letterBox')
        except Letter_Boxes.DoesNotExist:
            messages.error(request, "Letter Box entry does not exist.")
            return redirect('letterBox')
        

    def post(self, request, id):
        try:
            letter = Letter_Boxes.objects.get(id = id)
            letter.receipt_type = request.POST['receipt_type']
            letter.date = request.POST['date']
            letter.letter_box = request.POST.get('letter_box')
            letter.name = request.POST.get('name')
            letter.department_id = request.POST.get('department')
            letter.reference_no = request.POST.get('reference_no')
            letter.letter_type = request.POST.get('letter_type')
            letter.subject = request.POST.get('subject')
            letter.description = request.POST.get('description')
            if 'pdf' in request.FILES:
                letter.pdf = request.FILES.get('pdf')
            letter.save()
            messages.success(request, "Letter Box entry added successfully.")
            return redirect('letterBox')
        except Letter_Boxes.DoesNotExist:
            messages.error(request, "Letter Box entry does not exist.")
            return redirect('letterBox')



class ForgotPassword(View):

    def get(self, request):
        return render(request, "forgot-password.html", {'form' : PasswordEmailForm})   


@csrf_exempt
def sendOtp(request):
    try:
        user = Users.objects.get(email = request.POST.get('email'))
        otp = ''.join((random.choice('1234567890') for i in range(4)))
        request.session['otp'] = otp
        request.session['user_id'] = user.id  
        subject = "MIS Portal OTP request"
        to_email = [user.email]
        html_template = render_to_string("otp-template.html", {'logo' : settings.LOGO_URL, 'name' : user.name,  'otp' : otp})    
        text_content = strip_tags(html_template)
        email = EmailMultiAlternatives(subject, text_content, settings.EMAIL_HOST_USER, to_email)
        email.attach_alternative(html_template, "text/html")
        email.send()
        return JsonResponse({'message' : "OTP sent to registered Email", 'status':200}, safe=False)
    except Users.DoesNotExist:
        return JsonResponse({'message' : "Invalid email id.", 'status':400}, safe=False)
    except Exception as e:
        return JsonResponse({'message' : "Something went wrong. Please try again later.", 'status':400}, safe=False)


@csrf_exempt
def verifyOtp(request):
    otp = request.POST.get('otp')
    if(otp == request.session['otp']):
        return JsonResponse({'message' : "OTP Matched", 'status':200}, safe=False)
    else:
        return JsonResponse({'message' : "OTP Not Matched", 'status':400}, safe=False)


@csrf_exempt
def changePassword(request):
    try:
        password = request.POST.get('password')
        user = Users.objects.get(id = request.session['user_id'])
        user.set_password(password)
        user.save()
        return JsonResponse({'message':"password changed succesfully", 'status':200}, safe=False)
    except Users.DoesNotExist:
        return JsonResponse({'message':"User does't exist", 'status':400}, safe=False)
    except Exception as e:
        return JsonResponse({'message':"Something went wrong. Please try again later.", 'status':400}, safe=False, status=400)
    