import re
import time
import base64

from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.db import transaction
from django.db.models import Q

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.tokens import RefreshToken

from .models import Company, Customer, Product,Profiles, Invoice, InvoiceItem
from django.contrib.auth.hashers import make_password



from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from django.core.exceptions import ObjectDoesNotExist
from rest_framework_simplejwt.tokens import RefreshToken
import re  # For basic email validation
# from twilio.rest import Client as TwilioClient # 💡 Maru Peyaridhal!


from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from .models import Company, Customer, Product, Invoice, InvoiceItem
# from .models import Profiles  # uncomment / adjust import to match your app
TWO_PLACES = Decimal('0.01')


def ok(data=None, message=None, code=status.HTTP_200_OK):
    return Response({
        "status": {"code": code, "response": "success"},
        "error": None,
        **({"message": message} if message else {}),
        "data": data,
    }, status=code)


def fail(message, code=status.HTTP_400_BAD_REQUEST):
    return Response({
        "status": {"code": code, "response": "failed"},
        "error": True,
        "message": message,
    }, status=code)


def to_decimal(value, field_name):
    """
    Validate + coerce a value into a Decimal, raising a clear message on bad
    input. Goes through str() first so binary floating-point artifacts
    (e.g. 0.1 + 0.2 != 0.3) never leak into money fields.
    """
    if value is None or value == '':
        raise ValueError(f"'{field_name}' is required.")
    try:
        return Decimal(str(value))
    except (InvalidOperation, ValueError, TypeError):
        raise ValueError(f"'{field_name}' must be a valid number.")


def q2(value):
    """Round a Decimal to exactly 2 places using standard rounding (not banker's)."""
    return Decimal(value).quantize(TWO_PLACES, rounding=ROUND_HALF_UP)


# ============================================================ LOGIN =======
class LoginAPIView(APIView):
    """
    Accepts either a username or an email in `username`, plus `password`.
    `fcm_token` (optional) is stored against the profile for push notifications —
    it is intentionally NOT written into `pincode`; that was a bug in the
    previous version. Adjust the field name below to match your Profile model.
    """

    def post(self, request):
        data = request.data
        username_or_email = (data.get("username") or "").strip()
        password = data.get("password")
        fcm_token = data.get("fcm_token")

        if not username_or_email or not password:
            return fail("Username/email and password are required.", status.HTTP_400_BAD_REQUEST)

        is_email = re.match(r"[^@]+@[^@]+\.[^@]+", username_or_email)

        if is_email:
            try:
                matched = User.objects.get(email__iexact=username_or_email)
                username_to_auth = matched.username
            except User.DoesNotExist:
                return fail("Invalid username or password.", status.HTTP_401_UNAUTHORIZED)
        else:
            username_to_auth = username_or_email

        user = authenticate(request, username=username_to_auth, password=password)

        if user is None:
            return fail("Invalid username or password.", status.HTTP_401_UNAUTHORIZED)

        if not user.is_active:
            return fail("This account has been disabled.", status.HTTP_403_FORBIDDEN)

        login(request, user)
        token = RefreshToken.for_user(user)

        profile_photo = None
        phone = None
        role = None

        # Wire this up to your actual Profile model / related_name.
        # Example:
        try:
            profile = Profiles.objects.get(user_id=user.id)
            if fcm_token:
                profile.fcm_token = fcm_token
                profile.save(update_fields=["fcm_token"])
            profile_photo = request.build_absolute_uri(profile.profiles.url) if profile.profiles else None
            phone = profile.phone
            role = profile.role
        except Profiles.DoesNotExist:
            pass

        return ok({
            "name": user.username,
            "id": user.id,
            "username": user.username,
            "email": user.email,
            "isSuper": user.is_superuser,
            "refresh": str(token),
            "token": str(token.access_token),
            "profile": profile_photo,
            "companyname": "loop",
            "phone": phone,
            "role": role,
        }, message="Login success")


# ============================================================ COMPANY =====
class CompanyAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def _handle_logo(self, request, data):
        if 'logo' in request.FILES:
            return request.FILES['logo']

        logo_base64 = data.get('logo_base64')
        logo_filename = data.get('logo_filename', f'logo_{int(time.time())}.jpg')

        if logo_base64:
            try:
                if ',' in logo_base64:
                    logo_base64 = logo_base64.split(',')[1]
                logo_base64 = logo_base64.strip()
                image_data = base64.b64decode(logo_base64)
                return ContentFile(image_data, name=logo_filename)
            except Exception:
                return None
        return None

    def _serialize(self, request, company, row=None):
        payload = {
            'id': company.id,
            'company_name': company.company_name,
            'address': company.address,
            'mobile': company.mobile,
            'email': company.email,
            'gst_number': company.gst_number,
            'bank_details': company.bank_details,
            'dealers_in': company.dealers_in,
            'invoice_terms': company.invoice_terms,
            'logo': request.build_absolute_uri(company.logo.url) if company.logo else None,
        }
        if row is not None:
            payload['row'] = row
        return payload

    def _validate(self, data, partial=False):
        errors = {}
        company_name = data.get('company_name')
        if not partial and not (company_name and str(company_name).strip()):
            errors['company_name'] = 'Company name is required.'

        email = data.get('email')
        if email and not re.match(r'^[^@\s]+@[^@\s]+\.[^@\s]+$', str(email)):
            errors['email'] = 'Enter a valid email address.'

        mobile = data.get('mobile')
        if mobile and not re.match(r'^[0-9+\-\s]{7,15}$', str(mobile)):
            errors['mobile'] = 'Enter a valid mobile number.'

        return errors

    def get(self, request, id=None):
        if id is not None:
            try:
                company = Company.objects.get(id=id)
            except Company.DoesNotExist:
                return fail("No company found", status.HTTP_404_NOT_FOUND)
            return ok(self._serialize(request, company))

        search = request.query_params.get('search', '').strip()
        qs = Company.objects.all().order_by('-created_at')
        if search:
            qs = qs.filter(
                Q(company_name__icontains=search)
                | Q(gst_number__icontains=search)
                | Q(mobile__icontains=search)
                | Q(email__icontains=search)
            )
        data_list = [self._serialize(request, c, row=i) for i, c in enumerate(qs, 1)]
        return ok(data_list)

    def post(self, request):
        data = request.data
        errors = self._validate(data)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)

        logo = self._handle_logo(request, data)
        try:
            company = Company.objects.create(
                company_name=data.get('company_name'),
                address=data.get('address'),
                mobile=data.get('mobile'),
                email=data.get('email'),
                gst_number=data.get('gst_number'),
                bank_details=data.get('bank_details'),
                dealers_in=data.get('dealers_in'),
                invoice_terms=data.get('invoice_terms') or None,
                logo=logo,
            )
            return ok(self._serialize(request, company), message="Company added successfully",
                       code=status.HTTP_201_CREATED)
        except Exception as e:
            return fail(str(e))

    def put(self, request, id):
        data = request.data
        try:
            company = Company.objects.get(id=id)
        except Company.DoesNotExist:
            return fail("No company found", status.HTTP_404_NOT_FOUND)

        errors = self._validate(data, partial=True)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)

        try:
            logo = self._handle_logo(request, data)
            company.company_name = data.get("company_name", company.company_name)
            company.address = data.get("address", company.address)
            company.mobile = data.get("mobile", company.mobile)
            company.email = data.get("email", company.email)
            company.gst_number = data.get("gst_number", company.gst_number)
            company.bank_details = data.get("bank_details", company.bank_details)
            company.dealers_in = data.get("dealers_in", company.dealers_in)
            company.invoice_terms = data.get("invoice_terms", company.invoice_terms)
            if logo:
                company.logo = logo
            company.save()
            return ok(self._serialize(request, company), message="Company updated successfully")
        except Exception as e:
            return fail(str(e))

    def delete(self, request, id):
        try:
            company = Company.objects.get(id=id)
        except Company.DoesNotExist:
            return fail("No company found", status.HTTP_404_NOT_FOUND)
        company.delete()
        return ok(message="Company deleted successfully")


# =========================================================== CUSTOMER =====
class CustomerAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def _serialize(self, request, customer, row=None):
        payload = {
            'id': customer.id,
            'name': customer.name,
            'address': customer.address,
            'gst_number': customer.gst_number,
            'mobile': customer.mobile,
        }
        if row is not None:
            payload['row'] = row
        return payload

    def _validate(self, data, partial=False):
        errors = {}
        name = data.get('name')
        if not partial and not (name and str(name).strip()):
            errors['name'] = 'Customer name is required.'
        mobile = data.get('mobile')
        if mobile and not re.match(r'^[0-9+\-\s]{7,15}$', str(mobile)):
            errors['mobile'] = 'Enter a valid mobile number.'
        return errors

    def get(self, request, id=None):
        if id is not None:
            try:
                customer = Customer.objects.get(id=id)
            except Customer.DoesNotExist:
                return fail("No customer found", status.HTTP_404_NOT_FOUND)
            return ok(self._serialize(request, customer))

        search = request.query_params.get('search', '').strip()
        qs = Customer.objects.all().order_by('-created_at')
        if search:
            qs = qs.filter(
                Q(name__icontains=search)
                | Q(gst_number__icontains=search)
                | Q(mobile__icontains=search)
            )
        data_list = [self._serialize(request, c, row=i) for i, c in enumerate(qs, 1)]
        return ok(data_list)

    def post(self, request):
        data = request.data
        errors = self._validate(data)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)
        try:
            customer = Customer.objects.create(
                name=data.get('name'),
                address=data.get('address'),
                gst_number=data.get('gst_number'),
                mobile=data.get('mobile'),
            )
            return ok(self._serialize(request, customer), message="Customer added successfully",
                       code=status.HTTP_201_CREATED)
        except Exception as e:
            return fail(str(e))

    def put(self, request, id):
        data = request.data
        try:
            customer = Customer.objects.get(id=id)
        except Customer.DoesNotExist:
            return fail("No customer found", status.HTTP_404_NOT_FOUND)

        errors = self._validate(data, partial=True)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)

        try:
            customer.name = data.get("name", customer.name)
            customer.address = data.get("address", customer.address)
            customer.gst_number = data.get("gst_number", customer.gst_number)
            customer.mobile = data.get("mobile", customer.mobile)
            customer.save()
            return ok(self._serialize(request, customer), message="Customer updated successfully")
        except Exception as e:
            return fail(str(e))

    def delete(self, request, id):
        try:
            customer = Customer.objects.get(id=id)
        except Customer.DoesNotExist:
            return fail("No customer found", status.HTTP_404_NOT_FOUND)
        if customer.invoices.exists():
            return fail("This customer has invoices attached and can't be deleted.",
                        status.HTTP_400_BAD_REQUEST)
        customer.delete()
        return ok(message="Customer deleted successfully")


# ============================================================ PRODUCT =====
class ProductAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def _serialize(self, request, product, row=None):
        payload = {
            'id': product.id,
            'name': product.name,
            'hsn_code': product.hsn_code,
            'default_rate': str(product.default_rate),
            'unit': product.unit,
        }
        if row is not None:
            payload['row'] = row
        return payload

    def _validate(self, data, partial=False):
        errors = {}
        name = data.get('name')
        if not partial and not (name and str(name).strip()):
            errors['name'] = 'Product name is required.'
        rate = data.get('default_rate')
        if rate not in (None, ''):
            try:
                if float(rate) < 0:
                    errors['default_rate'] = 'Default rate cannot be negative.'
            except (TypeError, ValueError):
                errors['default_rate'] = 'Default rate must be a valid number.'
        return errors

    def get(self, request, id=None):
        if id is not None:
            try:
                product = Product.objects.get(id=id)
            except Product.DoesNotExist:
                return fail("No product found", status.HTTP_404_NOT_FOUND)
            return ok(self._serialize(request, product))

        search = request.query_params.get('search', '').strip()
        qs = Product.objects.all().order_by('-created_at')
        if search:
            qs = qs.filter(Q(name__icontains=search) | Q(hsn_code__icontains=search))
        data_list = [self._serialize(request, p, row=i) for i, p in enumerate(qs, 1)]
        return ok(data_list)

    def post(self, request):
        data = request.data
        errors = self._validate(data)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)
        try:
            product = Product.objects.create(
                name=data.get('name'),
                hsn_code=data.get('hsn_code'),
                default_rate=data.get('default_rate') or 0,
                unit=data.get('unit', 'Kg'),
            )
            return ok(self._serialize(request, product), message="Product added successfully",
                       code=status.HTTP_201_CREATED)
        except Exception as e:
            return fail(str(e))

    def put(self, request, id):
        data = request.data
        try:
            product = Product.objects.get(id=id)
        except Product.DoesNotExist:
            return fail("No product found", status.HTTP_404_NOT_FOUND)

        errors = self._validate(data, partial=True)
        if errors:
            return fail(errors, status.HTTP_400_BAD_REQUEST)

        try:
            product.name = data.get("name", product.name)
            product.hsn_code = data.get("hsn_code", product.hsn_code)
            product.default_rate = data.get("default_rate", product.default_rate)
            product.unit = data.get("unit", product.unit)
            product.save()
            return ok(self._serialize(request, product), message="Product updated successfully")
        except Exception as e:
            return fail(str(e))

    def delete(self, request, id):
        try:
            product = Product.objects.get(id=id)
        except Product.DoesNotExist:
            return fail("No product found", status.HTTP_404_NOT_FOUND)
        if product.invoice_items.exists():
            return fail("This product is used in invoices and can't be deleted.",
                        status.HTTP_400_BAD_REQUEST)
        product.delete()
        return ok(message="Product deleted successfully")


# ============================================================ INVOICE =====
class InvoiceAPIView(APIView):
    permission_classes = (IsAuthenticated,)

    def _serialize(self, request, invoice, row=None):
        items = [
            {
                'id': item.id,
                'product': item.product_id,
                'product_name': item.product.name,
                'hsn_code': item.product.hsn_code,
                'quantity': str(item.quantity),
                'rate': str(item.rate),
                'amount': str(item.amount),
            }
            for item in invoice.items.all()
        ]
        payload = {
            'id': invoice.id,
            'invoice_number': invoice.invoice_number,
            'invoice_date': invoice.invoice_date,
            'customer': invoice.customer_id,
            'customer_name': invoice.customer.name,
            'customer_gst_number': invoice.customer.gst_number,
            'customer_address': invoice.customer.address,
            'eway_bill_no': invoice.eway_bill_no,
            'eway_bill_date': invoice.eway_bill_date,
            'vehicle_no': invoice.vehicle_no,
            'subtotal': str(invoice.subtotal),
            'cgst': str(invoice.cgst),
            'sgst': str(invoice.sgst),
            'igst': str(invoice.igst),
            'round_off': str(invoice.round_off),
            'grand_total': str(invoice.grand_total),
            'items': items,
        }
        if row is not None:
            payload['row'] = row
        return payload

    def _validate_items(self, items_data):
        """Returns (cleaned_items, error_message_or_None). Also rejects duplicate products."""
        if not items_data:
            return None, "Add at least one line item."

        cleaned = []
        seen_products = set()
        for idx, it in enumerate(items_data, 1):
            product_id = it.get('product')
            if not product_id:
                return None, f"Line {idx}: select a product."
            if str(product_id) in seen_products:
                return None, f"Line {idx}: this product is already added to the invoice."
            seen_products.add(str(product_id))

            if not Product.objects.filter(id=product_id).exists():
                return None, f"Line {idx}: product not found."

            try:
                qty = to_decimal(it.get('quantity', 0), 'quantity')
                rate = to_decimal(it.get('rate', 0), 'rate')
            except ValueError as e:
                return None, f"Line {idx}: {e}"

            if qty <= 0:
                return None, f"Line {idx}: quantity must be greater than 0."
            if rate < 0:
                return None, f"Line {idx}: rate cannot be negative."

            cleaned.append({'product_id': product_id, 'quantity': qty, 'rate': rate})

        return cleaned, None

    def get(self, request, id=None):
        if id is not None:
            try:
                invoice = Invoice.objects.get(id=id)
            except Invoice.DoesNotExist:
                return fail("No invoice found", status.HTTP_404_NOT_FOUND)
            return ok(self._serialize(request, invoice))

        search = request.query_params.get('search', '').strip()
        qs = Invoice.objects.all().order_by('-created_at')
        if search:
            qs = qs.filter(
                Q(invoice_number__icontains=search) | Q(customer__name__icontains=search)
            )
        data_list = [self._serialize(request, i, row=r) for r, i in enumerate(qs, 1)]
        return ok(data_list)

    def _validate_tax_fields(self, cgst, sgst, igst, round_off):
        if cgst < 0:
            return "CGST cannot be negative."
        if sgst < 0:
            return "SGST cannot be negative."
        if igst < 0:
            return "IGST cannot be negative."
        # Round off exists only to absorb paisa-level rounding — cap its
        # magnitude so a typo can't silently swing the invoice total.
        if abs(round_off) >= 1:
            return "Round off must be a small adjustment (less than ₹1)."
        return None

    def post(self, request):
        data = request.data
        invoice_number = (data.get('invoice_number') or '').strip()
        customer_id = data.get('customer')
        items_data = data.get('items', [])

        if not invoice_number:
            return fail("Invoice number is required.")
        if Invoice.objects.filter(invoice_number=invoice_number).exists():
            return fail(f"Invoice number '{invoice_number}' is already in use.")
        if not customer_id or not Customer.objects.filter(id=customer_id).exists():
            return fail("A valid customer is required.")
        if not data.get('invoice_date'):
            return fail("Invoice date is required.")

        cleaned_items, err = self._validate_items(items_data)
        if err:
            return fail(err)

        try:
            cgst = to_decimal(data.get('cgst') or 0, 'cgst')
            sgst = to_decimal(data.get('sgst') or 0, 'sgst')
            igst = to_decimal(data.get('igst') or 0, 'igst')
            round_off = to_decimal(data.get('round_off') or 0, 'round_off')
        except ValueError as e:
            return fail(str(e))

        tax_err = self._validate_tax_fields(cgst, sgst, igst, round_off)
        if tax_err:
            return fail(tax_err)

        try:
            with transaction.atomic():
                subtotal = q2(sum((i['quantity'] * i['rate'] for i in cleaned_items), Decimal('0')))
                grand_total = q2(subtotal + cgst + sgst + igst + round_off)

                if grand_total < 0:
                    return fail("Invoice total cannot be negative — check the entered amounts.")

                invoice = Invoice.objects.create(
                    invoice_number=invoice_number,
                    invoice_date=data.get('invoice_date'),
                    customer_id=customer_id,
                    eway_bill_no=data.get('eway_bill_no'),
                    eway_bill_date=data.get('eway_bill_date') or None,
                    vehicle_no=data.get('vehicle_no'),
                    subtotal=subtotal,
                    cgst=q2(cgst),
                    sgst=q2(sgst),
                    igst=q2(igst),
                    round_off=q2(round_off),
                    grand_total=grand_total,
                )
                InvoiceItem.objects.bulk_create([
                    InvoiceItem(
                        invoice=invoice,
                        product_id=i['product_id'],
                        quantity=i['quantity'],
                        rate=i['rate'],
                        amount=q2(i['quantity'] * i['rate']),
                    )
                    for i in cleaned_items
                ])
            return ok(self._serialize(request, invoice), message="Invoice created successfully",
                       code=status.HTTP_201_CREATED)
        except Exception as e:
            return fail(str(e))

    def put(self, request, id):
        data = request.data
        try:
            invoice = Invoice.objects.get(id=id)
        except Invoice.DoesNotExist:
            return fail("No invoice found", status.HTTP_404_NOT_FOUND)

        new_number = data.get("invoice_number")
        if new_number and new_number != invoice.invoice_number:
            if Invoice.objects.filter(invoice_number=new_number).exclude(id=id).exists():
                return fail(f"Invoice number '{new_number}' is already in use.")

        cleaned_items = None
        if "items" in data:
            cleaned_items, err = self._validate_items(data.get("items", []))
            if err:
                return fail(err)

        try:
            cgst = to_decimal(data.get('cgst', invoice.cgst), 'cgst')
            sgst = to_decimal(data.get('sgst', invoice.sgst), 'sgst')
            igst = to_decimal(data.get('igst', invoice.igst), 'igst')
            round_off = to_decimal(data.get('round_off', invoice.round_off), 'round_off')
        except ValueError as e:
            return fail(str(e))

        tax_err = self._validate_tax_fields(cgst, sgst, igst, round_off)
        if tax_err:
            return fail(tax_err)

        # Validate the prospective total BEFORE touching the database — a
        # `return` inside transaction.atomic() commits rather than rolling
        # back (only an exception rolls back), so any check that can fail
        # must happen first, especially since we delete existing line items.
        prospective_subtotal = (
            q2(sum((i['quantity'] * i['rate'] for i in cleaned_items), Decimal('0')))
            if cleaned_items is not None else invoice.subtotal
        )
        prospective_grand_total = q2(prospective_subtotal + cgst + sgst + igst + round_off)
        if prospective_grand_total < 0:
            return fail("Invoice total cannot be negative — check the entered amounts.")

        try:
            with transaction.atomic():
                invoice.invoice_number = new_number or invoice.invoice_number
                invoice.invoice_date = data.get("invoice_date", invoice.invoice_date)
                invoice.eway_bill_no = data.get("eway_bill_no", invoice.eway_bill_no)
                invoice.eway_bill_date = data.get("eway_bill_date", invoice.eway_bill_date) or None
                invoice.vehicle_no = data.get("vehicle_no", invoice.vehicle_no)
                if data.get("customer"):
                    if not Customer.objects.filter(id=data["customer"]).exists():
                        raise ValueError("A valid customer is required.")
                    invoice.customer_id = data.get("customer")

                if cleaned_items is not None:
                    invoice.items.all().delete()
                    InvoiceItem.objects.bulk_create([
                        InvoiceItem(
                            invoice=invoice,
                            product_id=i['product_id'],
                            quantity=i['quantity'],
                            rate=i['rate'],
                            amount=q2(i['quantity'] * i['rate']),
                        )
                        for i in cleaned_items
                    ])
                    invoice.subtotal = prospective_subtotal

                invoice.cgst = q2(cgst)
                invoice.sgst = q2(sgst)
                invoice.igst = q2(igst)
                invoice.round_off = q2(round_off)
                invoice.grand_total = q2(
                    invoice.subtotal + invoice.cgst + invoice.sgst + invoice.igst + invoice.round_off
                )
                invoice.save()

            return ok(self._serialize(request, invoice), message="Invoice updated successfully")
        except ValueError as e:
            return fail(str(e))
        except Exception as e:
            return fail(str(e))

    def delete(self, request, id):
        try:
            invoice = Invoice.objects.get(id=id)
        except Invoice.DoesNotExist:
            return fail("No invoice found", status.HTTP_404_NOT_FOUND)
        invoice.delete()
        return ok(message="Invoice deleted successfully")




def send_otp_email(email, otp):
    subject = 'Your One-Time  (OTP) for Verification'
    message = f'''Dear User,

    Your One-Time  (OTP) for verification is:

    {otp}

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
    '''
    try:
        send_mail(
            subject,
            message,
            settings.DEFAULT_FROM_EMAIL,
            [email],
            fail_silently=False,
        )
    except Exception as e:
        print(f"Error sending email: {e}")
def send_otp_emails(email, otp):
   
    subject = 'Your One-Time  (OTP) for Verification'
    message = f'''Dear User,

    Your One-Time  (OTP) for verification is:

    {otp}

    Please enter this code to proceed. This OTP is valid for the next 1 minutes.

    If you did not request this code, please ignore this email.

    Thank you,  
    Pearlcon Technologies LLP
    https://pearlcons.com
        '''
    try:
        send_mail(
            subject,
            message,
            settings.DEFAULT_FROM_EMAIL,
            [email],
            fail_silently=False,
        )
    except Exception as e:
        print(f"Error sending email: {e}")

        
from django.contrib.auth import get_user_model
User = get_user_model()

class SendotpAPIView(APIView):
    def post(self, request):
        data = request.data
        try:
            email = data.get('params', {}).get('email', None)
            print('Received email:', email)

            # ✅ Step 1: Check if email exists in registered users
            if not User.objects.filter(email=email).exists():
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "Email not found"},
                    "error": True,
                    "message": "Email not registered"
                })

            # ✅ Step 2: Create OTP record and send OTP
            user = Otp.objects.create(email=email)
            otp = get_random_string(length=6, allowed_chars='1234567890')
            user.otp = otp
            user.otp_created_at = timezone.now()
            user.save()

            threading.Thread(target=send_otp_email, args=(email, otp)).start()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "Success"},
                "error": None,
                "data": {"email": email}
            })
        except Exception as e:
            print("Error:", e)
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "Internal Server Error"},
                'error': True,
                "message": str(e)
            })


class SendotpsAPIView(APIView):
    def post(self, request):
        data = request.data
        try:
            email = data.get('email', None)
            print('Received email:', email)

            # If this is registration
            if User.objects.filter(email=email).exists():
                return Response({
                    "status": {"code": status.HTTP_409_CONFLICT, "response": "Email already registered"},
                    "error": True,
                    "message": "This email is already registered. Please use another email."
                })

            otp = get_random_string(length=6, allowed_chars='1234567890')
            user = Otp.objects.create(email=email, otp=otp, otp_created_at=timezone.now())

            threading.Thread(target=send_otp_emails, args=(email, otp)).start()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "Success"},
                "error": None,
                "data": {"email": email}
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "Internal Server Error"},
                'error': True,
                "message": str(e)
            })

from datetime import timedelta
from django.utils import timezone

class VerifyotpAPIView(APIView):
    def get(self, request):
        email = request.query_params.get('email')
        otp_entered = request.query_params.get('otp')

        try:
            user_otp = Otp.objects.filter(email=email).latest('otp_created_at')

            # Expiry time check (30 seconds)
            expiration_time = user_otp.otp_created_at + timedelta(seconds=60)
            if timezone.now() > expiration_time:
                return Response({
                    "status": 401,
                    "message": "OTP expired. Please request a new one.",
                    "error": True
                }, status=status.HTTP_200_OK) 

            if otp_entered == user_otp.otp:
                return Response({
                    "status": 200,
                    "message": "OTP Verified",
                    "error": False
                }, status=status.HTTP_200_OK)
            else:
                return Response({
                    "status": 400,
                    "message": "Invalid OTP",
                    "error": True
                }, status=status.HTTP_200_OK)

        except Otp.DoesNotExist:
            return Response({
                "status": 404,
                "message": "OTP not found",
                "error": True
            }, status=status.HTTP_200_OK)




    def delete(self, request, id):
        if id is not None:
            try:
                profile = Profiles.objects.get(user_id=id)

                # Delete the image file from storage (optional)
                if profile.profiles:  # replace 'image' with your actual image field name
                    profile.profiles.delete(save=False)  # Deletes the file from MEDIA folder
                    profile.profiles = None
                    profile.save()

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "message": "Profile image deleted successfully"
                })

            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": None,
                    "message": "Profile not found"
                })

        return Response({
            "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
            "error": "ID not provided",
            "message": "User ID is required"
        })




class ProfileupdateAPIView(APIView):
    
    permission_classes = (IsAuthenticated,)

    def get(self, request, **kwargs):
        id = kwargs.get('id')


        if id is not None:
            try:
                user = User.objects.get(id=id)
                company = Profiles.objects.get(user_id=user.id)
                if company.profiles and company.profiles.url != "../static/dummy.png":
                    pr = company.profiles.url
                else:
                    pr = "../static/dummy.png"

                data = {
                    'name': company.name,
                    'email': company.email,
                    'phone': company.phone,
                    'f_name': user.first_name,
                    'l_name': user.last_name,

                    'profile' : pr,
                    'id': user.id   
                }



                

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "Success"},
                    "error": None,
                    "data": data
                })
            except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "Failed"},
                    'error': True,
                    "message": "Company not found"
                })

    def post(self, request):
        data = request.data
        try:


            pho = data.get("prof_photo")
            # name = data.get("username")

            take = Profiles.objects.get(user_id=request.user.id)
            take.profiles = pho

            take.save()
            # # Create User instance
            # van = User(username=name, email=email, password=hashed_password)
            # van.save()

           

            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Profile updated successfully"
            })

        except KeyError as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Missing required field: {str(e)}"
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_500_INTERNAL_SERVER_ERROR, "response": "failed"},
                "error": True,
                "message": f"An error occurred: {str(e)}"
            })


    def put(self, request, id):
        data = request.data
        # 1. போட்டோவை FILES-ல் இருந்து எடுக்கவும்
        photo = request.FILES.get('prof_photo') 
        
        try:
            mm = Profiles.objects.get(user_id=id)
            sd = User.objects.get(id=id)

            # 2. User டேபிள் அப்டேட் (get() பயன்படுத்துவது பாதுகாப்பானது)
            sd.username = data.get("first_name", sd.username)
            sd.first_name = data.get("first_names", sd.first_name)
            sd.last_name = data.get("last_name", sd.last_name)
            sd.email = data.get("email_id", sd.email)
            sd.save()

            # 3. Profiles டேபிள் அப்டேட்
            mm.email = data.get("email_id", mm.email)
            mm.phone = data.get("phone_no", mm.phone)
            mm.name = data.get("first_name", mm.name)

            # 4. இமேஜ் இருந்தால் மட்டும் அப்டேட் செய்யவும்
            if photo:
                mm.profiles = photo
            
            mm.save()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "User updated successfully"
            })

        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "User not found"
            })




class RegisterAPIView(APIView):
    def get(self, request, **kwargs):
        id = kwargs.get('id')


        if id is not None:
            try:
                student = Profiles.objects.get(user_id=id)
                data = {
                    'id': student.user_id,
                    'username': student.name,
                    'phone': student.phone,
                    'password': student.password,
                    'email': student.email,
                    'role': student.role,
                    'course': student.course,      # 👈 add this
                    'batch': student.batch,  

                    'status': student.status,
                    # Photo URL-ஐ எடுக்க (உதாரணமாக: http://127.0.0.1:8000/media/students/abc.jpg)
                    'profile_photo': request.build_absolute_uri(student.profiles.url) if student.profiles else None
                }


                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": data
                })
            except Profiles.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "No student found",
                })
        else:
            try:
                employees = Profiles.objects.filter(role__in=[2, 3,0]).order_by('-created_at')
                employee_list = []
                for index, student in enumerate(employees, 1):
                    employee_list.append({
                        'row': index,
                        'id': student.user_id,
                        'employeeName': student.name,
                        'email': student.email,
                        'phone': student.phone,
                        'status': student.status,
                        'role': student.role,
                        'course': student.course,      # 👈 add this
                        'batch': student.batch, 

                        'photo': request.build_absolute_uri(student.profiles.url) if student.profiles else None
                    })

                return Response({
                    "status": {"code": status.HTTP_200_OK, "response": "success"},
                    "error": None,
                    "data": employee_list
                })
            except Exception as e:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": str(e),
                })
    def post(self, request):
        data = request.data
        # ஆப்பில் இருந்து "profile_photo" என்று அனுப்புகிறோம், அதை இங்கே எடுக்கிறோம்
        photo = request.FILES.get('profile_photo') 


        try:
            username = data.get('username')
            email = data.get('email')
            phone = data.get('phone')
            password = data.get('password')
            role = data.get('role')
            course = data.get('course')     # 👈 add this
            batch = data.get('batch')  


            # 1. User உருவாக்குதல்
            hashed_password = make_password(password)
            van = User.objects.create(
                username=username, 
                email=email, 
                password=hashed_password
            )

            # 2. Profile உருவாக்குதல்
            photo = request.FILES.get('profile_photo') 

            profile = Profiles.objects.create(
                name=username,
                email=email,
                phone=phone,
                role=role,
                course=course,              # 👈 add this
                batch=batch, 
                user_id=van.id,
                password=password,
                profiles=photo  # 👈 உங்கள் Database Column பெயர் 'profiles' என்றால் இது சரி
            )

            return Response({
                "status": {"code": 201, "response": "success"},
                "error": None,
                "message": "Employee created successfully",
            }, status=status.HTTP_201_CREATED)

        except Exception as e:
            return Response({
                "status": {"code": 400, "response": "failed"},
                "error": True,
                "message": f"Error: {str(e)}"
        }, status=status.HTTP_400_BAD_REQUEST)


    
    def put(self, request, id):
        data = request.data
        # ஆப்பில் இருந்து "profile_photo" என்று அனுப்புகிறோம், அதை இங்கே எடுக்கிறோம்
        photo = request.FILES.get('profile_photo') 
        
        try:
                photo = request.FILES.get('profile_photo') 

                username = data.get('username')
                email = data.get('email')
                phone = data.get('phone')
                password = data.get('password')
                role = data.get('role')
                course = data.get('course')     # 👈 add this
                batch = data.get('batch')  

                mm = Profiles.objects.get(user_id=id)
                sd = User.objects.get(id=id)

                mm.name = username
                mm.email = email
                mm.phone = phone
                mm.role = role
                mm.course = course              # 👈 add this
                mm.batch = batch  
                mm.password = password

                if photo:
                    mm.profiles = photo
                mm.save()
                passes = make_password(password) 
                sd.username = username
                sd.email = email
                sd.password = passes
                sd.save()

                return Response({
                    "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                    "error": None,
                    "message": "User updated successfully"
                })
        except ObjectDoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Something went wrong"
                })

    def delete(self,  *args, **kwargs):
        company_id = kwargs.get('id')

        try:

            pr  = Profiles.objects.get(user_id =company_id)
            pr.delete()
            company = User.objects.get(id=company_id)
            company.delete()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Company deleted successfully"
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found"
            })



class CourseAPIView(APIView):
 
    def get(self, request):
        try:
            courses = Course.objects.all().order_by("name")
            data = [{"id": c.id, "name": c.name} for c in courses]
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data,
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)
 
    def post(self, request):
        try:
            name = (request.data.get("name") or "").strip()
            if not name:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Course name is required",
                }, status=status.HTTP_400_BAD_REQUEST)
 
            course = Course.objects.create(name=name)
            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Course added successfully",
                "data": {"id": course.id, "name": course.name},
            }, status=status.HTTP_201_CREATED)
        except IntegrityError:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "This course already exists",
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)
 
    def put(self, request, pk):
        try:
            try:
                course = Course.objects.get(id=pk)
            except Course.DoesNotExist:
                return Response({
                    "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                    "error": True,
                    "message": "Course not found",
                }, status=status.HTTP_404_NOT_FOUND)
 
            name = (request.data.get("name") or "").strip()
            if not name:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Course name is required",
                }, status=status.HTTP_400_BAD_REQUEST)
 
            course.name = name
            course.save()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Course updated successfully",
            }, status=status.HTTP_200_OK)
        except IntegrityError:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "This course already exists",
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)
 
    def delete(self, request, pk):
        try:
            course = Course.objects.get(id=pk)
            course.delete()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Course deleted successfully",
            }, status=status.HTTP_200_OK)
        except Course.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Course not found",
            }, status=status.HTTP_404_NOT_FOUND)
        except django_models.ProtectedError:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "This course is in use and cannot be deleted",
            }, status=status.HTTP_400_BAD_REQUEST)
 

from .models import SeoSettings, Course


def seo_to_dict(seo):
    return {
        "id": seo.id,
        "page_slug": seo.page_slug,
        "meta_title": seo.meta_title,
        "meta_description": seo.meta_description,
        "meta_keywords": seo.meta_keywords or "",
        "updated_at": seo.updated_at,
    }


class SeoAPIView(APIView):
    # Public website pages need to READ SEO data, so GET is open.
    # Only logged-in admin can create / update / delete.
    # def get_permissions(self):
    #     if self.request.method == "GET":
    #         return [AllowAny()]
    #     return [IsAuthenticated()]

    def get(self, request, **kwargs):
        page_slug = request.query_params.get("page_slug")
        try:
            if page_slug:
                seo = SeoSettings.objects.filter(page_slug=page_slug).first()
                data = seo_to_dict(seo) if seo else None   # null if not set yet
            else:
                data = [seo_to_dict(s) for s in SeoSettings.objects.all()]

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data
            })
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def post(self, request):
        data = request.data
        try:
            page_slug = (data.get("page_slug") or "").strip()
            meta_title = (data.get("meta_title") or "").strip()
            meta_description = (data.get("meta_description") or "").strip()
            meta_keywords = (data.get("meta_keywords") or "").strip()

            if not page_slug or not meta_title or not meta_description:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "page_slug, meta_title and meta_description are required",
                }, status=status.HTTP_400_BAD_REQUEST)

            # Upsert: create first time, update afterwards
            seo, created = SeoSettings.objects.update_or_create(
                page_slug=page_slug,
                defaults={
                    "meta_title": meta_title,
                    "meta_description": meta_description,
                    "meta_keywords": meta_keywords,
                },
            )

            return Response({
                "status": {
                    "code": status.HTTP_201_CREATED if created else status.HTTP_200_OK,
                    "response": "success",
                },
                "error": None,
                "message": "SEO created successfully" if created else "SEO updated successfully",
                "data": seo_to_dict(seo),
            }, status=status.HTTP_201_CREATED if created else status.HTTP_200_OK)

        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": f"Error: {str(e)}",
            }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, *args, **kwargs):
        page_slug = request.query_params.get("page_slug")
        try:
            seo = SeoSettings.objects.get(page_slug=page_slug)
            seo.delete()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "SEO deleted successfully",
            })
        except ObjectDoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "No data found",
            }, status=status.HTTP_404_NOT_FOUND)

# views.py — full corrected file.
# QuestionAPIView no longer looks up an Exam by id at all — it just
# stores/filters by the `course` string. This removes the entire
# "Selected exam does not exist" failure mode.
# Every Response() also passes a real HTTP status now, so failures
# actually reject on the frontend instead of silently returning 200.

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from django.contrib.auth.models import User
from django.db import models as django_models

from .models import Exam, Question, Profiles   # adjust import path to match your project


def get_student_display_name(user):
    try:
        profile = getattr(user, "profiles", None) or getattr(user, "profile", None)
        if profile and getattr(profile, "name", None):
            return profile.name
    except Exception:
        pass
    return user.get_full_name() or user.username


# ---------------------------------------------------------------------------
# EXAM  (unchanged — still per-student scheduled exams)
# ---------------------------------------------------------------------------
class ExamAPIView(APIView):

    def get(self, request):
        try:
            course = request.query_params.get("course")
            student_id = request.query_params.get("student")

            exams = Exam.objects.select_related("student").all().order_by("-created_at")
            if course:
                exams = exams.filter(course=course)
            if student_id:
                exams = exams.filter(student_id=student_id)

            data = [{
                "id": e.id,
                "student": e.student_id,
                "student_name": get_student_display_name(e.student),
                "title": e.title,
                "course": e.course,
                "date": e.date,
                "duration": e.duration,
                "status": e.status,
            } for e in exams]

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data,
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def post(self, request):
        try:
            payload = request.data
            required_fields = ["student", "title", "course", "date", "duration"]
            missing = [f for f in required_fields if not payload.get(f)]
            if missing:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": f"Missing fields: {', '.join(missing)}",
                }, status=status.HTTP_400_BAD_REQUEST)

            student = User.objects.get(id=payload["student"])
            exam = Exam.objects.create(
                student=student,
                title=payload["title"],
                course=payload["course"],
                date=payload["date"],
                duration=payload["duration"],
                status=payload.get("status", "Scheduled"),
            )
            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Exam created successfully",
                "data": {"id": exam.id},
            }, status=status.HTTP_201_CREATED)
        except User.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "Selected student does not exist",
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def put(self, request, pk):
        try:
            exam = Exam.objects.get(id=pk)
            payload = request.data

            if "student" in payload:
                exam.student = User.objects.get(id=payload["student"])
            for field in ["title", "course", "date", "duration", "status"]:
                if field in payload:
                    setattr(exam, field, payload[field])
            exam.save()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Exam updated successfully",
            }, status=status.HTTP_200_OK)
        except Exam.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Exam not found",
            }, status=status.HTTP_404_NOT_FOUND)
        except User.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "Selected student does not exist",
            }, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        try:
            exam = Exam.objects.get(id=pk)
            exam.delete()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Exam deleted successfully",
            }, status=status.HTTP_200_OK)
        except Exam.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Exam not found",
            }, status=status.HTTP_404_NOT_FOUND)
        except django_models.ProtectedError:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": "This exam is linked to records that prevent deletion",
            }, status=status.HTTP_400_BAD_REQUEST)


# ---------------------------------------------------------------------------
# QUESTION — now keyed purely by `course` (a string). No more FK lookups,
# no more "exam id doesn't exist" failures.
# ---------------------------------------------------------------------------
class QuestionAPIView(APIView):

    def get(self, request):
        try:
            course = request.query_params.get("course")

            questions = Question.objects.all().order_by("-created_at")
            if course:
                questions = questions.filter(course=course)

            data = [{
                "id": q.id,
                "course": q.course,
                "question": q.question,
                "options": q.options,
                "answer": q.answer,          # frontend highlights this option green
                "marks": q.marks,
            } for q in questions]

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "data": data,
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def post(self, request):
        try:
            payload = request.data
            required_fields = ["course", "question", "options", "answer", "marks"]
            missing = [f for f in required_fields if not payload.get(f)]
            if missing:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": f"Missing fields: {', '.join(missing)}",
                }, status=status.HTTP_400_BAD_REQUEST)

            options = payload["options"]
            if payload["answer"] not in options:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Correct answer must be one of the given options",
                }, status=status.HTTP_400_BAD_REQUEST)

            question = Question.objects.create(
                course=payload["course"],
                question=payload["question"],
                options=options,
                answer=payload["answer"],
                marks=payload["marks"],
            )
            return Response({
                "status": {"code": status.HTTP_201_CREATED, "response": "success"},
                "error": None,
                "message": "Question added successfully",
                "data": {"id": question.id},
            }, status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def put(self, request, pk):
        try:
            question = Question.objects.get(id=pk)
            payload = request.data

            options = payload.get("options", question.options)
            answer = payload.get("answer", question.answer)
            if answer not in options:
                return Response({
                    "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                    "error": True,
                    "message": "Correct answer must be one of the given options",
                }, status=status.HTTP_400_BAD_REQUEST)

            question.course = payload.get("course", question.course)
            question.question = payload.get("question", question.question)
            question.options = options
            question.answer = answer
            question.marks = payload.get("marks", question.marks)
            question.save()

            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Question updated successfully",
            }, status=status.HTTP_200_OK)
        except Question.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Question not found",
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        try:
            question = Question.objects.get(id=pk)
            question.delete()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Question deleted successfully",
            }, status=status.HTTP_200_OK)
        except Question.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Question not found",
            }, status=status.HTTP_404_NOT_FOUND)


# ---------------------------------------------------------------------------
# STUDENT DELETE
# ---------------------------------------------------------------------------
class StudentDeleteAPIView(APIView):

    def delete(self, request, pk):
        try:
            student = Profiles.objects.get(user_id=pk)
            student.delete()
            return Response({
                "status": {"code": status.HTTP_200_OK, "response": "success"},
                "error": None,
                "message": "Student deleted successfully",
            }, status=status.HTTP_200_OK)
        except Profiles.DoesNotExist:
            return Response({
                "status": {"code": status.HTTP_404_NOT_FOUND, "response": "failed"},
                "error": True,
                "message": "Student not found",
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({
                "status": {"code": status.HTTP_400_BAD_REQUEST, "response": "failed"},
                "error": True,
                "message": str(e),
            }, status=status.HTTP_400_BAD_REQUEST)





# student_exam_views.py  — NEW file, put it next to your views.py.
#
# Rules enforced on the SERVER (the frontend only displays them):
#   * a student sees / attempts only their own exams
#   * Start works only on the exam's date (server local date)
#   * one attempt per exam; the timer runs from the moment it is started
#   * questions are shuffled once per attempt, options shuffled per question
#   * correct answers are NEVER sent to the browser
#   * the exam is graded on the server when submitted (or when time is up)

import random
from datetime import timedelta

from django.db.models import Count
from django.utils import timezone
from rest_framework import status as http
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Exam, ExamAttempt, Question

GRACE_SECONDS = 5   # tolerance for network delay when saving/submitting near 00:00


# ---------------------------------------------------------------------------
# helpers
# ---------------------------------------------------------------------------
def ok(data=None, message="", code=http.HTTP_200_OK):
    return Response({
        "status": {"code": code, "response": "success"},
        "error": None,
        "message": message,
        "data": data,
    }, status=code)


def fail(message, code=http.HTTP_400_BAD_REQUEST):
    return Response({
        "status": {"code": code, "response": "failed"},
        "error": True,
        "message": message,
    }, status=code)


def student_name(user):
    # ⚠️ Adjust to however your Profiles row is linked to User.
    try:
        profile = getattr(user, "profiles", None) or getattr(user, "profile", None)
        if profile and getattr(profile, "name", None):
            return profile.name
    except Exception:
        pass
    return user.get_full_name() or user.username


def parse_duration(value):
    """'30:00' -> 1800, '25:11' -> 1511. Returns 0 if the value is malformed."""
    try:
        minutes, seconds = str(value).split(":")
        return int(minutes) * 60 + int(seconds)
    except (ValueError, TypeError):
        return 0


def grade_for(percentage):
    if percentage >= 90:
        return "A+"
    if percentage >= 75:
        return "A"
    if percentage >= 60:
        return "B"
    if percentage >= 40:
        return "C"
    return "F"


def seconds_left(attempt):
    deadline = attempt.started_at + timedelta(seconds=parse_duration(attempt.exam.duration))
    return int((deadline - timezone.now()).total_seconds())


def exam_state(exam, attempt, question_count):
    """Returns (state, can_start, message) — single source of truth for the Start button."""
    if attempt and attempt.status == "Submitted":
        return "Completed", False, ""
    if attempt and attempt.status == "InProgress":
        return "InProgress", True, ""
    if exam.status == "Cancelled":
        return "Cancelled", False, "This exam has been cancelled."
    if exam.status == "Completed":
        return "Closed", False, "This exam is closed."

    today = timezone.localdate()
    if exam.date > today:
        return "Upcoming", False, f"This exam opens on {exam.date:%d %b %Y}. You can start it only on that day."
    if exam.date < today:
        return "Missed", False, "The exam date has passed."
    if question_count == 0:
        return "Available", False, "No questions have been added for this course yet."
    return "Available", True, ""


def finalize(attempt):
    """Grade the attempt and lock it. Safe to call more than once."""
    if attempt.status == "Submitted":
        return attempt

    questions = Question.objects.in_bulk(attempt.question_ids)
    total = len(questions)
    correct = 0
    for qid, selected in attempt.answers.items():
        question = questions.get(int(qid))
        if question and selected and selected == question.answer:
            correct += 1

    percentage = round(correct * 100 / total) if total else 0
    attempt.total_questions = total
    attempt.correct_count = correct
    attempt.percentage = percentage
    attempt.grade = grade_for(percentage)
    attempt.status = "Submitted"
    attempt.submitted_at = timezone.now()
    attempt.save()

    Exam.objects.filter(id=attempt.exam_id).update(status="Completed")
    return attempt


def result_payload(attempt):
    exam = attempt.exam
    return {
        "attempt_id": attempt.id,
        "exam_id": exam.id,
        "title": exam.title,
        "course": exam.course,
        "date": exam.date,
        "correct_count": attempt.correct_count,
        "total_questions": attempt.total_questions,
        "percentage": attempt.percentage,
        "grade": attempt.grade,
        "submitted_at": attempt.submitted_at,
        "student_id": exam.student_id,
        "student_name": student_name(exam.student),
    }


def attempt_payload(attempt):
    """What the exam screen needs. Note: no `answer` field on questions."""
    questions = Question.objects.in_bulk(attempt.question_ids)
    ordered = []
    for qid in attempt.question_ids:
        q = questions.get(qid)
        if not q:
            continue
        options = list(q.options)
        random.Random(f"{attempt.id}-{q.id}").shuffle(options)   # stable per attempt
        ordered.append({"id": q.id, "question": q.question, "options": options})

    return {
        "finished": False,
        "attempt_id": attempt.id,
        "exam": {"id": attempt.exam_id, "title": attempt.exam.title, "course": attempt.exam.course},
        "duration_seconds": parse_duration(attempt.exam.duration),
        "remaining_seconds": max(seconds_left(attempt), 0),
        "current_index": len(attempt.answers),     # forward-only, so answered count == position
        "questions": ordered,
    }


def get_attempt(request, attempt_id):
    return ExamAttempt.objects.select_related("exam", "exam__student").get(
        id=attempt_id, exam__student=request.user
    )


# ---------------------------------------------------------------------------
# GET /api/v1/student/exams/
# ---------------------------------------------------------------------------
class StudentExamListAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            counts = {
                row["course"]: row["n"]
                for row in Question.objects.values("course").annotate(n=Count("id"))
            }
            exams = (
                Exam.objects.filter(student=request.user)
                .select_related("attempt", "student")
                .order_by("-date", "-id")
            )

            data = []
            for exam in exams:
                attempt = getattr(exam, "attempt", None)
                question_count = counts.get(exam.course, 0)
                state, can_start, message = exam_state(exam, attempt, question_count)

                item = {
                    "id": exam.id,
                    "title": exam.title,
                    "course": exam.course,
                    "date": exam.date,
                    "duration": exam.duration,
                    "duration_seconds": parse_duration(exam.duration),
                    "question_count": question_count,
                    "state": state,
                    "can_start": can_start,
                    "start_message": message,
                    "result": None,
                }
                if attempt and attempt.status == "Submitted":
                    item["question_count"] = attempt.total_questions
                    item["result"] = result_payload(attempt)
                data.append(item)

            return ok(data)
        except Exception as e:
            return fail(str(e))


# ---------------------------------------------------------------------------
# POST /api/v1/student/exams/<exam_id>/start/
# ---------------------------------------------------------------------------
class StudentExamStartAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, exam_id):
        try:
            try:
                exam = Exam.objects.select_related("student").get(id=exam_id, student=request.user)
            except Exam.DoesNotExist:
                return fail("Exam not found", http.HTTP_404_NOT_FOUND)

            attempt = getattr(exam, "attempt", None)

            if attempt and attempt.status == "Submitted":
                return fail("You have already completed this exam.")

            # Resume an attempt that is already running
            if attempt and attempt.status == "InProgress":
                if seconds_left(attempt) <= 0:
                    finalize(attempt)
                    return ok({"finished": True, "result": result_payload(attempt)})
                return ok(attempt_payload(attempt))

            # Fresh start — enforce the date / status / question rules
            pool_ids = list(Question.objects.filter(course=exam.course).values_list("id", flat=True))
            state, can_start, message = exam_state(exam, None, len(pool_ids))
            if not can_start:
                return fail(message or "This exam cannot be started.")
            if parse_duration(exam.duration) <= 0:
                return fail("Exam duration is not set correctly. Please contact your admin.")

            random.shuffle(pool_ids)
            attempt, _ = ExamAttempt.objects.get_or_create(
                exam=exam,
                defaults={"question_ids": pool_ids, "total_questions": len(pool_ids)},
            )
            return ok(attempt_payload(attempt))
        except Exception as e:
            return fail(str(e))


# ---------------------------------------------------------------------------
# POST /api/v1/student/attempts/<attempt_id>/answer/
# body: { "question_id": 14, "selected": "Option text" }   ("" = skipped)
# ---------------------------------------------------------------------------
class StudentAttemptAnswerAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, attempt_id):
        try:
            try:
                attempt = get_attempt(request, attempt_id)
            except ExamAttempt.DoesNotExist:
                return fail("Attempt not found", http.HTTP_404_NOT_FOUND)

            if attempt.status != "InProgress":
                return fail("This exam has already been submitted.")
            if seconds_left(attempt) < -GRACE_SECONDS:
                return fail("Time is up", http.HTTP_410_GONE)   # frontend submits on 410

            try:
                qid = int(request.data.get("question_id"))
            except (TypeError, ValueError):
                return fail("Invalid question")
            if qid not in attempt.question_ids:
                return fail("Invalid question")

            key = str(qid)
            if key in attempt.answers:                 # forward-only: answers can't be changed
                return ok(message="Already answered")

            selected = request.data.get("selected") or ""
            if selected:
                question = Question.objects.filter(id=qid).first()
                if not question or selected not in question.options:
                    return fail("Invalid option")

            attempt.answers[key] = selected
            attempt.save(update_fields=["answers"])
            return ok(message="Saved")
        except Exception as e:
            return fail(str(e))


# ---------------------------------------------------------------------------
# POST /api/v1/student/attempts/<attempt_id>/submit/
# ---------------------------------------------------------------------------
class StudentAttemptSubmitAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, attempt_id):
        try:
            try:
                attempt = get_attempt(request, attempt_id)
            except ExamAttempt.DoesNotExist:
                return fail("Attempt not found", http.HTTP_404_NOT_FOUND)

            finalize(attempt)      # idempotent
            return ok(result_payload(attempt), "Exam submitted")
        except Exception as e:
            return fail(str(e))


# ---------------------------------------------------------------------------
# GET /api/v1/student/marksheet/
# ---------------------------------------------------------------------------
class StudentMarksheetAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            attempts = (
                ExamAttempt.objects.filter(exam__student=request.user, status="Submitted")
                .select_related("exam", "exam__student")
                .order_by("-submitted_at")
            )
            return ok([result_payload(a) for a in attempts])
        except Exception as e:
            return fail(str(e))
# import json
# import os

# from rest_framework.views import APIView
# from rest_framework.response import Response
# from rest_framework import status
# from django.conf import settings
# from openai import OpenAI

# from .models import Studentprofiles

# # =====================================================
# # OPENAI API KEY
# # =====================================================
# # Never hardcode the key in source. Add this to settings.py instead:
# #
# #     OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
# #
# # ...and set the real key as an environment variable on the server
# # (e.g. in your .env file, systemd unit, or hosting provider's
# # environment variable settings) — never commit it to git.


# client = OpenAI(api_key=getattr(settings, "OPENAI_API_KEY", os.environ.get("OPENAI_API_KEY", "")))
# # =====================================================
# # STUDENT PROFILE + LIVE JOB SEARCH API
# # =====================================================

# class StudentProfileAPIView(APIView):

#     # -------------------------------------------------
#     # GET - View all student profiles
#     # GET /api/student-profile/
#     # GET /api/student-profile/?id=1
#     # GET /api/student-profile/?skills=python&location=chennai   (company search)
#     # -------------------------------------------------

#     def get(self, request, id=None):

#         if id:
#             try:
#                 student = Studentprofiles.objects.get(id=id)

#                 return Response({
#                     "status": {
#                         "code": status.HTTP_200_OK,
#                         "response": "success"
#                     },
#                     "data": {
#                         "id": student.id,
#                         "name": student.name,
#                         "email": student.email,
#                         "phone": student.phone,
#                         "skills": student.skills,
#                         "location": student.location,
#                         "resume": (
#                             student.resume.url
#                             if student.resume else None
#                         ),
#                     }
#                 })

#             except Studentprofiles.DoesNotExist:
#                 return Response({
#                     "error": True,
#                     "message": "Student not found"
#                 }, status=404)

#         # ALL STUDENTS — supports company-side search by skill/location
#         students = Studentprofiles.objects.all().order_by("-id")

#         skills_q = request.query_params.get("skills", "").strip()
#         location_q = request.query_params.get("location", "").strip()
#         name_q = request.query_params.get("name", "").strip()

#         if skills_q:
#             students = students.filter(skills__icontains=skills_q)
#         if location_q:
#             students = students.filter(location__icontains=location_q)
#         if name_q:
#             students = students.filter(name__icontains=name_q)

#         data = []
#         for student in students:
#             data.append({
#                 "id": student.id,
#                 "name": student.name,
#                 "email": student.email,
#                 "phone": student.phone,
#                 "skills": student.skills,
#                 "location": student.location,
#                 "resume": (
#                     student.resume.url
#                     if student.resume else None
#                 ),
#             })

#         return Response({
#             "status": {
#                 "code": status.HTTP_200_OK,
#                 "response": "success"
#             },
#             "data": data
#         })

#     # -------------------------------------------------
#     # POST - Save student + Live AI Job Search
#     # POST /api/student-profile/
#     # -------------------------------------------------

#     def post(self, request):
#         data = request.data

#         try:
#             # 1. SAVE STUDENT PROFILE
#             student = Studentprofiles.objects.create(
#                 name=data.get("name"),
#                 email=data.get("email"),
#                 phone=data.get("phone"),
#                 skills=data.get("skills"),
#                 location=data.get("location"),
#                 resume=request.FILES.get("resume"),
#             )

#             # 2. OPENAI LIVE JOB SEARCH
#             prompt = f"""
# You are a job search assistant.

# Search the web for CURRENT job openings suitable for this student.

# Student Details:
# Name: {student.name}
# Skills: {student.skills}
# Preferred Location: {student.location}

# Find real, currently available job openings, prioritizing the student's
# preferred location where possible.

# Search for:
# - Job title
# - Office / Company name
# - Location
# - Required skills
# - Application URL

# IMPORTANT:
# - Search the web for current openings.
# - Do not invent companies or job openings.
# - Return ONLY valid JSON.
# - If you cannot verify an opening, do not include it.

# Return this exact JSON format:

# {{
#   "jobs": [
#     {{
#       "office_name": "Company name",
#       "job_title": "Job title",
#       "location": "City",
#       "required_skills": "Python, Django",
#       "application_url": "https://example.com"
#     }}
#   ]
# }}
# """

#             response = client.responses.create(
#                 model="gpt-5.6-luna",
#                 tools=[{"type": "web_search"}],
#                 input=prompt,
#             )

#             # 3. AI RESPONSE
#             ai_text = response.output_text

#             try:
#                 ai_result = json.loads(ai_text)
#             except json.JSONDecodeError:
#                 ai_result = {"jobs": [], "message": ai_text}

#             # 4. RETURN STUDENT + JOBS
#             return Response({
#                 "status": {
#                     "code": status.HTTP_201_CREATED,
#                     "response": "success"
#                 },
#                 "message": "Student saved and live jobs fetched",
#                 "student": {
#                     "id": student.id,
#                     "name": student.name,
#                     "email": student.email,
#                     "phone": student.phone,
#                     "skills": student.skills,
#                     "location": student.location,
#                 },
#                 "jobs": ai_result.get("jobs", []),
#                 "ai_message": ai_result.get("message", ""),
#             })

#         except Exception as e:
#             return Response({
#                 "status": {
#                     "code": status.HTTP_500_INTERNAL_SERVER_ERROR,
#                     "response": "failed"
#                 },
#                 "error": True,
#                 "message": str(e),
#             }, status=500)

#     # -------------------------------------------------
#     # PUT - Update student
#     # PUT /api/student-profile/1/
#     # -------------------------------------------------

#     def put(self, request, id):
#         try:
#             student = Studentprofiles.objects.get(id=id)
#             data = request.data

#             student.name = data.get("name", student.name)
#             student.email = data.get("email", student.email)
#             student.phone = data.get("phone", student.phone)
#             student.skills = data.get("skills", student.skills)
#             student.location = data.get("location", student.location)

#             if request.FILES.get("resume"):
#                 student.resume = request.FILES.get("resume")

#             student.save()

#             return Response({
#                 "status": {
#                     "code": status.HTTP_200_OK,
#                     "response": "success"
#                 },
#                 "message": "Student updated successfully"
#             })

#         except Studentprofiles.DoesNotExist:
#             return Response({
#                 "error": True,
#                 "message": "Student not found"
#             }, status=404)

#     # -------------------------------------------------
#     # DELETE - Delete student
#     # DELETE /api/student-profile/1/
#     # -------------------------------------------------

#     def delete(self, request, id):
#         try:
#             student = Studentprofiles.objects.get(id=id)
#             student.delete()

#             return Response({
#                 "status": {
#                     "code": status.HTTP_200_OK,
#                     "response": "success"
#                 },
#                 "message": "Student deleted successfully"
#             })

#         except Studentprofiles.DoesNotExist:
#             return Response({
#                 "error": True,
#                 "message": "Student not found"
#             }, status=404)

    


from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .models import Studentprofiles

# =====================================================
# STUDENT PROFILE API (No external job search — just CRUD)
# =====================================================

class StudentProfileAPIView(APIView):

    # -------------------------------------------------
    # GET - View all student profiles
    # GET /api/student-profile/
    # GET /api/student-profile/?id=1
    # GET /api/student-profile/?skills=python&location=chennai
    # -------------------------------------------------

    def get(self, request, id=None):

        if id:
            try:
                student = Studentprofiles.objects.get(id=id)

                return Response({
                    "status": {
                        "code": status.HTTP_200_OK,
                        "response": "success"
                    },
                    "data": {
                        "id": student.id,
                        "name": student.name,
                        "email": student.email,
                        "phone": student.phone,
                        "skills": student.skills,
                        "education": student.education,
                        "experience": student.experience,
                        "location": student.location,
                        "resume": (
                            student.resume.url
                            if student.resume else None
                        ),
                    }
                })

            except Studentprofiles.DoesNotExist:
                return Response({
                    "error": True,
                    "message": "Student not found"
                }, status=404)

        # ALL STUDENTS — supports company-side search by skill/location
        students = Studentprofiles.objects.all().order_by("-id")

        skills_q = request.query_params.get("skills", "").strip()
        location_q = request.query_params.get("location", "").strip()
        name_q = request.query_params.get("name", "").strip()

        if skills_q:
            students = students.filter(skills__icontains=skills_q)
        if location_q:
            students = students.filter(location__icontains=location_q)
        if name_q:
            students = students.filter(name__icontains=name_q)

        data = []
        for student in students:
            data.append({
                "id": student.id,
                "name": student.name,
                "email": student.email,
                "phone": student.phone,
                "skills": student.skills,
                "education": student.education,
                "experience": student.experience,
                "location": student.location,
                "resume": (
                    student.resume.url
                    if student.resume else None
                ),
            })

        return Response({
            "status": {
                "code": status.HTTP_200_OK,
                "response": "success"
            },
            "data": data
        })

    # -------------------------------------------------
    # POST - Save student profile only
    # POST /api/student-profile/
    # -------------------------------------------------

    def post(self, request):
        data = request.data

        try:
            student = Studentprofiles.objects.create(
                name=data.get("name"),
                email=data.get("email"),
                phone=data.get("phone"),
                skills=data.get("skills"),
                education=data.get("education"),
                experience=data.get("experience"),
                location=data.get("location"),
                resume=request.FILES.get("resume"),
            )

            return Response({
                "status": {
                    "code": status.HTTP_201_CREATED,
                    "response": "success"
                },
                "message": "Student saved successfully",
                "student": {
                    "id": student.id,
                    "name": student.name,
                    "email": student.email,
                    "phone": student.phone,
                    "skills": student.skills,
                    "education": student.education,
                    "experience": student.experience,
                    "location": student.location,
                },
                # Frontend just shows a "searching..." state using this
                "jobs": [],
                "ai_message": "Job searching in progress. We'll notify you once matching openings are found.",
            })

        except Exception as e:
            return Response({
                "status": {
                    "code": status.HTTP_500_INTERNAL_SERVER_ERROR,
                    "response": "failed"
                },
                "error": True,
                "message": str(e),
            }, status=500)

    # -------------------------------------------------
    # PUT - Update student
    # PUT /api/student-profile/1/
    # -------------------------------------------------

    def put(self, request, id):
        try:
            student = Studentprofiles.objects.get(id=id)
            data = request.data

            student.name = data.get("name", student.name)
            student.email = data.get("email", student.email)
            student.phone = data.get("phone", student.phone)
            student.skills = data.get("skills", student.skills)
            student.education = data.get("education", student.education)
            student.experience = data.get("experience", student.experience)
            student.location = data.get("location", student.location)

            if request.FILES.get("resume"):
                student.resume = request.FILES.get("resume")

            student.save()

            return Response({
                "status": {
                    "code": status.HTTP_200_OK,
                    "response": "success"
                },
                "message": "Student updated successfully"
            })

        except Studentprofiles.DoesNotExist:
            return Response({
                "error": True,
                "message": "Student not found"
            }, status=404)

    # -------------------------------------------------
    # DELETE - Delete student
    # DELETE /api/student-profile/1/
    # -------------------------------------------------

    def delete(self, request, id):
        try:
            student = Studentprofiles.objects.get(id=id)
            student.delete()

            return Response({
                "status": {
                    "code": status.HTTP_200_OK,
                    "response": "success"
                },
                "message": "Student deleted successfully"
            })

        except Studentprofiles.DoesNotExist:
            return Response({
                "error": True,
                "message": "Student not found"
            }, status=404)