from django.shortcuts import render, get_object_or_404, redirect
from django.db.models import Sum, Count, Avg, Q
from django.db import transaction
from django.core.files.storage import default_storage
from django.contrib import messages
from .models import Firma, Fatura, FaturaKalemi
from .forms import FirmaForm, FaturaForm
from .utils import extract_text_from_pdf, analyze_invoice_text
import os

def home(request):
    """Fatura Yönetimi Gösterge Paneli."""
    toplam_firma = Firma.objects.count()
    toplam_fatura = Fatura.objects.count()
    toplam_harcama = Fatura.objects.aggregate(Sum('genel_toplam'))['genel_toplam__sum'] or 0
    son_faturalar = Fatura.objects.select_related('firma').all().order_by('-olusturulma_tarihi')[:10]

    context = {
        "toplam_firma": toplam_firma,
        "toplam_fatura": toplam_fatura,
        "toplam_harcama": toplam_harcama,
        "son_faturalar": son_faturalar,
        "active_menu": "dashboard"
    }
    return render(request, "core/index.html", context)

def fatura_arsivi(request):
    """Firmalara göre gruplanmış fatura arşivi."""
    firmalar = Firma.objects.annotate(
        fatura_sayisi=Count('faturalar'),
        toplam_tutar=Sum('faturalar__genel_toplam')
    ).order_by('ad')
    
    context = {
        "firmalar": firmalar,
        "active_menu": "archive"
    }
    return render(request, "core/fatura_arsivi.html", context)

def firma_detay(request, pk):
    """Belirli bir firmanın fatura listesi."""
    firma = get_object_or_404(Firma, pk=pk)
    faturalar = firma.faturalar.all().order_by('-tarih')
    
    context = {
        "firma": firma,
        "faturalar": faturalar,
        "active_menu": "archive"
    }
    return render(request, "core/firma_detay.html", context)

def fatura_detay(request, pk):
    """Fatura detay önizleme ve kalemleri."""
    fatura = get_object_or_404(Fatura.objects.select_related('firma'), pk=pk)
    kalemler = fatura.kalemler.all()
    
    context = {
        "fatura": fatura,
        "kalemler": kalemler,
        "active_menu": "archive"
    }
    return render(request, "core/fatura_detay.html", context)

def raporlar(request):
    """İstatistik ve Raporlar."""
    # Aylık harcama trendi
    aylik_harcama = Fatura.objects.values('tarih__month').annotate(
        toplam=Sum('genel_toplam'),
        adet=Count('id')
    ).order_by('tarih__month')
    
    # KDV dağılımı
    kdv_ozet = Fatura.objects.aggregate(
        toplam_kdv=Sum('kdv_toplam'),
        ortalama_kdv=Avg('kdv_toplam')
    )
    
    context = {
        "aylik_harcama": aylik_harcama,
        "kdv_ozet": kdv_ozet,
        "active_menu": "reports"
    }
    return render(request, "core/raporlar.html", context)

def firma_ekle(request):
    if request.method == 'POST':
        form = FirmaForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('fatura_arsivi')
    else:
        form = FirmaForm()
    return render(request, 'core/firma_form.html', {'form': form, 'title': 'Yeni Firma Ekle'})

def fatura_ekle(request):
    firma_id = request.GET.get('firma')
    initial = {}
    if firma_id:
        initial['firma'] = firma_id
        
    if request.method == 'POST':
        form = FaturaForm(request.POST, request.FILES)
        if form.is_valid():
            fatura = form.save()
            return redirect('fatura_detay', pk=fatura.pk)
    else:
        form = FaturaForm(initial=initial)
    return render(request, 'core/fatura_form.html', {'form': form, 'title': 'Yeni Fatura Yükle'})

def fatura_otomatik_yukle(request):
    if request.method == 'POST' and request.FILES.get('pdf_dosyasi'):
        pdf_file = request.FILES['pdf_dosyasi']
        
        # Save temporary file to extract text
        temp_name = 'temp_' + pdf_file.name
        path = default_storage.save('temp/' + temp_name, pdf_file)
        full_path = default_storage.path(path)
        
        try:
            text = extract_text_from_pdf(full_path)
            if not text:
                messages.error(request, "PDF dosyasından metin okunamadı. Dosya taranmış bir resim olabilir veya şifreli olabilir.")
            else:
                data = analyze_invoice_text(text)
                if not data:
                    messages.error(request, "Yapay zeka faturayı analiz edemedi. Lütfen dosyanın geçerli bir fatura olduğundan emin olun.")
                else:
                    with transaction.atomic():
                        # Smarter Firma matching
                        vergi_no = str(data.get('vergi_no', '')).strip()
                        mersis_no = str(data.get('mersis_no', '')).strip()
                        firma_adi = data.get('firma_adi', '').strip() or 'Bilinmeyen Firma'
                        
                        firma = None
                        
                        # 1. Try by Vergi No / TCKN
                        if vergi_no and vergi_no != 'None' and vergi_no != 'null':
                            firma = Firma.objects.filter(vergi_no=vergi_no).first()
                        
                        # 2. Try by Mersis No
                        if not firma and mersis_no and mersis_no != 'None' and mersis_no != 'null':
                            firma = Firma.objects.filter(mersis_no=mersis_no).first()
                            
                        # 3. Try by Name (Exact)
                        if not firma and firma_adi != 'Bilinmeyen Firma':
                            firma = Firma.objects.filter(ad__iexact=firma_adi).first()
                            
                        # 4. Create if not found
                        if not firma:
                            # Ensure we have a unique vergi_no even if AI failed
                            if not vergi_no or vergi_no == 'None' or vergi_no == 'null':
                                vergi_no = f"AUTO-{os.urandom(4).hex()}"
                            
                            firma = Firma.objects.create(
                                ad=firma_adi,
                                vergi_no=vergi_no,
                                mersis_no=mersis_no if (mersis_no != 'None' and mersis_no != 'null') else None,
                                adres=data.get('adres', '')
                            )
                        else:
                            # Update missing info if found existing firma
                            updated = False
                            if not firma.mersis_no and mersis_no and mersis_no != 'None' and mersis_no != 'null':
                                firma.mersis_no = mersis_no
                                updated = True
                            if not firma.adres and data.get('adres'):
                                firma.adres = data.get('adres')
                                updated = True
                            if updated:
                                firma.save()

                        # Create Fatura
                        fatura_no = data.get('fatura_no') or f"AUTO-{os.urandom(4).hex()}"
                        
                        # Check if this invoice already exists for this firm
                        fatura = Fatura.objects.filter(fatura_no=fatura_no, firma=firma).first()
                        if not fatura:
                            fatura = Fatura.objects.create(
                                firma=firma,
                                fatura_no=fatura_no,
                                tarih=data.get('tarih') or '2026-01-01',
                                ara_toplam=data.get('ara_toplam') or 0,
                                kdv_toplam=data.get('kdv_toplam') or 0,
                                genel_toplam=data.get('genel_toplam') or 0,
                                pdf_dosyasi=pdf_file,
                                islenmis=True
                            )
                            
                            # Add Items
                            kalemler = data.get('kalemler', [])
                            if isinstance(kalemler, list):
                                for k in kalemler:
                                    FaturaKalemi.objects.create(
                                        fatura=fatura,
                                        urun_adi=k.get('urun_adi') or 'Ürün',
                                        adet=k.get('adet') or 1,
                                        birim_fiyat=k.get('birim_fiyat') or 0,
                                        kdv_orani=k.get('kdv_orani') or 20,
                                        kdv_tutari=k.get('kdv_tutari') or 0,
                                        toplam_tutar=k.get('toplam_tutar') or 0
                                    )
                        
                        # Clean up temp file
                        if default_storage.exists(path):
                            default_storage.delete(path)
                        
                        messages.success(request, f"Fatura başarıyla analiz edildi ve {firma.ad} firmasına eklendi.")
                        return redirect('fatura_detay', pk=fatura.pk)
        except Exception as e:
            messages.error(request, f"Fatura işlenirken bir hata oluştu: {str(e)}")
            print(f"Error processing automatic invoice: {e}")
        finally:
            # Clean up temp file
            if default_storage.exists(path):
                default_storage.delete(path)
        
    return render(request, 'core/fatura_form_otomatik.html', {'title': 'Otomatik Fatura Yükle', 'active_menu': 'dashboard'})

def search(request):
    query = request.GET.get('q', '')
    faturalar = []
    firmalar = []
    if query:
        faturalar = Fatura.objects.filter(
            Q(fatura_no__icontains=query) | 
            Q(firma__ad__icontains=query)
        ).select_related('firma')
        firmalar = Firma.objects.filter(
            Q(ad__icontains=query) | 
            Q(vergi_no__icontains=query)
        )
    
    context = {
        'query': query,
        'faturalar': faturalar,
        'firmalar': firmalar,
    }
    return render(request, 'core/search_results.html', context)

def firma_sil(request, pk):
    firma = get_object_or_404(Firma, pk=pk)
    if request.method == 'POST':
        firma.delete()
        return redirect('fatura_arsivi')
    return render(request, 'core/confirm_delete.html', {'object': firma, 'type': 'Firma'})

def fatura_sil(request, pk):
    fatura = get_object_or_404(Fatura, pk=pk)
    firma_pk = fatura.firma.pk
    if request.method == 'POST':
        fatura.delete()
        return redirect('firma_detay', pk=firma_pk)
    return render(request, 'core/confirm_delete.html', {'object': fatura, 'type': 'Fatura'})
