import os
import csv
import logging
from datetime import datetime
from functools import wraps
from flask import Flask, render_template, request, redirect, url_for, jsonify, session, flash
from dotenv import load_dotenv
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

from models import db, Product, Order, Coupon
from paddle_webhook import PaddleWebhook
from utils.file_delivery import GitHubFileDelivery

load_dotenv()

app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('FLASK_SECRET_KEY', 'dev-secret-key')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///vector_shop.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db.init_app(app)

paddle_webhook = PaddleWebhook(os.getenv('PADDLE_SHARED_SECRET'))
github_delivery = GitHubFileDelivery(
    os.getenv('GITHUB_TOKEN'),
    os.getenv('GITHUB_REPO')
)

os.makedirs('logs', exist_ok=True)
log_file = os.path.join('logs', f"{datetime.now().strftime('%Y-%m-%d')}.txt")
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(log_file, encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'admin_logged_in' not in session:
            return redirect(url_for('admin_login'))
        return f(*args, **kwargs)
    return decorated_function

def send_email(to_email, subject, body):
    try:
        msg = MIMEMultipart()
        msg['From'] = os.getenv('FROM_EMAIL')
        msg['To'] = to_email
        msg['Subject'] = subject
        
        msg.attach(MIMEText(body, 'html'))
        
        server = smtplib.SMTP(os.getenv('SMTP_SERVER'), int(os.getenv('SMTP_PORT')))
        server.starttls()
        server.login(os.getenv('SMTP_USERNAME'), os.getenv('SMTP_PASSWORD'))
        server.send_message(msg)
        server.quit()
        
        logger.info(f"Email gönderildi: {to_email}")
        return True
    except Exception as e:
        logger.error(f"Email gönderme hatası: {e}")
        return False

@app.route('/')
def index():
    products = Product.query.filter_by(active=True).all()
    logger.info(f"Ana sayfa ziyareti - {len(products)} ürün listelendi")
    return render_template('index.html', products=products)

@app.route('/product/<int:product_id>')
def product_detail(product_id):
    product = Product.query.get_or_404(product_id)
    logger.info(f"Ürün detay sayfası: {product.name}")
    return render_template('product.html', product=product)

@app.route('/checkout/<int:product_id>')
def checkout(product_id):
    product = Product.query.get_or_404(product_id)
    
    paddle_checkout_url = f"https://buy.paddle.com/product/{product.paddle_product_id}"
    
    logger.info(f"Checkout başlatıldı: {product.name}")
    return redirect(paddle_checkout_url)

@app.route('/webhook/paddle', methods=['POST'])
def paddle_webhook_handler():
    logger.info("Paddle webhook alındı")
    
    webhook_data, status_code = paddle_webhook.handle_webhook(request)
    
    if status_code != 200:
        logger.error(f"Webhook doğrulama hatası: {webhook_data}")
        return jsonify(webhook_data), status_code
    
    if webhook_data['event'] == 'payment_succeeded':
        try:
            product_id = int(webhook_data.get('product_id', 0))
            product = Product.query.get(product_id)
            
            if not product:
                logger.error(f"Ürün bulunamadı: {product_id}")
                return jsonify({'error': 'Product not found'}), 404
            
            order_id = Order.generate_order_id()
            download_password = order_id
            
            order = Order(
                order_id=order_id,
                product_id=product_id,
                customer_email=webhook_data['customer_email'],
                customer_name=webhook_data.get('customer_name', ''),
                amount=webhook_data['amount'],
                currency=webhook_data.get('currency', 'USD'),
                paddle_order_id=webhook_data['order_id'],
                status='completed',
                download_password=download_password
            )
            db.session.add(order)
            db.session.commit()
            
            download_links = github_delivery.get_download_links(product.github_release_tag)
            
            email_body = f"""
            <h2>Siparişiniz Tamamlandı!</h2>
            <p>Sayın {webhook_data.get('customer_name', 'Müşteri')},</p>
            <p><strong>{product.name}</strong> ürününüzü satın aldığınız için teşekkür ederiz.</p>
            
            <h3>İndirme Bilgileri:</h3>
            <p><strong>Şifre:</strong> {download_password}</p>
            
            <h3>Dosyaları İndirin:</h3>
            <ul>
            {''.join([f'<li><a href="{link["url"]}">{link["name"]}</a> ({link["size"]/1024/1024:.2f} MB)</li>' for link in download_links])}
            </ul>
            
            <h3>Kullanım Talimatları:</h3>
            <ol>
                <li>Tüm dosya parçalarını indirin</li>
                <li>WinRAR veya 7-Zip ile birleştirin</li>
                <li>Yukarıdaki şifreyi kullanarak açın</li>
            </ol>
            
            <p>Sipariş No: {order_id}</p>
            """
            
            send_email(webhook_data['customer_email'], f"Siparişiniz Hazır - {product.name}", email_body)
            
            order.delivery_sent = True
            db.session.commit()
            
            logger.info(f"Sipariş tamamlandı: {order_id} - {product.name}")
            
        except Exception as e:
            logger.error(f"Webhook işleme hatası: {e}")
            db.session.rollback()
            return jsonify({'error': str(e)}), 500
    
    return jsonify({'status': 'success'}), 200

@app.route('/success')
def success():
    return render_template('success.html')

@app.route('/admin/login', methods=['GET', 'POST'])
def admin_login():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        
        if username == os.getenv('ADMIN_USERNAME') and password == os.getenv('ADMIN_PASSWORD'):
            session['admin_logged_in'] = True
            logger.info("Admin girişi başarılı")
            return redirect(url_for('admin_dashboard'))
        else:
            logger.warning("Başarısız admin giriş denemesi")
            flash('Hatalı kullanıcı adı veya şifre')
    
    return render_template('admin_login.html')

@app.route('/admin/logout')
def admin_logout():
    session.pop('admin_logged_in', None)
    logger.info("Admin çıkışı yapıldı")
    return redirect(url_for('index'))

@app.route('/admin')
@login_required
def admin_dashboard():
    products = Product.query.all()
    orders = Order.query.order_by(Order.created_at.desc()).limit(50).all()
    coupons = Coupon.query.all()
    
    total_revenue = db.session.query(db.func.sum(Order.amount)).filter_by(status='completed').scalar() or 0
    total_orders = Order.query.filter_by(status='completed').count()
    
    return render_template('admin.html', 
                         products=products, 
                         orders=orders, 
                         coupons=coupons,
                         total_revenue=total_revenue,
                         total_orders=total_orders)

@app.route('/admin/product/add', methods=['POST'])
@login_required
def add_product():
    try:
        product = Product(
            name=request.form['name'],
            description=request.form['description'],
            price=float(request.form['price']),
            paddle_product_id=request.form['paddle_product_id'],
            github_release_tag=request.form.get('github_release_tag'),
            file_parts_count=int(request.form.get('file_parts_count', 1)),
            image_url=request.form.get('image_url'),
            active=request.form.get('active') == 'on'
        )
        db.session.add(product)
        db.session.commit()
        
        logger.info(f"Yeni ürün eklendi: {product.name}")
        flash('Ürün başarıyla eklendi')
    except Exception as e:
        logger.error(f"Ürün ekleme hatası: {e}")
        flash(f'Hata: {str(e)}')
    
    return redirect(url_for('admin_dashboard'))

@app.route('/admin/product/delete/<int:product_id>', methods=['POST'])
@login_required
def delete_product(product_id):
    product = Product.query.get_or_404(product_id)
    product.active = False
    db.session.commit()
    
    logger.info(f"Ürün devre dışı bırakıldı: {product.name}")
    flash('Ürün silindi')
    return redirect(url_for('admin_dashboard'))

@app.route('/admin/coupon/add', methods=['POST'])
@login_required
def add_coupon():
    try:
        coupon = Coupon(
            code=request.form['code'].upper(),
            discount_percent=float(request.form['discount_percent']),
            max_uses=int(request.form.get('max_uses')) if request.form.get('max_uses') else None,
            active=True
        )
        db.session.add(coupon)
        db.session.commit()
        
        logger.info(f"Yeni kupon oluşturuldu: {coupon.code}")
        flash('Kupon başarıyla oluşturuldu')
    except Exception as e:
        logger.error(f"Kupon oluşturma hatası: {e}")
        flash(f'Hata: {str(e)}')
    
    return redirect(url_for('admin_dashboard'))

@app.route('/admin/import-csv', methods=['POST'])
@login_required
def import_csv():
    if 'file' not in request.files:
        flash('Dosya seçilmedi')
        return redirect(url_for('admin_dashboard'))
    
    file = request.files['file']
    if file.filename == '':
        flash('Dosya seçilmedi')
        return redirect(url_for('admin_dashboard'))
    
    try:
        stream = file.stream.read().decode("utf-8")
        lines = stream.splitlines()
        
        count = 0
        skipped = 0
        for line in lines[1:]:
            parts = line.split('|')
            if len(parts) < 11:
                skipped += 1
                continue
            
            try:
                csv_id = int(parts[0])
                title = parts[1]
                description = parts[2]
                price = float(parts[3])
                image = parts[4]
                category = parts[5]
                tags = parts[6]
                keywords = parts[7]
                popular = parts[8].lower() == 'true'
                permanentlink = parts[9]
                
                existing = Product.query.filter_by(csv_id=csv_id).first()
                if existing:
                    existing.name = title
                    existing.description = description
                    existing.price = price
                    existing.image_url = image
                    existing.category = category
                    existing.tags = tags
                    existing.keywords = keywords
                    existing.popular = popular
                    existing.permanentlink = permanentlink
                else:
                    product = Product(
                        csv_id=csv_id,
                        name=title,
                        description=description,
                        price=price,
                        image_url=image,
                        category=category,
                        tags=tags,
                        keywords=keywords,
                        popular=popular,
                        permanentlink=permanentlink,
                        paddle_product_id=f"prod_{csv_id}",
                        github_release_tag=f"product-{csv_id}",
                        file_parts_count=1,
                        active=True
                    )
                    db.session.add(product)
                
                count += 1
            except Exception as e:
                logger.error(f"Satır işleme hatası: {e} - {line[:100]}")
                skipped += 1
                continue
        
        db.session.commit()
        logger.info(f"CSV import tamamlandı: {count} ürün işlendi, {skipped} atlandı")
        flash(f'{count} ürün başarıyla içe aktarıldı, {skipped} satır atlandı')
    except Exception as e:
        logger.error(f"CSV import hatası: {e}")
        db.session.rollback()
        flash(f'Hata: {str(e)}')
    
    return redirect(url_for('admin_dashboard'))

@app.route('/admin/logs')
@login_required
def view_logs():
    try:
        with open(log_file, 'r', encoding='utf-8') as f:
            logs = f.read()
        return render_template('logs.html', logs=logs)
    except Exception as e:
        return f"Log dosyası okunamadı: {e}", 500

with app.app_context():
    db.create_all()
    logger.info("Veritabanı tabloları oluşturuldu")

if __name__ == '__main__':
    logger.info("Flask uygulaması başlatılıyor...")
    app.run(debug=True, host='0.0.0.0', port=5000)
