from __init__ import *
from admin.forms.forms import *
from werkzeug.security import generate_password_hash, check_password_hash
from sqlalchemy.orm.attributes import flag_modified
from sqlalchemy import and_
from datetime import date, timedelta
from models import *
# from oldModel import *
from functions.functions import *
from pytube import extract
from PIL import Image
import secrets
import string

def make_vehicle_slugs():
    cars = CarMake.query.all()
    cs = []
    for car in cars:
        car.slug = makeSlug(car.name)
        cs.append(
            f"MAKE -- {car.name} --- {car.slug} ---DONE"
        )
        for model in car.models:
            model.slug = makeSlug(model.name)
            db.session.commit()
            cs.append(
                f"      MODEl -- {model.name} --- {model.slug} ---DONE"
            )
        db.session.commit()
        
    return cs

def generate_password(length=12):
    characters = string.ascii_letters + string.digits + string.punctuation
    password = ''.join(secrets.choice(characters) for _ in range(length))
    return password

# from fpdf import FPDF, HTMLMixin
def submitForm(form):
    print(form)
    return True


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def generate_username(email, staff_id):
    username = email.split('@')[0]
    username = username.replace('.', '_')
    username = re.sub(r'\W+', '', username)
    return f"{username.lower()}{staff_id}"

def imageUpload(file):
    if file and allowed_file(file.filename):
        try:
            filename = secure_filename(file.filename)
            image = Image.open(file)
            width, height = image.size

            # Resize if needed (currently using original size)
            new_size = (width, height)
            compressed_image = image.resize(new_size, Image.ANTIALIAS)

            # Build safe save path
            upload_folder = current_app.config['UPLOAD_FOLDER']
            os.makedirs(upload_folder, exist_ok=True)  # Ensure folder exists

            save_path = os.path.join(upload_folder, filename)
            compressed_image.save(save_path, quality=85)

            return filename  # or save_path if you want full path
        except Exception as e:
            return None
    return None

class MainApp():
    def index(self):
        return make_response(render_template('index.html'))
    
    def dashboard(self):
        return make_response(render_template('dashboard.html'))
    
    def addListing(self):
        return make_response(render_template('addListing.html'))
    
# class myAdmin():
@login_required
def admin_slider_hide(id):
    slider = SliderModel.query.filter_by(id=id).first()
    status = request.args.get('status')
    slider.active = False if status == 'True' else True
    flash('Slider updated successfully', 'success')
    return redirect(url_for('admin_slider'))

@login_required
def admin_slider_delete(id):
    slider = SliderModel.query.filter_by(id=id).first()
    db.session.delete(slider)
    db.session.commit()
    flash('Slider deleted successfully', 'success')
    return redirect(url_for('admin_slider'))



@login_required
def admin_slider():
    form = SliderForm()
    if form.validate_on_submit():
        video_id = extract.video_id(form.youtube.data) if form.youtube.data else None
        file = request.files.get('image')
        message = form.message.data
        new = SliderModel(
            message=message,
            image=imageUpload(file),
            link=form.link.data,
            youtube=video_id,
            author_id=current_user.id
        )
        db.session.add(new)
        db.session.commit()
        flash('Slider posted successfully', 'success')
    sliders = SliderModel.query.all()
    return render_template('admin/pages/slider.html', form=form, sliders=sliders)

@login_required
def delete_staff(id):
    item = Staff.query.filter(Staff.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def admin_staff():
    form = StaffForm()
    form.department_id.choices = [(select.id, select.name) for select in Department.query.all()]
    if form.validate_on_submit():
        first_name = form.first_name.data
        last_name = form.last_name.data
        email = form.email.data
        phone_number = form.phone_number.data
        new = Staff(
            first_name = first_name,
            last_name = last_name,
            email = email,
            phone_number = phone_number,
            hire_date = form.hire_date.data,
            department_id = form.department_id.data
        )
        db.session.add(new)
        db.session.commit()
        if form.has_account.data:
            password = generate_password()
            username = generate_username(email, new.id)
            new_user = Users(
                username = username,
                email = email,
                post = 'Admin',
                email_verified = True,
                firstname = first_name,
                lastname = last_name,
                password = generate_password_hash(password),
                staff_id = new.id
            )
            db.session.add(new_user)
            db.session.commit()
            
            msg = Message(f'New Account for {first_name}', sender = 'admin@carsoko.co.ke', recipients = [email])
            # msg.body = "Hello Flask message sent from Flask-Mail"
            
            # You can also use msg.html to send html templates!
            # Example:
            msg.html = render_template("admin/mail/new-user.html", 
                                       firstname = first_name, 
                                       lastname=last_name,
                                       password = password,
                                       username = username,
                                       email = email) # Template should be in 'templates' folder
            
            
            
            mail.send(msg)
            flash(f'Account has been created for {form.first_name.data}', 'info')
        flash('Staff added successfully', 'success')
    staff = Staff.query.all()
    return render_template('admin/pages/staff/staff.html', form=form, staff = staff)
@login_required
def delete_department(id):
    item = Department.query.filter(Department.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def admin_departments():
    form = DepartmentForm()
    if form.validate_on_submit():
        new = Department(
            name = form.name.data,
            director = form.director.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Department added successfully', 'success')
    departments = Department.query.all()
    return render_template('admin/pages/staff/departments.html', form=form, departments = departments)

@login_required
def delete_listing(id):
    listing = Listing.query.filter(Listing.id == id).first()
    db.session.delete(listing)
    db.session.commit()
    flash('Deleted successfully', 'success')
    return redirect(request.referrer)

@login_required
def mark_featured_listing(id):
    listing = Listing.query.filter(Listing.id == id).first()
    listing.featured = False if listing.featured else True
    db.session.commit()
    flash('Featured successfully', 'success')
    return redirect(request.referrer)
    
@login_required
def featured_listing():
    page = int(request.args.get('page', 1))
    limit = 20
    next_offset = limit * page
    offset = next_offset - limit
    cars = Listing.query.filter(Listing.featured == True).order_by(Listing.id.desc())
    count = cars.count()
    
    cars = cars.limit(limit).offset(offset).all()
    pages = count/limit
    form = ChangeStatus()
    form.status.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarStatus.query.all()]
    last_page = False
    pages_count = pages if type(pages) is int else int(pages)+1
    if page == pages_count:
        last_page = True
    return render_template('admin/pages/all-listing.html', 
                           cars = cars,
                           last_page = last_page, form = form)
@login_required
def status_change(id):
    listing = Listing.query.filter(Listing.id == id).first()
    listing.status = request.form.get('status')
    db.session.commit()
    flash('Status Changed Successfully', 'success')
    return redirect(request.referrer)
@login_required
def all_listing():
    page = int(request.args.get('page', 1))
    limit = 20
    next_offset = limit * page
    offset = next_offset - limit
    cars = Listing.query.order_by(Listing.id.desc())
    count = cars.count()
    
    cars = cars.limit(limit).offset(offset).all()
    pages = count/limit
    last_page = False
    pages_count = pages if type(pages) is int else int(pages)+1
    form = ChangeStatus()
    form.status.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarStatus.query.all()]
    if page == pages_count:
        last_page = True
    return render_template('admin/pages/all-listing.html', 
                           cars = cars,
                           last_page = last_page, form = form)
    


def is_valid_kenyan_phone(number: str) -> bool:
    """
    Validates if the given number is a valid Kenyan phone number.
    
    Acceptable formats:
    - 07XXXXXXXX
    - 01XXXXXXXX
    - +2547XXXXXXXX
    - +2541XXXXXXXX
    - 2547XXXXXXXX
    - 2541XXXXXXXX
    """
    import re
    
    # Remove spaces, dashes, or parentheses
    cleaned = re.sub(r"[^\d+]", "", number)
    
    # Regex patterns for validation
    patterns = [
        r"^07\d{8}$",          # 07XXXXXXXX
        r"^01\d{8}$",          # 01XXXXXXXX
        r"^\+2547\d{8}$",      # +2547XXXXXXXX
        r"^\+2541\d{8}$",      # +2541XXXXXXXX
        r"^2547\d{8}$",        # 2547XXXXXXXX
        r"^2541\d{8}$",        # 2541XXXXXXXX
    ]
    
    return any(re.match(pattern, cleaned) for pattern in patterns) 

# @app.route('/migrate-blog-posts', methods=['GET'])
# def migrate_blog_posts():
#     try:
#         old_posts = OldPosts.query.all()
#         if not old_posts:
#             return jsonify({"status": "success", "message": "No old posts found."})

#         migrated_posts = 0
#         migrated_comments = 0

#         for old_post in old_posts:
#             # ✅ Check if a post with the same title already exists
#             new_post = BlogArticles.query.filter_by(title=old_post.title).first()
#             if not new_post:
#                 # Convert author to ID if possible, otherwise None
#                 try:
#                     author_id = int(old_post.author) if old_post.author and old_post.author.isnumeric() else None
#                 except:
#                     author_id = None

#                 new_post = BlogArticles(
#                     title=old_post.title,
#                     image=old_post.image,
#                     article=old_post.content,
#                     author_id=author_id,
#                     likes=old_post.likes or 0,
#                     active=True,
#                     date=old_post.date or datetime.now()
#                 )

#                 db.session.add(new_post)
#                 db.session.flush()  # Get new_post.id before commit
#                 migrated_posts += 1

#             # ✅ Now migrate comments for this post
#             old_comments = OldComments.query.filter_by(post_id=old_post.id).all()
#             for oc in old_comments:
#                 # ✅ Check if comment with same email & content exists for this post
#                 existing_comment = Comment.query.filter_by(
#                     post_id=new_post.id,
#                     content=oc.comment,
#                     email=oc.email
#                 ).first()

#                 if not existing_comment:
#                     new_comment = Comment(
#                         content=oc.comment or "",
#                         email=oc.email or "",
#                         name=oc.name or "Anonymous",
#                         post_id=new_post.id
#                     )
#                     db.session.add(new_comment)
#                     migrated_comments += 1

#         db.session.commit()

#         return jsonify({
#             "status": "success",
#             "migrated_posts": migrated_posts,
#             "migrated_comments": migrated_comments
#         })

#     except Exception as e:
#         db.session.rollback()
#         return jsonify({
#             "status": "error",
#             "message": str(e)
#         })

# def migrate_inquiries():
#     try:
#         # Fetch only unchecked inquiries (or change to include both if needed)
#         old_records = OldInquries.query.all()

#         migrated_count = 0
#         skipped_count = 0
#         missing_vehicle_count = 0

#         for old in old_records:
#             print(old)
#             # Check if an equivalent record already exists in the new table
#             if is_valid_kenyan_phone(old.phone):
#                 vehicle = Listing.query.get(old.car_id)
#                 if not vehicle:
#                     missing_vehicle_count += 1
#                     continue
#                 exists = RequestModel.query.filter(
#                     and_(
#                         RequestModel.email == old.email,
#                         RequestModel.phone == old.phone,
#                         RequestModel.vehicle_id == old.car_id
#                     )
#                 ).first()

#                 if exists:
#                     skipped_count += 1
#                     continue

#                 # Create a new RequestModel instance
#                 new_request = RequestModel(
#                     name=old.name,
#                     email=old.email,
#                     phone=old.phone,
#                     subject=f"Inquiry about vehicle {old.car_id}" if old.car_id else None,
#                     message=old.message,
#                     seen=True,
#                     completed=False,
#                     date=old.created or datetime.now(),
#                     vehicle_id=old.car_id if old.car_id else 0
#                 )

#                 db.session.add(new_request)
#                 migrated_count += 1

#                 # Mark old inquiry as checked (if you want to)
#                 # old.checked = "Yes"

#             db.session.commit()

    #     return jsonify({
    #         "status": "success",
    #         "migrated": migrated_count,
    #         "skipped_duplicates": skipped_count,
    #         "missing_vehicle_ids": missing_vehicle_count
    #     }), 200

    # except Exception as e:
    #     db.session.rollback()
    #     return jsonify({
    #         "status": "error",
    #         "message": str(e)
    #     }), 500
        
# def tryMigrate2():
#     vehicles = OldListing.query.all()
#     for vehicle in vehicles:
#         image_attrs = vehicle.images
#         # print(image_attrs)
#         images = [img.get('filename') if img else None for img in image_attrs]
#         # print("----", vehicle.id)
#         print(images)
#         features = vehicle.features
#         print(features)
#         enabled_features = []
#         if features:
#             # features = json.loads(features)
#             for value in features:
#                 if value:
#                     if type(value) == str:
#                         enabled_features = features
#                         continue
#                     feature = Features.query.filter(Features.id == value.feature_id).first()
#                     if feature:
#                         feature_id = feature.id
#                         enabled_features.append(feature_id)
            
            
#         print(enabled_features)
#         make = vehicle.name
#         model = vehicle.car_model_id
#         doors = vehicle.doors_id
        
#         make_m = CarMake.query.filter_by(id= make).first()
#         model_m = CarModel.query.filter_by(id= model).first()
        
#         if make_m and model_m:
        
#             title = f'{vehicle.year} {make_m.name} {model_m.name}'
#             e = Listing.query.filter_by(id = vehicle.id).first()
#             if not e:
#                 new_car = Listing(
#                     id = vehicle.id,
#                     title = title,
#                     VIN = vehicle.VIN,
#                     price = vehicle.car_price if vehicle.car_price else 0,
#                     mileage = vehicle.mileage,
#                     year = vehicle.year,
#                     engine_size = vehicle.engine_size if vehicle.engine_size else 3000,
#                     make = make,
#                     model = model,
#                     condition = vehicle.condition,
#                     body_type = vehicle.car_type_id,
#                     drive_type = vehicle.drive_type_id,
#                     transmission = vehicle.transmission_id,
#                     fuel_type = vehicle.fuel_type,
#                     color = vehicle.color_id,
#                     doors = doors,
#                     cylinders = 1,
#                     status = 1,
#                     staff_handler = 2,
#                     description = vehicle.description if vehicle.description else ' ',
#                     terms_of_services = True,
#                     features = enabled_features,
#                     images = images,
#                 )
#                 db.session.add(new_car)
#                 db.session.commit()
#                 print(f"Car successfully added to db - {vehicle.id}")
        
#     return 'test migrate'
@login_required
def delete_status(id):
    item = CarStatus.query.filter(CarStatus.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)

@login_required
def status():
    form = UtilityForm()
    if form.validate_on_submit():
        new = CarStatus(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Status added successfully', 'success')
    status = CarStatus.query.order_by(CarStatus.id.desc()).all()
    return render_template('admin/pages/utilities/status.html', status=status, form=form)

@login_required
def delete_make(id):
    item = CarMake.query.filter(CarMake.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)


def tryMigrate():
    # data = request.form or request.args
    # print(data)
    cars = Vehicle.query.all()
    for car in cars:
        
        findMake = CarMake.query.filter(CarMake.name.like(car.vmodel.oldmake.make_name)).first()
        if findMake:
            id = findMake.id
        else:
            newMake = CarMake(
                name = car.vmodel.oldmake.make_name,
                logo = car.vmodel.oldmake.make_image
            )
            db.session.add(newMake)
            db.session.commit()
            id = newMake.id
            
        if id:
            findMOdel = CarModel.query.filter(
                        CarModel.name.like(f'%{car.vmodel.model_name}%'),
                        CarModel.make_id == id).first()
            if findMOdel:
                mId = findMOdel.id
            else:
                newModel = CarModel(
                    name = car.vmodel.model_name,
                    make_id = id
                )
                db.session.add(newModel)
                db.session.commit()
                mId = newModel.id
                
            print(f"{car.id} =======")
            print(car.vmodel.oldmake.make_name)
            print(car.vmodel.model_name)
            specs = json.loads(car.specifications)
            specsList = []
            for spec in specs:
                findSpec = Features.query.filter(Features.name.like(f'%{spec}%')).first()
                if findSpec:
                    dId = findSpec.id
                else:
                    newSpec = Features(name = spec, description = '')
                    db.session.add(newSpec)
                    db.session.commit()
                    dId = newSpec.id
                specsList.append(dId)
            
            
            primary_image = VehicleUpload.query.filter_by(id = car.primary_image).first()
            left_side = VehicleUpload.query.filter_by(id = car.left_side).first() 
            right_side = VehicleUpload.query.filter_by(id = car.right_side).first() 
            dashboard = VehicleUpload.query.filter_by(id = car.dashboard).first()
            interior_image = VehicleUpload.query.filter_by(id = car.interior_image).first() 
            other_image = VehicleUpload.query.filter_by(id = car.other_image).first()
            
            images = [
                primary_image.filename if primary_image else None,
                left_side.filename if left_side else None,
                right_side.filename if right_side else None,
                dashboard.filename if dashboard else None,
                interior_image.filename if interior_image else None,
                other_image.filename if other_image else None
            ]
            print(specsList)
            print(images)
            print(f"Make - {id}", f"Model - {mId}", 'You can now trasfer the vehicle\n\n')
            # print('You can now trasfer the vehicle\n\n')
            
    # cl = VehicleUpload.query.filter_by(id=3337).first()
    # print(cl.filename)
    # for clss in cl:
    #     print(clss)
    return jsonify(dict(message='Data for vehicle', success=True))


@login_required
def makes():
    form = BrandsForm()
    if form.validate_on_submit():
        image = form.logo.data
        logo = imageUpload(image)
        new = CarMake(
            name = form.name.data,
            slug = makeSlug(form.name.data),
            logo = form.logo.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Make added successfully', 'success')
    makes = CarMake.query.order_by(CarMake.id.desc()).all()
    return render_template('admin/pages/utilities/makes.html', makes=makes, form=form)

@login_required
def delete_body_type(id):
    item = BodyTypes.query.filter(BodyTypes.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)

@login_required
def delete_model(id):
    item = CarModel.query.filter(CarModel.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_condition(id):
    item = Condition.query.filter(Condition.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_drive_type(id):
    item = DriveType.query.filter(DriveType.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_transmission(id):
    item = Transmission.query.filter(Transmission.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def admin_delete_article(id):
    item = BlogArticles.query.filter(BlogArticles.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Blog article deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_fuel_type(id):
    item = FuelType.query.filter(FuelType.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_cylinders(id):
    item = Cylinders.query.filter(Cylinders.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_external_colour(id):
    item = Colors.query.filter(Colors.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_door(id):
    item = Doors.query.filter(Doors.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def delete_feature(id):
    item = Features.query.filter(Features.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)

@login_required
def models():
    form = ModelForm()
    makes = [(select.id, select.name) for select in CarMake.query.all()]
    makes.insert(0, ('', '-- Select Make --'))
    form.make.choices = makes
    if form.validate_on_submit():
        new = CarModel(
            name = form.name.data,
            slug = makeSlug(form.name.data),
            description = form.description.data,
            make_id = form.make.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Model added successfully', 'success')
    models = db.session.query(CarMake.name.label('make'), CarModel.id,
                              CarModel.date, CarModel.active, CarModel.description,
                              CarModel.name, CarModel.make_id
                            ).outerjoin(CarMake, CarModel.make_id == CarMake.id).order_by(CarModel.id.desc()).all()
    return render_template('admin/pages/utilities/models.html', models=models, form=form)

@login_required
def body_types():
    form = UtilityForm()
    if form.validate_on_submit():
        new = BodyTypes(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Body Type added successfully', 'success')
    body_types = BodyTypes.query.order_by(BodyTypes.id.desc()).all()
    return render_template('admin/pages/utilities/body-types.html', body_types=body_types, form=form)

@login_required
def admin_delete_Review(id):
    item = Review.query.filter(Review.id == id).first()
    db.session.delete(item)
    db.session.commit()
    flash('Item deleted successfully', 'success')
    return redirect(request.referrer)
@login_required
def admin_reviews():
    form = ReviewForm()
    if form.validate_on_submit():
        new = Review(
            customer_name = form.customer_name.data,
            rating = form.rating.data,
            comment = form.comment.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Review added successfully', 'success')
    reviews = Review.query.order_by(Review.id.desc()).all()
    return render_template('admin/pages/reviews.html', reviews=reviews, form=form)
@login_required
def conditions():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Condition(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Condition added successfully', 'success')
    conditions = Condition.query.order_by(Condition.id.desc()).all()
    return render_template('admin/pages/utilities/conditions.html', conditions=conditions, form=form)
@login_required
def drive_types():
    form = UtilityForm()
    if form.validate_on_submit():
        new = DriveType(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Drive Type added successfully', 'success')
    drive_types = DriveType.query.order_by(DriveType.id.desc()).all()
    return render_template('admin/pages/utilities/drive-types.html', drive_types=drive_types, form=form)
@login_required
def transmisions():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Transmission(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Transmission added successfully', 'success')
    transmissions = Transmission.query.order_by(Transmission.id.desc()).all()
    return render_template('admin/pages/utilities/transmisions.html', transmissions=transmissions, form=form)
@login_required
def fuel_types():
    form = UtilityForm()
    if form.validate_on_submit():
        new = FuelType(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Drive Type added successfully', 'success')
    fuel_types = FuelType.query.order_by(FuelType.id.desc()).all()
    return render_template('admin/pages/utilities/fuel-types.html', fuel_types=fuel_types, form=form)
@login_required
def cylinders():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Cylinders(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Drive Type added successfully', 'success')
    cylinders = Cylinders.query.order_by(Cylinders.id.desc()).all()
    return render_template('admin/pages/utilities/cylinders.html', cylinders=cylinders, form=form)
@login_required
def external_colours():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Colors(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Drive Type added successfully', 'success')
    external_colours = Colors.query.order_by(Colors.id.desc()).all()
    return render_template('admin/pages/utilities/external-colours.html', external_colours=external_colours, form=form)
@login_required
def doors():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Doors(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Drive Type added successfully', 'success')
    doors = Doors.query.order_by(Doors.id.desc()).all()
    return render_template('admin/pages/utilities/doors.html', doors=doors, form=form)
@login_required
def features():
    form = UtilityForm()
    if form.validate_on_submit():
        new = Features(
            name = form.name.data,
            description = form.description.data
        )
        db.session.add(new)
        db.session.commit()
        flash('Features added successfully', 'success')
    features = Features.query.order_by(Features.id.desc()).all()
    return render_template('admin/pages/utilities/features.html', features=features, form=form)

@login_required
def update_model(make_id):
    models = [{'id':select.id, 'name':select.name} for select in CarModel.query.filter(CarModel.make_id==make_id).all()]
    return models

@login_required
def edit_listing(id):
    listing = Listing.query.filter(Listing.id==id).first()
    form = AddListing(obj = listing)
    form2 = AddModel(obj = listing)
    # form3 = EditImages(obj = listing)
    this_year = int(datetime.now().year)
    years = list(range(1995, this_year+1))
    # years = years.reverse()
    # print(years)
    form.make.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarMake.query.all()]
    form2.model.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarModel.query.filter(CarModel.make_id == listing.model2.car_make.id) .all()]
    form.year.choices = [('', 'Choose...')]+[(year, year) for year in years[::-1]]
    form.drive_type.choices = [('', 'Choose...')]+[(select.id, select.name) for select in DriveType.query.all()]
    form.transmission.choices = [('', 'Choose...')]+[(select.id, select.name) for select in Transmission.query.all()]
    form.fuel_type.choices = [('', 'Choose...')]+[(select.id, select.name) for select in FuelType.query.all()]
    form.color.choices = [('', 'Choose...')]+[(select.id, select.name) for select in Colors.query.all()]
    form.doors.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Doors.query.all()]
    form.cylinders.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Cylinders.query.all()]
    form.condition.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Condition.query.all()]
    form.body_type.choices = [('', 'Choose...')] + [(select.id, select.name) for select in BodyTypes.query.all()]
    form.status.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarStatus.query.all()]
    form.features.choices = [(select.id, select.name) for select in Features.query.all()]
    form.staff_handler.choices = [(str(select.id), f'{select.first_name} {select.last_name} - {select.department.name}') for select in Staff.query.all()]
    if form.validate_on_submit():
        # staff_handlers = form.staff_handler.data
        # form.populate_obj(listing)
        listing.title = form.title.data
        listing.VIN = form.VIN.data
        listing.price = form.price.data
        listing.mileage = form.mileage.data
        listing.engine_size = form.engine_size.data
        listing.status = form.status.data
        listing.make = form.make.data
        # listing.model = request.form.get('model')
        listing.condition = form.condition.data
        listing.body_type = form.body_type.data
        listing.year = form.year.data
        listing.drive_type = form.drive_type.data
        listing.transmission = form.transmission.data
        listing.fuel_type = form.fuel_type.data
        listing.color = form.color.data
        listing.doors = form.doors.data
        # listing.youtube = extract.video_id(form.youtube.data) if form.youtube.data else None
        listing.cylinders = form.cylinders.data
        listing.tags_or_keyword = form.tags_or_keyword.data
        listing.description = form.description.data
        listing.terms_of_services = form.terms_of_services.data
        listing.features = form.features.data
        listing.staff_handler = form.staff_handler.data
        # images = imagesList
        imagesList = listing.images
        
        remove_ids = request.form.getlist('remove_images')
        if remove_ids:
            for image_id in remove_ids:
                imagesList.remove(image_id)
                
        images = request.files.getlist('images')
        
        for image in images:
            if image and image.filename != '':
                f = imageUpload(image)
                if f: imagesList.append(f)
                
        listing.images = imagesList
        flag_modified(listing, "images")
        
        listing.model =  request.form.get('model')  if request.form.get('model') else listing.model
        
        db.session.commit()
        
        flash('Listing updated successfully', 'success')
        return redirect(request.referrer)
    
    return render_template('admin/pages/edit-listing.html', form = form, form2 = form2, listing = listing)

@login_required
def add_listing():
    form = AddListing()
    form2 = AddModel()
    # form3 = AddImages()
    this_year = int(datetime.now().year)
    years = list(range(1995, this_year+1))
    # years = years.reverse()
    # print(years)
    form.make.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarMake.query.all()]
    form.year.choices = [('', 'Choose...')]+[(year, year) for year in years[::-1]]
    form.drive_type.choices = [('', 'Choose...')]+[(select.id, select.name) for select in DriveType.query.all()]
    form.transmission.choices = [('', 'Choose...')]+[(select.id, select.name) for select in Transmission.query.all()]
    form.fuel_type.choices = [('', 'Choose...')]+[(select.id, select.name) for select in FuelType.query.all()]
    form.color.choices = [('', 'Choose...')]+[(select.id, select.name) for select in Colors.query.all()]
    form.doors.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Doors.query.all()]
    form.cylinders.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Cylinders.query.all()]
    form.condition.choices = [('', 'Choose...')] + [(select.id, select.name) for select in Condition.query.all()]
    form.body_type.choices = [('', 'Choose...')] + [(select.id, select.name) for select in BodyTypes.query.all()]
    form.status.choices = [('', 'Choose...')] + [(select.id, select.name) for select in CarStatus.query.all()]
    form.features.choices = [(select.id, select.name) for select in Features.query.all()]
    form.staff_handler.choices = [(str(select.id), f'{select.first_name} {select.last_name} - {select.department.name}') for select in Staff.query.all()]
    
   # print(form.staff_handler.data)
    if form.validate_on_submit():
        try:
            imagesList = []
                
            images = request.files.getlist('images')
            for image in images:
                if image and image.filename != '':
                    imagesList.append(imageUpload(image))
                    
            new = Listing(
                title = form.title.data,
                VIN = form.VIN.data,
                price = form.price.data,
                mileage = form.mileage.data,
                engine_size = form.engine_size.data,
                status = form.status.data,
                make = form.make.data,
                model = request.form.get('model'),
                condition = form.condition.data,
                body_type = form.body_type.data,
                year = form.year.data,
                drive_type = form.drive_type.data,
                transmission = form.transmission.data,
                fuel_type = form.fuel_type.data,
                color = form.color.data,
                doors = form.doors.data,
                youtube = extract.video_id(form.youtube.data) if form.youtube.data else None,
                cylinders = form.cylinders.data,
                tags_or_keyword = form.tags_or_keyword.data,
                description = form.description.data,
                terms_of_services = form.terms_of_services.data,
                features = form.features.data,
                images = imagesList,
                staff_handler = current_user.id
            )
            
            db.session.add(new)
            db.session.commit()
            flash('Successfully uploaded car', 'success')
            
        except Exception as e:
            flash(f"{str(e)}", 'error')
            
    return render_template('admin/pages/add-listing.html', form = form, form2 = form2)

@login_required
def admin_news():
    articles = BlogArticles.query.order_by(BlogArticles.created_at.desc()).all()
    return render_template('admin/pages/news-all.html', articles=articles)

@login_required
def uploader():
    values = request.values
    print(values)
    return "This is nice!"

@login_required
def admin_news_add():
    form = BlogForm()
    if form.validate_on_submit():
        file = request.files.get('image')
        try:
            new = BlogArticles(
                title=form.title.data,
                image=imageUpload(file),
                article=form.article.data,
                author_id=1,
            )
            db.session.add(new)
            db.session.commit()
            flash('Article posted successfully', 'success')
        except Exception as e:
            flash(str(e), 'error')
    return render_template('admin/pages/news.html', form=form)

@login_required
def admin_news_post_view(slug):
    article = BlogArticles.query.filter_by(id=slug).first()
    return render_template('admin/pages/news-view.html', article=article, form=form)

@login_required
def admin_news_post(slug):
    article = BlogArticles.query.filter_by(id=slug).first()
    form = BlogForm()
    if request.method == 'POST':
        file = request.files.get('image')
        image = request.form.get('old-image')
        if file:
            image = imageUpload(file)
        try:
            update = BlogArticles.query.filter_by(id=slug).first()

            update.title = request.form.get(
                'title') if request.form.get('title') else update.title
            update.image = image
            update.article = request.form.get('article') if request.form.get(
                'article') else update.article,

            db.session.commit()
            flash('Article updated successfully', 'success')
        except Exception as e:
            flash(str(e), 'error')
    return render_template('admin/pages/news-post.html', article=article, form=form)

@login_required
def delete_car_sell(id):
    info = CarInfo.query.filter(CarInfo.id == id).first()
    db.session.delete(info)
    db.session.commit()
    flash('Deleted successfully', 'info')
    return redirect(request.referrer)
@login_required
def view_car_sell(id):
    car = CarInfo.query.filter(CarInfo.id == id).first()
    return render_template('admin/pages/car-sell-view.html', car=car)
@login_required
def admin_car_sell():
    cars =  CarInfo.query.all()
    return render_template('admin/pages/car-sell.html', cars = cars)

@login_required
def delete_contact_request(id):
    info = Enquiry.query.filter(Enquiry.id == id).first()
    db.session.delete(info)
    db.session.commit()
    flash('Deleted successfully', 'info')
    return redirect(request.referrer)
@login_required
def view_contact_request(id):
    enquiry = Enquiry.query.filter(Enquiry.id == id).first()
    return render_template('admin/pages/enquiry/enquiry-view.html', enquiry=enquiry)
@login_required
def admin_contact_request():
    enquiries =  Enquiry.query.all()
    return render_template('admin/pages/enquiry/enquiry.html', enquiries = enquiries)

@login_required
def admin_principal():
    form = PrincipalMessageForm()
    if form.validate_on_submit():
        file = request.files.get('image')
        try:
            for message in PrincipalMessage.query.all():
                message.active = False
            new = PrincipalMessage(
                name=form.name.data,
                image=imageUpload(file),
                message=form.message.data,
                author_id=session.get('DATA').get('id'),
            )
            db.session.add(new)
            db.session.commit()
            flash('Message posted successfully', 'success')
        except Exception as e:
            flash(str(e), 'error')
    return render_template('admin/pages/principal.html',
                            form=form,
                            message=PrincipalMessage.query.filter_by(active=True).first())

@login_required
def admin_gallery_hide(id):
    gallery = GalleryModel.query.filter_by(id=id).first()
    status = request.args.get('status')
    gallery.active = False if status == 'True' else True
    flash('Image updated successfully', 'success')
    return redirect(url_for('admin_gallery'))

@login_required
def admin_gallery_delete(id):
    gallery = GalleryModel.query.filter_by(id=id).first()
    db.session.delete(gallery)
    db.session.commit()
    flash('Image deleted successfully', 'success')
    return redirect(url_for('admin_gallery'))

@login_required
def admin_gallery():
    form = GalleryForm()
    if form.validate_on_submit():
        imageList = []
        for file in form.image.data:
            image = imageUpload(file)
            check = GalleryModel.query.filter_by(image=image).first()
            if check:
                pass
            else:
                new = GalleryModel(
                    image=image,
                    author_id=session.get('DATA').get('id')
                )
                db.session.add(new)
                db.session.commit()
                imageList.append(image)
        flash(f'{len(imageList)} images uploaded', 'success')
    images = GalleryModel.query.all()
    return render_template('admin/pages/gallery.html', form=form, images=images)

@login_required
def admin_contacts():
    contact = ContactUs.query.filter(ContactUs.active==True).first()
    return render_template('admin/pages/contacts.html', contact = contact)
@login_required
def admin_new_contacts():
    form = AboutForm()
    if form.validate_on_submit():
        db.session.query(ContactUs).update({ContactUs.active: False})
        new = ContactUs(
            message = form.message.data,
        )
        db.session.add(new)
        db.session.commit()
        flash('Successfully created a new About', 'success')
        return redirect(url_for('admin_contacts'))
    return render_template('admin/pages/contacts-new.html', form= form)
@login_required
def admin_edit_contacts():
    about = ContactUs.query.filter(ContactUs.active == True).first()
    form = AboutForm(obj=about)
    if form.validate_on_submit():
        form.populate_obj(about)
        db.session.commit()
        flash('Successfully updated About', 'success')
        return redirect(url_for('admin_contacts'))
    return render_template('admin/pages/contacts-edit.html', form= form)

@login_required
def completed_request(id):
    question = RequestModel.query.filter_by(id=id).first()
    question.completed = True
    flash('Request marked successfully', 'success')
    db.session.commit()
    return redirect(request.referrer)

@login_required
def open_request(id):
    request = RequestModel.query.filter_by(id=id).first()
    request.seen = True
    db.session.commit()
    return render_template('admin/pages/open-request.html', request = request)

@login_required
def admin_about():
    about = AboutUs.query.filter(AboutUs.active==True).first()
    return render_template('admin/pages/about-us.html', about = about)

@login_required
def admin_new_about():
    form = AboutForm()
    if form.validate_on_submit():
        db.session.query(AboutUs).update({AboutUs.active: False})
        new = AboutUs(
            message = form.message.data,
        )
        db.session.add(new)
        db.session.commit()
        flash('Successfully created a new About', 'success')
        return redirect(url_for('admin_about'))
    return render_template('admin/pages/about-us-new.html', form= form)
@login_required
def admin_edit_about():
    about = AboutUs.query.filter(AboutUs.active == True).first()
    form = AboutForm(obj=about)
    if form.validate_on_submit():
        form.populate_obj(about)
        db.session.commit()
        flash('Successfully updated About', 'success')
        return redirect(url_for('admin_about'))
    return render_template('admin/pages/about-us-edit.html', form= form)

def humanize_date(dt):
    now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now()
    today = now.date()
    date_only = dt.date()
    
    if date_only == today:
        return dt.strftime("Today at %I:%M %p")
    elif date_only == (today - timedelta(days=1)):
        return dt.strftime("Yesterday at %I:%M %p")
    else:
        return dt.strftime("%B %d, %Y at %I:%M %p")
    
app.jinja_env.filters['humanize_date'] = humanize_date

@login_required
def admin_requests():
    page = int(request.args.get('page', 1))
    limit = 20
    next_offset = limit * page
    offset = next_offset - limit
    
    questions = RequestModel.query.order_by(RequestModel.id.desc())
    count = questions.count()
    
    questions = questions.limit(limit).offset(offset).all()
    pages = count/limit
    last_page = False
    pages_count = pages if type(pages) is int else int(pages)+1
    if page == pages_count:
        last_page = True
    
    return render_template('admin/pages/requests.html', 
                           questions=questions,
                           last_page = last_page,)

@login_required
def admin_dashboard():
    total_listings = Listing.query.count()
    total_sold = Listing.query.filter_by(sold=True).count()
    listing_requests  = RequestModel.query.count()
    department  = Department.query.count()
    staff  = Staff.query.count()
    blog  = BlogArticles.query.count()
    
    return render_template('admin/pages/dashboard.html',
            total_listings=total_listings, department=department, total_sold =total_sold,
            listing_requests=listing_requests, staff = staff, blog = blog)

@login_required
def admin_billing():
    return render_template('admin/pages/billing.html')

@login_required
def admin_virtual_reality():
    return render_template('admin/pages/virtual-reality.html')

@login_required
def admin_rtl():
    return render_template('admin/pages/rtl.html')

@login_required
def admin_profile():
    return render_template('admin/pages/profile.html')

def admin_sign_in():
    form = LoginForm()
    try:
        if form.validate_on_submit():
            f = request.form
            email = f.get('email')
            password = f.get('password')
            user = Users.query.filter(Users.email == email).first()
            if user:
                if check_password_hash(user.password, password):
                    user.id = user.email
                    login_user(user)
                    # token, data = Token(user)
                    # session['TOKEN'] = token
                    # session['DATA'] = data
                    next = request.args.get('next')
                    flash('You have been logged in successfully', 'success')
                    return redirect(next or url_for('admin_dashboard'))
                else:
                    flash('Incorrect password', 'error')
                    return redirect(url_for('admin_sign_in'))
            else:
                flash('Account not found', 'error')
                return redirect(url_for('admin_sign_in'))
        # else:
        #     flash("Not valid Login", 'error')
    except Exception as e:
        flash(str(e), 'error')
    return render_template('admin/pages/login.html', form=form)

# @login_required
# def admin_logout():
#     # logout_user()
#     session.pop('TOKEN')
#     session.pop('DATA')
#     flash('Logged out successfully', 'info')
#     resp = redirect(url_for('admin_sign_in'))
#     resp.set_cookie('access_token_cookie', '')
#     def logout():
#     logout_user()
#     flash('You have been logged out successfully', 'info')
#     return redirect('/login')
    return resp

def admin_sign_up():
    return render_template('admin/pages/sign-up.html')

    