from django.shortcuts import render, get_object_or_404, redirect
from django.db.models import Q
from .models import *
from .forms import *
from django.http import HttpResponseRedirect
from django.utils.translation import gettext_lazy
from django.utils.translation import gettext as _
from django.utils.translation import get_language
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib import messages
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
# Create your views here.
# from faker import Faker
from django.http import HttpResponse
import random
import re
import os
import uuid
from django.utils.text import slugify


def _phone_hop_le(raw):
    """Kiểm tra số điện thoại phía SERVER — lớp chặn thật, không thể vòng qua như
    kiểm tra bằng JavaScript ở trình duyệt. Trả về số đã làm sạch nếu hợp lệ,
    ngược lại trả None. Chấp nhận: 0xxxxxxxxx(x) hoặc +84xxxxxxxxx, có/không dấu
    cách, chấm, gạch, ngoặc (khớp đúng với kiểm tra phía trình duyệt)."""
    if not raw:
        return None
    s = re.sub(r'[\s.\-()]', '', str(raw))
    if re.fullmatch(r'\+84\d{9}', s):
        return s
    if re.fullmatch(r'0\d{9,10}', s):
        return s
    return None


def _quay_lai(request, mac_dinh='/'):
    """Về lại đúng trang vừa gửi (để người dùng thấy thông báo lỗi ngay tại chỗ)."""
    return redirect(request.META.get('HTTP_REFERER') or mac_dinh)
# fake = Faker()
# fake.seed_instance(4321)


def _build_safe_upload_name(uploaded_file):
    original_name = uploaded_file.name or "uploaded-file"
    base_name, extension = os.path.splitext(original_name)
    safe_base_name = slugify(base_name)
    if not safe_base_name:
        safe_base_name = "uploaded-file"
    unique_suffix = uuid.uuid4().hex[:10]
    return f"{safe_base_name}-{unique_suffix}{extension.lower()}"


def _extract_original_upload_name(uploaded_file):
    return os.path.basename(uploaded_file.name or "")

def index(request):
    query = request.GET.get('q')
    products = SanPham.objects.all()[:9]
    thuocsaus = SanPham.objects.filter(loai="thuốc sâu").order_by("-id")[:9]
    thuoctrubenhs = SanPham.objects.filter(loai="thuốc trừ bệnh").order_by("-id")[:9]
    thuoccos = SanPham.objects.filter(loai="thuốc cỏ").order_by("-id")[:9]
    thuocsinhtruongs = SanPham.objects.filter(loai="thuốc sinh trưởng").order_by("-id")[:9]
    binhbom = SanPhamBinhBom.objects.all()[:9]
    allnews = TinTuc.objects.all()

    if query:
        # Tìm kiếm sản phẩm theo tên (Vietnamese hoặc English)
        search_results = SanPham.objects.filter(
            Q(ten__icontains=query) |
            Q(ten_en__icontains=query) |
            Q(mo_ta_ngan__icontains=query)
        ).distinct()

        result_count = search_results.count()

        # Nếu tìm thấy đúng 1 sản phẩm, redirect tới detail
        if result_count == 1:
            product = search_results.first()
            if product:
                return redirect('product_detail', product_id=product.pk)
        # Nếu tìm thấy nhiều sản phẩm, hiển thị kết quả tìm kiếm
        if result_count > 0:
            context = {
                'search_query': query,
                'search_results': search_results,
                'result_count': result_count,
            }
            return render(request, 'BmcBase/search_results.html', context)
        # Nếu không tìm thấy, hiển thị trang không có kết quả
        else:
            context = {
                'search_query': query,
                'search_results': [],
                'result_count': 0,
            }
            return render(request, 'BmcBase/search_results.html', context)

    context = {'products': products,
               'thuocsaus': thuocsaus,
               'thuoctrubenhs': thuoctrubenhs,
               'thuoccos': thuoccos,
               'thuocsinhtruongs': thuocsinhtruongs,
               'binh_bom': binhbom,
               'news': allnews,
            }
    return render(request, 'BmcBase/index.html', context)

def about(request):
    return render(request, 'BmcBase/about.html')

def noti(request):
    notifications_list = ThongBao.objects.all()

    paginator = Paginator(notifications_list, 12)

    page_number = request.GET.get("page")
    try:
        notifications = paginator.get_page(page_number)
    except PageNotAnInteger:
        # Nếu page_number không thuộc kiểu integer, trả về page đầu tiên
        notifications = paginator.get_page(1)
    except EmptyPage:
        # Nếu page không có item nào, trả về page cuối cùng
        notifications = paginator.get_page(paginator.num_pages)

    context = {
        'notifications': notifications
    }
    return render(request, 'BmcBase/noti.html', context)

def news(request):
    news = TinTuc.objects.all()
    context = {'list_of_news': news}

    return render(request, 'BmcBase/news.html', context)

def news_detail(request, news_id):
    news = get_object_or_404(TinTuc, pk=news_id)
    context = {'news': news}
    return render(request, 'BmcBase/news_detail.html', context)

def _trich_khu_vuc(tieu_de):
    """Trích các khu vực nằm trong ngoặc của tiêu đề job, tách theo '/'.
    VD: 'WAREHOUSE ASSISTANT (LONG AN/BINH DINH)' -> ['LONG AN', 'BINH DINH'].
    Dựa vào ĐÚNG pattern hiện có '... (KHU VỰC)', không đổi dữ liệu."""
    if not tieu_de:
        return []
    m = re.search(r"\(([^)]*)\)", tieu_de)
    if not m:
        return []
    return [x.strip() for x in m.group(1).split("/") if x.strip()]


# Chuẩn hóa tên khu vực (KHÔNG sửa dữ liệu — chỉ gom lúc dựng bộ lọc). Dùng HEURISTIC
# để bền với mọi biến thể trong dữ liệu thật (không phải liệt kê từng chuỗi):
#  - Mục là YÊU CẦU NGÔN NGỮ (chứa "TIẾNG"/ENGLISH/CHINESE/SPEAKING/JAPANESE/KOREAN...)
#    -> gom vào "LONG AN" (theo yêu cầu; đó là mục phi-khu-vực).
#  - Bản tiếng Anh nhập lẫn có/không dấu Đ (BINH ĐINH vs BINH DINH) -> bỏ Đ cho thống nhất.
_TU_NGON_NGU = ("TIẾNG", "ENGLISH", "CHINESE", "SPEAKING", "JAPANESE", "KOREAN", "NGOẠI NGỮ")


def _chuan_kv(raw, is_en=False):
    raw = (raw or "").strip()
    if not raw:
        return ""
    u = raw.upper()
    if any(k in u for k in _TU_NGON_NGU):
        return "LONG AN"
    if is_en:
        raw = raw.replace("Đ", "D").replace("đ", "d")
    return raw


def careers(request):
    # Trường tiêu đề theo ngôn ngữ đang xem (tên khu vực khớp ngôn ngữ hiển thị).
    lang = str(get_language() or "vi")
    is_en = lang.startswith("en")
    field = "tieu_de_en" if is_en else "tieu_de"

    q = (request.GET.get("q") or "").strip()
    khu_vuc = (request.GET.get("khu_vuc") or "").strip()
    xem_tat_ca = request.GET.get("tat_ca") == "1"

    all_jobs = Careers.objects.all()

    # Dựng dropdown theo tên CHUẨN, đồng thời nhớ mọi cách gõ thô của mỗi tên chuẩn
    # để khi lọc còn khớp được cả biến thể trong tiêu đề.
    raw_theo_chuan = {}   # tên chuẩn -> tập các chuỗi thô xuất hiện trong tiêu đề
    for c in all_jobs:
        for raw in _trich_khu_vuc(getattr(c, field) or ""):
            chuan = _chuan_kv(raw, is_en=is_en)
            raw_theo_chuan.setdefault(chuan, set()).add(raw)
    khu_vuc_list = sorted(raw_theo_chuan.keys())

    # Lọc theo từ khóa + khu vực (giữ nguyên pattern tiêu đề, chỉ đọc để lọc).
    careers_list = all_jobs
    if q:
        careers_list = careers_list.filter(**{f"{field}__icontains": q})
    if khu_vuc:
        # khớp MỌI cách gõ thô ứng với tên chuẩn được chọn (VD Bình Định gõ 2 kiểu).
        aliases = set(raw_theo_chuan.get(khu_vuc, set())) | {khu_vuc}
        dieu_kien = Q()
        for a in aliases:
            dieu_kien |= Q(**{f"{field}__icontains": a})
        careers_list = careers_list.filter(dieu_kien)

    tong_ket_qua = careers_list.count()

    if xem_tat_ca:
        careers = careers_list  # xem tất cả, không phân trang
    else:
        paginator = Paginator(careers_list, 6)
        page_number = request.GET.get("page")
        try:
            careers = paginator.get_page(page_number)
        except PageNotAnInteger:
            careers = paginator.get_page(1)
        except EmptyPage:
            careers = paginator.get_page(paginator.num_pages)

    context = {
        "careers": careers,
        "khu_vuc_list": khu_vuc_list,
        "khu_vuc": khu_vuc,
        "q": q,
        "query": q,               # cho includes/pagination.html (nó dùng biến 'query')
        "xem_tat_ca": xem_tat_ca,
        "tong_ket_qua": tong_ket_qua,
    }
    return render(request, "BmcBase/careers.html", context)


def career(request, career_id):
    career = get_object_or_404(Careers, pk=career_id)
    context = {'career': career}
    return render(request, "BmcBase/career.html", context)

def contact(request):
    return render(request, "BmcBase/contact.html")

def noti_post(request, post_id):
    post = get_object_or_404(ThongBao, pk=post_id)
    context = {'post': post}
    return render(request, "BmcBase/noti_post.html", context)


# def blog_fake_data(request, count=10):

#     # categories = TheLoaiBaiViet.objects.all()
#     # for _ in range(count):
#     #     kienthuc = KienThuc.objects.create(
#     #         ten=fake.sentence(),
#     #         ngay_dang=fake.date(),
#     #         mo_ta=fake.paragraph(nb_sentences=8),
#     #         noi_dung=fake.paragraph(nb_sentences=50)
#     #     )
#     #     kienthuc.the_loai.set(fake.random_elements(elements=categories))
#     #     kienthuc.save()
#     # return HttpResponseRedirect('/blog')

#     for _ in range(count):
#         # random_KienThuc_instance = KienThuc.objects.filter(pk=random.randint(1, 111)).first() # Chọn bài viết ng  u nhiên
#         random_KienThuc_instance = KienThuc.objects.filter(pk=111).first()
#         if not random_KienThuc_instance:
#             continue
#         kienthuc = BinhLuan.objects.create(
#             ten_nguoi_dang=fake.name(),
#             thong_tin_lien_he=fake.phone_number(),
#             ngay_dang=fake.date(),
#             trang_thai_da_duyet=random.choice([True, False]),
#             tieu_de=fake.sentence(),
#             noi_dung=fake.paragraph(nb_sentences=10),
#             bai_viet=random_KienThuc_instance,  # Chọn bài viết ng  u nhiên
#         )
        
#     return HttpResponseRedirect('/blog')

def display_image(request):
    # Bạn có thể xử lý các tham số truy vấn nếu cần
    str_param = request.GET.get('str', '')  # Lấy tham số 'str' từ URL
    # Có thể thêm logic xử lý dựa trên tham số str_param nếu cần

    return render(request, 'BmcBase/image_display.html')

def blog(request, id_the_loai=None):

    notifications_list = KienThuc.objects.all().order_by('-ngay_dang')
    categories = TheLoaiBaiViet.objects.all()

    if id_the_loai:
        ten_the_loai = get_object_or_404(TheLoaiBaiViet, pk=id_the_loai)
        notifications_list = KienThuc.objects.filter(the_loai=ten_the_loai).order_by('-ngay_dang')  # Lấy 50 bài viết mới nhất

    paginator = Paginator(notifications_list, 10)

    page_number = request.GET.get("page")
    try:
        notifications = paginator.get_page(page_number)
    except PageNotAnInteger:
        # Nếu page_number không thuộc kiểu integer, trả về page đầu tiên
        notifications = paginator.get_page(1)
    except EmptyPage:
        # Nếu page không có item nào, trả về page cuối cùng
        notifications = paginator.get_page(paginator.num_pages)

    context = {
        'notifications': notifications,
        'categories': categories,
    }
    return render(request, "BmcBase/blog.html", context)


def blog_search(request):
    categories = TheLoaiBaiViet.objects.all()

    # Tìm bằng icontains (chạy được cả SQLite lẫn PostgreSQL) thay cho full-text
    # search của Postgres — trước đây làm trang 500 khi chạy local trên SQLite
    # (lỗi 'unrecognized token: "@"'). Cùng cách với tìm kiếm sản phẩm.
    query = (request.GET.get('q') or '').strip()
    if query:
        search_results_list = KienThuc.objects.filter(
            Q(ten__icontains=query) |
            Q(ten_tieng_anh__icontains=query) |
            Q(mo_ta__icontains=query) |
            Q(mo_ta_tieng_anh__icontains=query) |
            Q(noi_dung__icontains=query) |
            Q(noi_dung_tieng_anh__icontains=query)
        ).distinct().order_by("-ngay_dang")
    else:
        search_results_list = KienThuc.objects.none()
    total_results = len(search_results_list)

    # Phân trang kết quả tìm kiếm
    paginator = Paginator(search_results_list, 10)
    page_number = request.GET.get("page")
    try:
        search_results = paginator.get_page(page_number)
    except PageNotAnInteger:
        # Nếu page_number không thuộc kiểu integer, trả về page đầu tiên
        search_results = paginator.get_page(1)
    except EmptyPage:
        # Nếu page không có item nào, trả về page cuối cùng
        search_results = paginator.get_page(paginator.num_pages)

    context = {
        'search_results': search_results,
        'total_results': total_results,  # Tính t  ng số kết quả tìm kiếm
        'categories': categories,
        'query': query,
    }

    return render(request, "BmcBase/blog_search_results.html", context)


def blog_post(request, id_bai_viet):

    bai_viet = get_object_or_404(KienThuc, pk=id_bai_viet)

    danh_sach_binh_luan = bai_viet.cac_binh_luan.filter(trang_thai_da_duyet=True).order_by('-ngay_dang')[:10]  # Lấy 10 bình luận mới nhất

    binh_luan_moi = None    # Comment posted
    if request.method == 'POST':
        binh_luan_form = BinhLuanForm(data=request.POST)
        if binh_luan_form.is_valid():
            # Create Comment object but don't save to database yet
            binh_luan_moi = binh_luan_form.save(commit=False)
            # Assign the current post to the comment
            binh_luan_moi.bai_viet = bai_viet
            # Save the comment to the database
            binh_luan_moi.save()
    else:
        binh_luan_form = BinhLuanForm()

    categories = bai_viet.the_loai.all()
    danh_sach_bai_viet_cung_chu_de = []
    for category in categories:
        danh_sach_bai_viet_cung_chu_de += KienThuc.objects.filter(the_loai=category).exclude(pk=bai_viet.pk).order_by('-ngay_dang')[:1]  # Lấy 1 bài viết tương tự
    if len(danh_sach_bai_viet_cung_chu_de) > 5:
        danh_sach_bai_viet_cung_chu_de = danh_sach_bai_viet_cung_chu_de[:5]

    context = {
        'bai_viet': bai_viet,
        'categories': categories,
        "danh_sach_bai_viet_cung_chu_de": danh_sach_bai_viet_cung_chu_de,
        "danh_sach_binh_luan": danh_sach_binh_luan,
        "binh_luan_moi": binh_luan_moi,
        "binh_luan_form": binh_luan_form,  # Truyền form cho việc comment vào trang html
    }

    return render(request, "BmcBase/blog_post.html", context)


def _phan_trang_san_pham(request, danh_sach, ten):
    """Phân trang 12/trang cho MỘT tab sản phẩm, HOẶC trả hết khi ?<ten>_all=1.

    Trả (items, xem_tat_ca, tong): template vừa hiển thị items vừa dựng nút
    "Xem tất cả"/"Xem theo trang" và bộ đếm tổng. Gom 6 khối phân trang lặp
    trước đây về một chỗ. get_page tự xử lý page rỗng/không hợp lệ nên không
    cần try/except như bản cũ.
    """
    tong = danh_sach.count()
    if request.GET.get(f"{ten}_all") == "1":
        return danh_sach, True, tong          # xem tất cả, bỏ phân trang
    items = Paginator(danh_sach, 12).get_page(request.GET.get(f"{ten}_page"))
    return items, False, tong


def products(request):
    # Mỗi tab một ngành hàng; helper lo phân trang hoặc xem-tất-cả theo cờ ?<tab>_all=1.
    products, products_all, products_tong = _phan_trang_san_pham(
        request, SanPham.objects.all(), "products")
    thuocsaus, thuocsaus_all, thuocsaus_tong = _phan_trang_san_pham(
        request, SanPham.objects.filter(loai="thuốc sâu"), "thuocsaus")
    thuoctrubenhs, thuoctrubenhs_all, thuoctrubenhs_tong = _phan_trang_san_pham(
        request, SanPham.objects.filter(loai="thuốc trừ bệnh"), "thuoctrubenhs")
    thuoccos, thuoccos_all, thuoccos_tong = _phan_trang_san_pham(
        request, SanPham.objects.filter(loai="thuốc cỏ"), "thuoccos")
    thuocsinhtruongs, thuocsinhtruongs_all, thuocsinhtruongs_tong = _phan_trang_san_pham(
        request, SanPham.objects.filter(loai="thuốc sinh trưởng"), "thuocsinhtruongs")
    binh_bom, binh_bom_all, binh_bom_tong = _phan_trang_san_pham(
        request, SanPhamBinhBom.objects.all(), "binh_bom")

    context = {
        'products': products, 'products_all': products_all, 'products_tong': products_tong,
        'thuocsaus': thuocsaus, 'thuocsaus_all': thuocsaus_all, 'thuocsaus_tong': thuocsaus_tong,
        'thuoctrubenhs': thuoctrubenhs, 'thuoctrubenhs_all': thuoctrubenhs_all, 'thuoctrubenhs_tong': thuoctrubenhs_tong,
        'thuoccos': thuoccos, 'thuoccos_all': thuoccos_all, 'thuoccos_tong': thuoccos_tong,
        'thuocsinhtruongs': thuocsinhtruongs, 'thuocsinhtruongs_all': thuocsinhtruongs_all, 'thuocsinhtruongs_tong': thuocsinhtruongs_tong,
        'binh_bom': binh_bom, 'binh_bom_all': binh_bom_all, 'binh_bom_tong': binh_bom_tong,
    }
    return render(request, "BmcBase/products.html", context)


def product_detail(request, product_id):
    product = get_object_or_404(SanPham, pk=product_id)
    return render(request, 'BmcBase/product.html', {'product': product})

def product_binhbom(request, product_id):
    product = get_object_or_404(SanPhamBinhBom, pk=product_id)
    return render(request, 'BmcBase/products-binhbom.html', {'product': product})

def form_submit(request):
    if request.method == 'POST':
        name = (request.POST.get('name') or '').strip()
        email = (request.POST.get('email') or '').strip()
        phone_raw = request.POST.get('phone')
        user_type = request.POST.get('user_type')
        message = (request.POST.get('message') or '').strip()
        attachment = request.FILES.get('file-input')

        # --- Kiểm tra phía server: KHÔNG tin dữ liệu từ client ---
        phone = _phone_hop_le(phone_raw)
        loi = []
        if not name:
            loi.append(_('Vui lòng nhập họ và tên.'))
        if phone_raw and not phone:
            loi.append(_('Số điện thoại không hợp lệ.'))
        if email:
            try:
                validate_email(email)
            except ValidationError:
                loi.append(_('Email không hợp lệ.'))
        if not phone and not email:
            loi.append(_('Cần ít nhất số điện thoại hoặc email để chúng tôi liên hệ.'))

        if loi:
            for m in loi:
                messages.error(request, m)
            return _quay_lai(request, '/lien-he/')

        submission = FormLienHe(
            ten=name,
            email=email,
            so_dien_thoai=phone or '',
            loai_khach_hang=user_type,
            noi_dung=message,
        )
        if attachment:
            submission.original_file_name = _extract_original_upload_name(attachment)
            safe_name = _build_safe_upload_name(attachment)
            submission.file.save(safe_name, attachment, save=False)
        submission.save()

        return HttpResponseRedirect('/')  # Chuyển hướng đến trang thành công

    return render(request, 'form.html')  # Trả về trang form nếu phương thức là GET

def form_submit_product(request):
    if request.method == 'POST':
        sdt = _phone_hop_le(request.POST.get('phone_number'))
        nameProduct = (request.POST.get('product_name') or '').strip()

        # Chặn phía server: số rỗng / sai định dạng -> KHÔNG lưu, báo lỗi và quay lại.
        # Đây là lớp bảo vệ thật (JS ở trình duyệt có thể bị tắt hoặc bị bỏ qua).
        if not sdt:
            messages.error(request, _('Số điện thoại không hợp lệ. Ví dụ: 0912 345 678'))
            return _quay_lai(request, '/products/')

        submission = FormTuVanSanPham(
            sdt=sdt,
            tenSp=nameProduct,
        )
        submission.save()

        return HttpResponseRedirect('/')  # Chuyển hướng đến trang thành công

    return render(request, 'products.html')  # Trả về trang form nếu phương thức là GET
    
def error(request):
    return render(request, "BmcBase/404.html")
