﻿import smtplib
from urllib.parse import quote_plus

from django.conf import settings
from django.contrib.auth import authenticate, get_user_model, login, logout
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.core.mail import EmailMultiAlternatives
from django.core.mail import BadHeaderError
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.templatetags.static import static

from .models import ContactMessage, SiteSettings, TeamMember


def _branded_email(
    *,
    subject: str,
    text_body: str,
    recipient: str,
    reply_to: str,
    eyebrow: str,
    title: str,
    intro: str,
    content: str,
) -> EmailMultiAlternatives:
    safe_eyebrow = conditional_escape(eyebrow)
    safe_title = conditional_escape(title)
    safe_intro = conditional_escape(intro)
    html_body = mark_safe(
        f'''<!doctype html>
<html lang="en">
  <body style="margin:0;background:#f4f7fb;color:#182238;font-family:Arial,Helvetica,sans-serif;">
    <div style="padding:36px 16px;">
      <div style="max-width:640px;margin:0 auto;background:#ffffff;border:1px solid #e5eaf2;border-radius:20px;overflow:hidden;box-shadow:0 12px 35px rgba(25,40,70,.10);">
        <div style="padding:30px 34px;background:linear-gradient(135deg,#101a36 0%,#28356d 62%,#5b62d9 100%);">
          <div style="font-size:13px;letter-spacing:2px;text-transform:uppercase;color:#aebcff;font-weight:700;">VAYCANCY</div>
          <div style="margin-top:22px;font-size:12px;letter-spacing:1.5px;text-transform:uppercase;color:#b8c7ff;">{safe_eyebrow}</div>
          <h1 style="margin:8px 0 0;color:#ffffff;font-size:28px;line-height:1.2;font-weight:700;">{safe_title}</h1>
        </div>
        <div style="padding:32px 34px;">
          <p style="margin:0 0 24px;color:#536078;font-size:16px;line-height:1.65;">{safe_intro}</p>
          {content}
        </div>
        <div style="padding:20px 34px;background:#f8faff;border-top:1px solid #e8edf5;color:#718096;font-size:12px;line-height:1.6;">
          <strong style="color:#28356d;">Vaycancy</strong> · Anything is listable.<br>
          This notification was sent from your Vaycancy workspace.
        </div>
      </div>
    </div>
  </body>
</html>'''
    )
    message = EmailMultiAlternatives(
        subject=subject,
        body=text_body,
        from_email=settings.DEFAULT_FROM_EMAIL,
        to=[recipient],
        reply_to=[reply_to],
    )
    message.attach_alternative(html_body, 'text/html')
    return message


def vayadmin_required(view):
    def wrapped(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect(f'/vayadmin/login/?next={request.path}')
        if not request.user.is_staff:
            logout(request)
            messages.error(request, 'You do not have access to the Vaycancy workspace.')
            return redirect('vayadmin-login')
        return view(request, *args, **kwargs)
    return wrapped


def home(request: HttpRequest) -> HttpResponse:
    return render(request, 'index.html')


def favicon(request: HttpRequest) -> HttpResponse:
    """Use the brand mark even when a browser requests /favicon.ico directly."""
    return redirect(static('img/vaylogo.png'))


def robots_txt(request: HttpRequest) -> HttpResponse:
    """Give crawlers a clear public-site boundary and sitemap location."""
    site_url = settings.SITE_URL or request.build_absolute_uri('/').rstrip('/')
    content = (
        'User-agent: *\n'
        'Allow: /\n'
        'Disallow: /vayadmin/\n'
        'Disallow: /workspace/\n'
        'Disallow: /accounts/\n\n'
        f'Sitemap: {site_url}/sitemap.xml\n'
    )
    return HttpResponse(content, content_type='text/plain')


def sitemap_xml(request: HttpRequest) -> HttpResponse:
    """A small, explicit sitemap for the public marketing pages."""
    site_url = settings.SITE_URL or request.build_absolute_uri('/').rstrip('/')
    pages = ('/', '/about/', '/team/', '/contact/')
    urls = ''.join(f'<url><loc>{site_url}{path}</loc></url>' for path in pages)
    content = (
        '<?xml version="1.0" encoding="UTF-8"?>'
        '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
        f'{urls}</urlset>'
    )
    return HttpResponse(content, content_type='application/xml')


def about(request: HttpRequest) -> HttpResponse:
    return render(request, 'about.html', {'team_members': TeamMember.objects.filter(is_published=True)})


def team(request: HttpRequest) -> HttpResponse:
    return render(request, 'team.html', {'team_members': TeamMember.objects.filter(is_published=True)})


def contact(request: HttpRequest) -> HttpResponse:
    return render(request, 'contact.html')


def send_contact(request: HttpRequest) -> HttpResponse:
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
    if request.method != 'POST':
        if is_ajax:
            return JsonResponse({'ok': False, 'message': 'This form only accepts POST requests.'}, status=405)
        return redirect('contact')
    required_fields = ('name', 'email', 'subject', 'message')
    if any(not request.POST.get(field, '').strip() for field in required_fields):
        if is_ajax:
            return JsonResponse({'ok': False, 'message': 'Please complete all contact fields.'}, status=400)
        messages.error(request, 'Please complete all contact fields.')
    else:
        try:
            validate_email(request.POST['email'].strip())
        except ValidationError:
            if is_ajax:
                return JsonResponse({'ok': False, 'message': 'Please enter a valid email address.'}, status=400)
            messages.error(request, 'Please enter a valid email address.')
        else:
            contact_message = ContactMessage.objects.create(
                name=request.POST['name'].strip(),
                email=request.POST['email'].strip(),
                subject=request.POST['subject'].strip(),
                message=request.POST['message'].strip(),
            )
            try:
                recipient = SiteSettings.current().notification_email
                safe_name = conditional_escape(contact_message.name)
                safe_email = conditional_escape(contact_message.email)
                safe_message = conditional_escape(contact_message.message).replace('\n', '<br>')
                _branded_email(
                    subject=f'Vaycancy contact: {contact_message.subject}',
                    text_body=(
                        f'Name: {contact_message.name}\n'
                        f'Email: {contact_message.email}\n\n'
                        f'{contact_message.message}'
                    ),
                    recipient=recipient,
                    reply_to=contact_message.email,
                    eyebrow='New contact message',
                    title=contact_message.subject,
                    intro=f'{contact_message.name} sent a new message through the Vaycancy website.',
                    content=f'''<div style="padding:20px;background:#f8faff;border:1px solid #e5eaf2;border-radius:14px;">
                      <div style="margin-bottom:14px;color:#718096;font-size:12px;text-transform:uppercase;letter-spacing:1px;">From</div>
                      <div style="color:#182238;font-size:16px;font-weight:700;">{safe_name}</div>
                      <a href="mailto:{safe_email}" style="display:inline-block;margin-top:5px;color:#4e5ed5;font-size:14px;text-decoration:none;">{safe_email}</a>
                    </div>
                    <div style="margin-top:18px;padding:22px;background:#ffffff;border:1px solid #e5eaf2;border-radius:14px;color:#35425c;font-size:15px;line-height:1.7;">
                      {safe_message}
                    </div>''',
                ).send(fail_silently=False)
            except (BadHeaderError, OSError, ValueError, smtplib.SMTPException):
                if is_ajax:
                    return JsonResponse({
                        'ok': True,
                        'message': 'Your message was saved, but email delivery is temporarily unavailable.',
                    })
                messages.warning(
                    request,
                    'Your message was saved, but email delivery is temporarily unavailable.',
                )
            else:
                if is_ajax:
                    return JsonResponse({'ok': True, 'message': 'Your message has been sent. Thank you!'})
                messages.success(request, 'Your message has been sent. Thank you!')
    if is_ajax:
        return JsonResponse({'ok': False, 'message': 'Please check the form and try again.'}, status=400)
    return redirect('contact')


def subscribe(request: HttpRequest) -> HttpResponse:
    if request.method != 'POST':
        return redirect('home')
    email = request.POST.get('email', '').strip()
    try:
        validate_email(email)
    except ValidationError:
        messages.error(request, 'Please enter a valid email address.')
    else:
        try:
            recipient = SiteSettings.current().notification_email
            safe_email = conditional_escape(email)
            _branded_email(
                subject='New Vaycancy early-list signup',
                text_body=f'A visitor joined the Vaycancy early list with email: {email}',
                recipient=recipient,
                reply_to=email,
                eyebrow='Early-list signup',
                title='A new person is interested',
                intro='Someone has joined the Vaycancy early list and is ready to hear what comes next.',
                content=f'''<div style="padding:22px;background:#f8faff;border:1px solid #e5eaf2;border-radius:14px;">
                  <div style="color:#718096;font-size:12px;text-transform:uppercase;letter-spacing:1px;">Email address</div>
                  <a href="mailto:{safe_email}" style="display:block;margin-top:8px;color:#4e5ed5;font-size:20px;font-weight:700;text-decoration:none;">{safe_email}</a>
                </div>''',
            ).send(fail_silently=False)
        except (BadHeaderError, OSError, smtplib.SMTPException):
            messages.warning(request, 'Your signup was saved, but notification email is temporarily unavailable.')
        else:
            messages.success(request, 'Your subscription request has been sent. Thank you!')
    return redirect('home')


def join(request: HttpRequest) -> HttpResponse:
    if request.method == 'POST':
        email = request.POST.get('email', '').strip().lower()
        password = request.POST.get('password', '')
        password_confirm = request.POST.get('password_confirm', '')
        if not email or not password or not password_confirm:
            messages.error(request, 'Please complete every field.')
        elif password != password_confirm:
            messages.error(request, 'Your passwords do not match.')
        else:
            try:
                validate_email(email)
            except ValidationError:
                messages.error(request, 'Please enter a valid email address.')
            else:
                if get_user_model().objects.filter(username=email).exists():
                    messages.error(request, 'That email is already on the early list.')
                else:
                    user = get_user_model().objects.create_user(
                        username=email,
                        email=email,
                        password=password,
                    )
                    try:
                        recipient = SiteSettings.current().notification_email
                        safe_email = conditional_escape(email)
                        _branded_email(
                            subject='New Vaycancy early-list account',
                            text_body=f'{email} created an early-access account on Vaycancy.',
                            recipient=recipient,
                            reply_to=email,
                            eyebrow='New account',
                            title='Someone joined Vaycancy',
                            intro='A new visitor created an early-access account on the platform.',
                            content=f'''<div style="padding:22px;background:#f8faff;border:1px solid #e5eaf2;border-radius:14px;">
                              <div style="color:#718096;font-size:12px;text-transform:uppercase;letter-spacing:1px;">Account email</div>
                              <a href="mailto:{safe_email}" style="display:block;margin-top:8px;color:#4e5ed5;font-size:20px;font-weight:700;text-decoration:none;">{safe_email}</a>
                            </div>''',
                        ).send(fail_silently=False)
                    except (BadHeaderError, OSError, smtplib.SMTPException):
                        messages.warning(request, 'Your account was created, but notification email is temporarily unavailable.')
                    login(request, user)
                    messages.success(request, 'You are on the Vaycancy early list.')
                    return redirect('home')
    return render(request, 'signup.html')


def logout_view(request: HttpRequest) -> HttpResponse:
    logout(request)
    return redirect('home')


def vayadmin_login(request: HttpRequest) -> HttpResponse:
    if request.user.is_authenticated and request.user.is_staff:
        return redirect('vayadmin')
    if request.method == 'POST':
        email = request.POST.get('email', '').strip().lower()
        password = request.POST.get('password', '')
        user = authenticate(request, username=email, password=password)
        if user is not None and user.is_staff:
            login(request, user)
            request.session.set_expiry(settings.VAYADMIN_SESSION_AGE)
            return redirect(request.GET.get('next') or 'vayadmin')
        messages.error(request, 'Those workspace credentials were not recognised.')
    return render(request, 'vayadmin.html', {'login_mode': True})


@vayadmin_required
def workspace(request: HttpRequest) -> HttpResponse:
    return render(request, 'vayadmin.html', {
        'team_members': TeamMember.objects.all(),
        'contact_messages': ContactMessage.objects.all(),
        'site_settings': SiteSettings.current(),
    })


@vayadmin_required
def site_settings_update(request: HttpRequest) -> HttpResponse:
    site = SiteSettings.current()
    if request.method == 'POST':
        site.notification_email = request.POST.get('notification_email', '').strip()
        site.public_email = request.POST.get('public_email', '').strip()
        site.company_address = request.POST.get('company_address', '').strip()
        site.map_url = f'https://www.google.com/maps/search/?api=1&query={quote_plus(site.company_address)}'
        site.map_embed_url = f'https://www.google.com/maps?q={quote_plus(site.company_address)}&output=embed'
        for field in ('facebook_url', 'instagram_url', 'linkedin_url', 'twitter_url', 'tiktok_url'):
            setattr(site, field, request.POST.get(field, '').strip())
        try:
            validate_email(site.notification_email)
            validate_email(site.public_email)
            site.full_clean()
            site.save()
        except ValidationError:
            messages.error(request, 'Please enter valid email addresses and complete all settings fields.')
        else:
            messages.success(request, 'Site settings updated everywhere.')
    return redirect('vayadmin')


@vayadmin_required
def team_create(request: HttpRequest) -> HttpResponse:
    if request.method == 'POST':
        TeamMember.objects.create(
            name=request.POST.get('name', '').strip(),
            role=request.POST.get('role', '').strip(),
            bio=request.POST.get('bio', '').strip(),
            sort_order=int(request.POST.get('sort_order', 0) or 0),
            is_published=request.POST.get('is_published') == 'on',
            image=request.FILES.get('image'),
            tiktok_url=request.POST.get('tiktok_url', '').strip(),
            instagram_url=request.POST.get('instagram_url', '').strip(),
            twitter_url=request.POST.get('twitter_url', '').strip(),
            linkedin_url=request.POST.get('linkedin_url', '').strip(),
            email=request.POST.get('email', '').strip(),
        )
        messages.success(request, 'Team member created.')
    return redirect('workspace')


@vayadmin_required
def team_edit(request: HttpRequest, member_id: int) -> HttpResponse:
    member = get_object_or_404(TeamMember, pk=member_id)
    if request.method == 'POST':
        member.name = request.POST.get('name', '').strip()
        member.role = request.POST.get('role', '').strip()
        member.bio = request.POST.get('bio', '').strip()
        member.sort_order = int(request.POST.get('sort_order', 0) or 0)
        member.is_published = request.POST.get('is_published') == 'on'
        if request.FILES.get('image'):
            member.image = request.FILES['image']
        member.tiktok_url = request.POST.get('tiktok_url', '').strip()
        member.instagram_url = request.POST.get('instagram_url', '').strip()
        member.twitter_url = request.POST.get('twitter_url', '').strip()
        member.linkedin_url = request.POST.get('linkedin_url', '').strip()
        member.email = request.POST.get('email', '').strip()
        member.save()
        messages.success(request, 'Team member updated.')
    return redirect('workspace')


@vayadmin_required
def team_delete(request: HttpRequest, member_id: int) -> HttpResponse:
    if request.method == 'POST':
        get_object_or_404(TeamMember, pk=member_id).delete()
        messages.success(request, 'Team member deleted.')
    return redirect('workspace')


@vayadmin_required
def message_read(request: HttpRequest, message_id: int) -> HttpResponse:
    if request.method == 'POST':
        message = get_object_or_404(ContactMessage, pk=message_id)
        message.is_read = True
        message.save(update_fields=('is_read',))
    return redirect('workspace')
