from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from .models import *
from django.contrib import messages
from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.core.files.storage import FileSystemStorage
from django.urls import reverse
from django.core.paginator import Paginator
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from django.conf import settings
import subprocess
import shlex
import os
# Create your views here.


def get_company_data():
    context = {}
    company_name = Setting.objects.filter(name="update_within_company_name").values_list('value',flat=True).first()
    company_logo = Setting.objects.filter(name="update_within_company_logo").values_list('value',flat=True).first()
    company_number = Setting.objects.filter(name="update_within_company_number").values_list('value',flat=True).first()
    company_email = Setting.objects.filter(name="update_within_company_email").values_list('value',flat=True).first()
    company_image = Setting.objects.filter(name="update_within_company_image").values_list('value',flat=True).first()
    context['company_name'] = company_name
    context['company_logo'] = company_logo
    context['company_number'] = company_number
    context['company_email'] = company_email
    context['company_image'] = company_image
    return context


def get_company_data2(request):
    # context = {}
    company_name = Setting.objects.filter(name="update_within_company_name").values_list('value',flat=True).first()
    company_logo = Setting.objects.filter(name="update_within_company_logo").values_list('value',flat=True).first()
    company_number = Setting.objects.filter(name="update_within_company_number").values_list('value',flat=True).first()
    company_email = Setting.objects.filter(name="update_within_company_email").values_list('value',flat=True).first()
    company_image = Setting.objects.filter(name="update_within_company_image").values_list('value',flat=True).first()

     # Example code:
    company_data = {
        'company_name': company_name,
        'company_image': company_image,
        'company_logo': company_logo,
        'company_number':company_number,
        'company_email':company_email
    }
    
    return JsonResponse(company_data)


class SettingView(LoginRequiredMixin,View):

    def get(self, request):
        company_data = get_company_data()
        range = Setting.objects.filter(name="update_within_range").values("value")
        if range[0] == "":
            range =None
        range_status = Setting.objects.filter(name="update_within_range_status").values("value")
        if range_status[0]['value'] =="":
            range_status=None
        update_within_company_name = Setting.objects.filter(name="update_within_company_name").values("value")
        if update_within_company_name =="":
            update_within_company_name =None
        update_within_company_logo = Setting.objects.filter(name="update_within_company_logo").values("value")
    
        # if update_within_company_logo :
            # logo = update_within_company_logo[0]['logo'].split("/")[1]
        update_within_company_email = Setting.objects.filter(name="update_within_company_email").values("value")
        if update_within_company_email == "":
            update_within_company_email =None
        update_within_company_number = Setting.objects.filter(name="update_within_company_number").values("value")
        update_within_company_image = Setting.objects.filter(name="update_within_company_image").values("value")
        if update_within_company_number == "":
            update_within_company_number =None
        
        update_siteinput = Setting.objects.filter(name="update_siteinput").values("value")
        
        context = {"range":range[0],"range_status":range_status[0]['value'],"update_within_company_name":update_within_company_name[0],"update_within_company_logo":update_within_company_logo[0],"update_within_company_email":update_within_company_email[0],"update_within_company_number":update_within_company_number[0], 
        "update_siteinput":update_siteinput[0]['value'],                           
        "update_within_company_image":update_within_company_image[0],"title":"Settings",
        "company_data":company_data}
        return render(request, 'menu/settings/setting.html', context)
    
    # @csrf_exempt
    def post(self, request):
        if request.method == "POST":

            range_status = request.POST.get('range_status',None)
            range = request.POST.get('range')
            company_name = request.POST.get('company_name',None)
            company_logo = request.FILES.get('company_logo',None)
            company_email = request.POST.get('company_email',None)
            company_number = request.POST.get('company_phone_no',None)
            company_image = request.FILES.get('company_image',None)
            siteupdate = request.POST.get('editor')

            
            if range_status:
                Setting.objects.filter(name="update_within_range_status").update(value=range_status)
            if range:
                Setting.objects.filter(name="update_within_range").update(value=range)
            if company_name:
                Setting.objects.filter(name="update_within_company_name").update(value=company_name)
            if company_email:
                Setting.objects.filter(name="update_within_company_email").update(value=company_email)
            if company_number:
                Setting.objects.filter(name="update_within_company_number").update(value=company_number)
           
            Setting.objects.filter(name="update_siteinput").update(value=siteupdate)
            if company_logo:
                
                file_data = Setting.objects.filter(name="update_within_company_logo")
                db_file_name = file_data.values('value').first()
    
                fs = FileSystemStorage()

                if db_file_name['value'] not in ['',None]:
                    fs.delete(db_file_name['value'])    
                    
                filename = fs.save(company_logo.name, company_logo)

                Setting.objects.filter(name="update_within_company_logo").update(value=filename)
            
            if company_image:
                
                file_data = Setting.objects.filter(name="update_within_company_image")
                db_file_name = file_data.values('value').first()
    
                fs = FileSystemStorage()

                if db_file_name['value'] not in ['',None]:
                    fs.delete(db_file_name['value'])    
                    
                filename = fs.save(company_image.name, company_image)

                Setting.objects.filter(name="update_within_company_image").update(value=filename)
            return redirect('settings')
        else:
            return redirect('menu/settings/setting.html.html')
    
class database_backup(LoginRequiredMixin,View):
   def get(self, request):
        pages = request.GET.get('page_count', 10)  # Default page count if not specified
        order_by = request.GET.get('order_by', 'id')  # Default sort field if not specified
        sort_order = request.GET.get('sort_order', 'asc')  # Default sort order if not specified

        page_list = [10, 20, 50, 100, 500]
        databases = DatabaseBackup.objects.all().order_by(order_by, '-id')

        if sort_order == 'desc':
            databases = databases.reverse()

        if int(pages) in page_list:
            page_passed = pages
        else:
            page_passed = 10

        # count = len(databases)
        paginator = Paginator(databases, page_passed)
        page_number = request.GET.get('page', 1)
        page_obj = paginator.get_page(page_number)

        # Calculate the starting serial number for the current page
        serial_number = (page_obj.number - 1) * page_obj.paginator.per_page + 1

        # Add serial numbers to each state in the current page
        for state in page_obj:
            state.serial_number = serial_number
            serial_number += 1

        context = {
            "page_obj": page_obj,
            "title": "Databases",
            "company_data": get_company_data(),
            "order_by": order_by,
            "sort_order": sort_order,
        }

        return render(request, 'menu/database/database.html', context)
   
def download_file(name):
    # Specify the path to your Google Drive API credentials JSON file
        credentials_path = settings.DRIVE_API

        creds = service_account.Credentials.from_service_account_file(credentials_path)
        service = build('drive', 'v3', credentials=creds)

        response = service.files().list(q=f"name='{name}'", fields="files(id)").execute()
        file_id = response['files'][0]['id']

        request = service.files().get_media(fileId=file_id)
        file_stream = open(name, 'wb')
        downloader = MediaIoBaseDownload(file_stream, request)

        done = False
        while not done:
            status, done = downloader.next_chunk()
   


# Import Database
def import_mysql(request,name):
    try:
        # Specify your database configuration
        db_name = settings.DATABASES['default']['NAME']
        db_user = settings.DATABASES['default']['USER']
        db_password = settings.DATABASES['default']['PASSWORD']
        db_host = settings.DATABASES['default']['HOST']
        db_port = settings.DATABASES['default']['PORT']

        download_file(name)
        escaped_password = shlex.quote(db_password)
        # Construct the command to import the SQL file using the mysql command-line tool
        command = f"mysql -h {db_host} -u {db_user} -p{escaped_password} {db_name} < {name}"

        try:
            subprocess.run(command, shell=True, check=True)
            # messages.add_message(request, messages.SUCCESS, 'SQL file imported successfully.')
            messages.success(request, 'SQL file imported successfully')
            # messages.success(request, "SQL file imported successfully.")
        except subprocess.CalledProcessError as e:
            # messages.add_message(request, messages.error,f"Error: {e}")
            messages.error(request, f"Error: {e}")
            
        os.remove(name)
        # return HttpResponse("Data imported successfully.")
        return redirect('database_backup')

    
    except Exception as ex:
        os.remove(name)
        messages.error(request, f"Error: {ex}")
        return HttpResponse("An error occurred.", status=500)
            


    
