from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from .forms import SignUpForm, CompanyForm, TenderForm, BidForm, DocumentForm, NoteForm, ApprovalForm
from .models import Company, Membership, Tender, Bid, Document, Note, Approval
from .decorators import group_required

def home(request):
    return render(request, "core/index.html")

@login_required
def dashboard(request):
    memberships = Membership.objects.filter(user=request.user)
    companies = [m.company for m in memberships]
    context = {
        'companies': companies
    }
    return render(request, "core/dashboard.html", context)

def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect('dashboard')
    else:
        form = SignUpForm()
    return render(request, 'core/signup.html', {'form': form})

def logout_view(request):
    logout(request)
    return redirect('home')

@login_required
def create_company(request):
    if request.method == 'POST':
        form = CompanyForm(request.POST)
        if form.is_valid():
            company = form.save()
            Membership.objects.create(user=request.user, company=company, role='owner')
            return redirect('dashboard')
    else:
        form = CompanyForm()
    return render(request, 'core/create_company.html', {'form': form})

@login_required
def tender_list(request, company_id):
    company = get_object_or_404(Company, pk=company_id)
    tenders = Tender.objects.filter(company=company)
    context = {
        'company': company,
        'tenders': tenders
    }
    return render(request, 'core/tender_list.html', context)

@login_required
def tender_detail(request, tender_id):
    tender = get_object_or_404(Tender, pk=tender_id)
    bids = Bid.objects.filter(tender=tender)
    documents = Document.objects.filter(tender=tender)
    notes = Note.objects.filter(tender=tender)

    if request.method == 'POST':
        if 'submit_document' in request.POST:
            doc_form = DocumentForm(request.POST, request.FILES)
            if doc_form.is_valid():
                document = doc_form.save(commit=False)
                document.tender = tender
                document.uploaded_by = request.user
                document.save()
                return redirect('tender_detail', tender_id=tender.id)
        elif 'submit_note' in request.POST:
            note_form = NoteForm(request.POST)
            if note_form.is_valid():
                note = note_form.save(commit=False)
                note.tender = tender
                note.user = request.user
                note.save()
                return redirect('tender_detail', tender_id=tender.id)

    doc_form = DocumentForm()
    note_form = NoteForm()

    # Workflow logic
    current_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == tender.status][0]
    next_status = Tender.STATUS_CHOICES[current_status_index + 1] if current_status_index + 1 < len(Tender.STATUS_CHOICES) else None


    context = {
        'tender': tender,
        'bids': bids,
        'documents': documents,
        'notes': notes,
        'doc_form': doc_form,
        'note_form': note_form,
        'next_status': next_status,
    }
    return render(request, 'core/tender_detail.html', context)

@login_required
@group_required(['Head of Bids', 'Bid Administrator'])
def update_tender_status(request, tender_id, next_status):
    tender = get_object_or_404(Tender, pk=tender_id)
    
    # Find the index of the current status
    current_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == tender.status][0]
    
    # Find the index of the next status
    next_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == next_status][0]

    # Check if the next status is valid
    if next_status_index == current_status_index + 1:
        tender.status = next_status
        tender.save()

    return redirect('tender_detail', tender_id=tender.id)


@login_required
def create_tender(request, company_id):
    company = get_object_or_404(Company, pk=company_id)
    if request.method == 'POST':
        form = TenderForm(request.POST)
        if form.is_valid():
            tender = form.save(commit=False)
            tender.company = company
            tender.save()
            return redirect('tender_list', company_id=company.id)
    else:
        form = TenderForm()
    context = {
        'form': form,
        'company': company
    }
    return render(request, 'core/create_tender.html', context)

@login_required
def update_tender(request, tender_id):
    tender = get_object_or_404(Tender, pk=tender_id)
    if request.method == 'POST':
        form = TenderForm(request.POST, instance=tender)
        if form.is_valid():
            form.save()
            return redirect('tender_detail', tender_id=tender.id)
    else:
        form = TenderForm(instance=tender)
    context = {
        'form': form,
        'tender': tender
    }
    return render(request, 'core/update_tender.html', context)

@login_required
def delete_tender(request, tender_id):
    tender = get_object_or_404(Tender, pk=tender_id)
    if request.method == 'POST':
        company_id = tender.company.id
        tender.delete()
        return redirect('tender_list', company_id=company_id)
    context = {
        'tender': tender
    }
    return render(request, 'core/delete_tender.html', context)

@login_required
def create_bid(request, tender_id):
    tender = get_object_or_404(Tender, pk=tender_id)
    membership = Membership.objects.filter(user=request.user).first()
    if not membership:
        # Handle case where user has no company
        return redirect('dashboard') # Or show an error
    
    company = membership.company

    if request.method == 'POST':
        form = BidForm(request.POST)
        if form.is_valid():
            bid = form.save(commit=False)
            bid.tender = tender
            bid.company = company
            bid.save()
            return redirect('tender_detail', tender_id=tender.id)
    else:
        form = BidForm()
    
    context = {
        'form': form,
        'tender': tender
    }
    return render(request, 'core/create_bid.html', context)

@login_required
def update_bid(request, bid_id):
    bid = get_object_or_404(Bid, pk=bid_id)
    if request.method == 'POST':
        form = BidForm(request.POST, instance=bid)
        if form.is_valid():
            form.save()
            return redirect('tender_detail', tender_id=bid.tender.id)
    else:
        form = BidForm(instance=bid)
    context = {
        'form': form,
        'bid': bid
    }
    return render(request, 'core/update_bid.html', context)

@login_required
def delete_bid(request, bid_id):
    bid = get_object_or_404(Bid, pk=bid_id)
    if request.method == 'POST':
        tender_id = bid.tender.id
        bid.delete()
        return redirect('tender_detail', tender_id=tender_id)
    context = {
        'bid': bid
    }
    return render(request, 'core/delete_bid.html', context)

@login_required
def approve_bid(request, bid_id):
    bid = get_object_or_404(Bid, pk=bid_id)
    approval, created = Approval.objects.get_or_create(bid=bid, approver=request.user)

    if request.method == 'POST':
        form = ApprovalForm(request.POST, instance=approval)
        if form.is_valid():
            form.save()
            return redirect('tender_detail', tender_id=bid.tender.id)
    else:
        form = ApprovalForm(instance=approval)

    context = {
        'form': form,
        'bid': bid
    }
    return render(request, 'core/approve_bid.html', context)

@login_required
def delete_document(request, document_id):
    document = get_object_or_404(Document, pk=document_id)
    if request.method == 'POST':
        tender_id = document.tender.id
        document.delete()
        return redirect('tender_detail', tender_id=tender_id)
    context = {
        'document': document
    }
    return render(request, 'core/delete_document.html', context)

