#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_file
import mysql.connector
from datetime import datetime, timedelta
import os
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
import subprocess
import bcrypt
from flask_mail import Mail, Message
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import threading

app = Flask(__name__)
app.secret_key = 'R0mt3l3c0m!'

# Configurare Email
app.config['MAIL_SERVER'] = 'box.lbsol.ro'  # SAU alt server SMTP
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'concedii@lbsol.ro'  # Email-ul companiei
app.config['MAIL_PASSWORD'] = 'Qpq9kbmbr6!'     # Parola aplica?iei
app.config['MAIL_DEFAULT_SENDER'] = 'concedii@lbsol.ro'

mail = Mail(app)


# Configurare MySQL
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': 'romtelecom',  # SCHIMBÄ‚ ASTA
    'database': 'evidenta_deconturi'
}

def get_db_connection():
    return mysql.connector.connect(**DB_CONFIG)

def send_email_notification(cerere_id):
    """Trimite email la HR cand ambele parti au semnat - asincron"""
    def send_async():
        try:
            conn = get_db_connection()
            cursor = conn.cursor(dictionary=True)
            
            cursor.execute("SELECT * FROM cereri_concediu WHERE id = %s", (cerere_id,))
            cerere = cursor.fetchone()
            
            cursor.close()
            conn.close()
            
            if not cerere:
                return
            
            # Creeaza mesajul
            msg = MIMEMultipart()
            msg['From'] = app.config['MAIL_DEFAULT_SENDER']
            msg['To'] = 'hr@lbsol.ro'
            msg['Subject'] = f'Cerere de concediu semnata - {cerere["name"]}'
            
            body = f"""
Buna ziua,

O cerere de concediu a fost semnata de ambele parti si asteapta aprobare:

Solicitant: {cerere['name']}
Inlocuitor: {cerere['inlocuitor_name']}
Perioada: {cerere['data_start'].strftime('%d.%m.%Y')} - {cerere['data_sfarsit'].strftime('%d.%m.%Y')}
Numar zile: {cerere['nr_zile']}
Data completare: {cerere['data_completare']}

Data semnare solicitant: {cerere['data_semnare_solicitant'].strftime('%d.%m.%Y %H:%M') if cerere['data_semnare_solicitant'] else 'N/A'}
Data semnare inlocuitor: {cerere['data_semnare_inlocuitor'].strftime('%d.%m.%Y %H:%M') if cerere['data_semnare_inlocuitor'] else 'N/A'}

Accesati aplicatia pentru a aproba cererea.

Aplicatie Cereri de Concediu
            """
            
            msg.attach(MIMEText(body, 'plain'))
            
            # Trimite email cu timeout
            server = smtplib.SMTP(app.config['MAIL_SERVER'], app.config['MAIL_PORT'], timeout=10)
            server.starttls()
            server.login(app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
            text = msg.as_string()
            server.sendmail(msg['From'], msg['To'], text)
            server.quit()
            
            print(f"? Email trimis cu succes pentru cererea {cerere_id}")
            
        except Exception as e:
            print(f"? Eroare trimitere email: {e}")
            # Nu oprim procesul daca emailul e?ueaza
    
    # Ruleaza în thread separat pentru a nu bloca request-ul
    thread = threading.Thread(target=send_async)
    thread.daemon = True
    thread.start()

# Decorator pentru autentificare
def login_required(f):
    from functools import wraps
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return jsonify({'error': 'Neautentificat'}), 401
        return f(*args, **kwargs)
    return decorated_function

# ===== RUTE AUTENTIFICARE =====

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

@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    cursor.execute("SELECT * FROM employees WHERE username = %s", (username,))
    user = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    if not user:
        return jsonify({'error': 'Username sau parolÄƒ incorectÄƒ'}), 401
    
    # Verificare parolÄƒ cu bcrypt
    try:
        password_hash = user['password']
        if isinstance(password_hash, str):
            password_hash = password_hash.encode('utf-8')
        
        if not bcrypt.checkpw(password.encode('utf-8'), password_hash):
            return jsonify({'error': 'Username sau parolÄƒ incorectÄƒ'}), 401
    except Exception as e:
        print(f"Eroare verificare parolÄƒ: {e}")
        return jsonify({'error': 'Username sau parolÄƒ incorectÄƒ'}), 401
    
    # SeteazÄƒ sesiunea
    session['user_id'] = user['id']
    session['username'] = user['username']
    session['name'] = user['name']
    session['role'] = user.get('role', 'user')
    
    return jsonify({
        'success': True,
        'user': {
            'id': user['id'],
            'name': user['name'],
            'username': user['username'],
            'role': session['role']
        }
    })

@app.route('/api/logout', methods=['POST'])
def logout():
    session.clear()
    return jsonify({'success': True})

@app.route('/api/current-user')
@login_required
def current_user():
    return jsonify({
        'id': session['user_id'],
        'name': session['name'],
        'username': session['username'],
        'role': session['role']
    })

# ===== RUTE PRINCIPALE =====

@app.route('/')
def index():
    # Verifica daca user-ul e autentificat
    if 'user_id' not in session:
        return redirect(url_for('login_page'))
    return render_template('index_mysql_v2.html')  # ATEN?IE: v2!

@app.route('/api/users')
@login_required
def get_users():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT id, name, username FROM employees ORDER BY name")
    users = cursor.fetchall()
    cursor.close()
    conn.close()
    return jsonify(users)

@app.route('/api/cereri', methods=['GET'])
@login_required
def get_cereri():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    user_role = session.get('role', 'user')
    username = session.get('username', '')
    user_id = session.get('user_id')
    
    # Admin, Calin, Rares vad TOATE cererile
    allowed_users = ['admin', 'calin.lisovschi', 'rares.lisovschi']
    
    if user_role == 'admin' or username in allowed_users:
        # Vede toate cererile
        cursor.execute("""
            SELECT c.*, e1.name as name, e2.name as inlocuitor_name
            FROM cereri_concediu c
            LEFT JOIN employees e1 ON c.user_id = e1.id
            LEFT JOIN employees e2 ON c.inlocuitor_id = e2.id
            ORDER BY c.created_at DESC
        """)
    else:
        # User normal vede doar cererile LUI (ca solicitant sau înlocuitor)
        cursor.execute("""
            SELECT c.*, e1.name as name, e2.name as inlocuitor_name
            FROM cereri_concediu c
            LEFT JOIN employees e1 ON c.user_id = e1.id
            LEFT JOIN employees e2 ON c.inlocuitor_id = e2.id
            WHERE c.user_id = %s OR c.inlocuitor_id = %s
            ORDER BY c.created_at DESC
        """, (user_id, user_id))
    
    cereri = cursor.fetchall()
    cursor.close()
    conn.close()
    
    # Formateaza datele
    for cerere in cereri:
        for key in ['data_start', 'data_sfarsit', 'data_semnare_solicitant', 'data_semnare_inlocuitor', 'created_at', 'data_aprobare']:
            if cerere.get(key):
                cerere[key] = cerere[key].isoformat() if hasattr(cerere[key], 'isoformat') else str(cerere[key])
    
    return jsonify(cereri)

@app.route('/api/cereri', methods=['POST'])
@login_required
def create_cerere():
    data = request.get_json()
    
    user_id = data.get('user_id')
    data_start = data.get('data_start')
    data_sfarsit = data.get('data_sfarsit')
    inlocuitor_id = data.get('inlocuitor_id')
    
    # ValidÄƒri
    if not all([user_id, data_start, data_sfarsit, inlocuitor_id]):
        return jsonify({'error': 'Toate cÃ¢mpurile sunt obligatorii'}), 400
    
    if user_id == inlocuitor_id:
        return jsonify({'error': 'ÃŽnlocuitorul trebuie sÄƒ fie o persoanÄƒ diferitÄƒ'}), 400
    
    # CalculeazÄƒ numÄƒrul de zile
    start = datetime.strptime(data_start, '%Y-%m-%d')
    end = datetime.strptime(data_sfarsit, '%Y-%m-%d')
    nr_zile = (end - start).days + 1
    
    if nr_zile <= 0:
        return jsonify({'error': 'Perioada invalidÄƒ'}), 400
    
    # ObÈ›ine numele
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    cursor.execute("SELECT name FROM employees WHERE id = %s", (user_id,))
    solicitant = cursor.fetchone()
    
    cursor.execute("SELECT name FROM employees WHERE id = %s", (inlocuitor_id,))
    inlocuitor = cursor.fetchone()
    
    if not solicitant or not inlocuitor:
        cursor.close()
        conn.close()
        return jsonify({'error': 'Utilizator invalid'}), 400
    
    data_completare = datetime.now().strftime('%d.%m.%Y')
    
    # Insert Ã®n baza de date
    cursor.execute("""
        INSERT INTO cereri_concediu 
        (user_id, name, data_start, data_sfarsit, nr_zile, inlocuitor_id, inlocuitor_name, data_completare, status)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, 'pending')
    """, (user_id, solicitant['name'], data_start, data_sfarsit, nr_zile, inlocuitor_id, inlocuitor['name'], data_completare))
    
    cerere_id = cursor.lastrowid
    conn.commit()
    
    # GenereazÄƒ PDF iniÈ›ial (fÄƒrÄƒ semnÄƒturi)
    try:
        pdf_path = generate_pdf(cerere_id, solicitant['name'], inlocuitor['name'], data_start, data_sfarsit, nr_zile, data_completare)
        cursor.execute("UPDATE cereri_concediu SET pdf_path = %s WHERE id = %s", (pdf_path, cerere_id))
        conn.commit()
    except Exception as e:
        print(f"Eroare generare PDF: {e}")
    
    cursor.close()
    conn.close()
    
    return jsonify({'success': True, 'id': cerere_id})

@app.route('/api/cereri/<int:id>/semneaza', methods=['POST'])
@login_required
def semneaza_cerere(id):
    data = request.get_json()
    tip = data.get('tip')  # 'solicitant' sau 'inlocuitor'
    
    if tip not in ['solicitant', 'inlocuitor']:
        return jsonify({'error': 'Tip invalid'}), 400
    
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    # ObÈ›ine cererea
    cursor.execute("SELECT * FROM cereri_concediu WHERE id = %s", (id,))
    cerere = cursor.fetchone()
    
    if not cerere:
        cursor.close()
        conn.close()
        return jsonify({'error': 'Cerere negÄƒsitÄƒ'}), 404
    
    # Update status semnare
    now = datetime.now()
    if tip == 'solicitant':
        cursor.execute("""
            UPDATE cereri_concediu 
            SET semnat_solicitant = 1, data_semnare_solicitant = %s 
            WHERE id = %s
        """, (now, id))
    else:
        cursor.execute("""
            UPDATE cereri_concediu 
            SET semnat_inlocuitor = 1, data_semnare_inlocuitor = %s 
            WHERE id = %s
        """, (now, id))
    
    conn.commit()

    # Verifica daca ambele par?i au semnat DUPA acest update
    cursor.execute("SELECT semnat_solicitant, semnat_inlocuitor FROM cereri_concediu WHERE id = %s", (id,))
    check = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    # Regenereaza PDF IMEDIAT
    try:
        pdf_path = generate_pdf_with_signatures(id)
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("UPDATE cereri_concediu SET pdf_path = %s WHERE id = %s", (pdf_path, id))
        conn.commit()
        cursor.close()
        conn.close()
    except Exception as e:
        print(f"Eroare regenerare PDF: {e}")
    
    # Trimite email ASINCRON (în background) - nu blochez response-ul
    if check and check['semnat_solicitant'] and check['semnat_inlocuitor']:
        send_email_notification(id)
    
    return jsonify({'success': True})

def generate_pdf(cerere_id, nume_solicitant, nume_inlocuitor, data_start, data_sfarsit, nr_zile, data_completare):
    """GenereazÄƒ PDF iniÈ›ial fÄƒrÄƒ semnÄƒturi"""
    template_path = '/var/www/html/concedii/templates_word/cerere_concediu_template.docx'
    
    if not os.path.exists(template_path):
        raise FileNotFoundError(f"Template nu existÄƒ: {template_path}")
    
    doc = Document(template_path)
    
    # ÃŽnlocuieÈ™te placeholder-ele
    replacements = {
        '{NUME_SOLICITANT}': nume_solicitant,
        '{NUME_INLOCUITOR}': nume_inlocuitor,
        '{DATA_START}': datetime.strptime(data_start, '%Y-%m-%d').strftime('%d.%m.%Y'),
        '{DATA_SFARSIT}': datetime.strptime(data_sfarsit, '%Y-%m-%d').strftime('%d.%m.%Y'),
        '{NR_ZILE}': str(nr_zile),
        '{DATA_COMPLETARE}': data_completare,
        '{SEMNATURA_SOLICITANT}': '................................',
        '{DATA_SEMNARE_SOLICITANT}': '',
        '{SEMNATURA_INLOCUITOR}': '................................',
        '{DATA_SEMNARE_INLOCUITOR}': ''
    }
    
    for paragraph in doc.paragraphs:
        for key, value in replacements.items():
            if key in paragraph.text:
                paragraph.text = paragraph.text.replace(key, value)
    
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for key, value in replacements.items():
                    if key in cell.text:
                        cell.text = cell.text.replace(key, value)
    
    # SalveazÄƒ DOCX
    filename = f"{nume_solicitant.replace(' ', '-')}-{datetime.now().strftime('%Y%m%d')}.docx"
    docx_path = f'/var/www/html/concedii/cereri_pdf/{filename}'
    doc.save(docx_path)
    
    # ConverteÈ™te la PDF
    pdf_filename = filename.replace('.docx', '.pdf')
    pdf_path = f'/var/www/html/concedii/cereri_pdf/{pdf_filename}'
    
    subprocess.run([
        'libreoffice', '--headless', '--convert-to', 'pdf',
        '--outdir', '/var/www/html/concedii/cereri_pdf',
        docx_path
    ], check=True)
    
    return pdf_filename

def generate_pdf_with_signatures(cerere_id):
    """RegenereazÄƒ PDF cu semnÄƒturi (nume Ã®n cursiv)"""
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    cursor.execute("SELECT * FROM cereri_concediu WHERE id = %s", (cerere_id,))
    cerere = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    if not cerere:
        raise ValueError("Cerere negÄƒsitÄƒ")
    
    template_path = '/var/www/html/concedii/templates_word/cerere_concediu_template.docx'
    doc = Document(template_path)
    
    # PregÄƒteÈ™te semnÄƒturile
    semn_sol = cerere['name'] if cerere['semnat_solicitant'] else '................................'
    data_semn_sol = cerere['data_semnare_solicitant'].strftime('%d.%m.%Y') if cerere['data_semnare_solicitant'] else ''
    
    semn_inl = cerere['inlocuitor_name'] if cerere['semnat_inlocuitor'] else '................................'
    data_semn_inl = cerere['data_semnare_inlocuitor'].strftime('%d.%m.%Y') if cerere['data_semnare_inlocuitor'] else ''
    
    replacements = {
        '{NUME_SOLICITANT}': cerere['name'],
        '{NUME_INLOCUITOR}': cerere['inlocuitor_name'],
        '{DATA_START}': cerere['data_start'].strftime('%d.%m.%Y'),
        '{DATA_SFARSIT}': cerere['data_sfarsit'].strftime('%d.%m.%Y'),
        '{NR_ZILE}': str(cerere['nr_zile']),
        '{DATA_COMPLETARE}': cerere['data_completare'],
        '{SEMNATURA_SOLICITANT}': semn_sol,
        '{DATA_SEMNARE_SOLICITANT}': data_semn_sol,
        '{SEMNATURA_INLOCUITOR}': semn_inl,
        '{DATA_SEMNARE_INLOCUITOR}': data_semn_inl
    }
    
    # ÃŽnlocuieÈ™te text
    for paragraph in doc.paragraphs:
        for key, value in replacements.items():
            if key in paragraph.text:
                # DacÄƒ e semnÄƒturÄƒ, foloseÈ™te font cursiv
                if 'SEMNATURA' in key and value != '................................':
                    for run in paragraph.runs:
                        if key in run.text:
                            run.text = run.text.replace(key, value)
                            run.font.name = 'Brush Script MT'
                            run.font.size = Pt(14)
                            run.font.bold = True
                else:
                    paragraph.text = paragraph.text.replace(key, value)
    
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for key, value in replacements.items():
                    if key in cell.text:
                        if 'SEMNATURA' in key and value != '................................':
                            for paragraph in cell.paragraphs:
                                for run in paragraph.runs:
                                    if key in run.text:
                                        run.text = run.text.replace(key, value)
                                        run.font.name = 'Brush Script MT'
                                        run.font.size = Pt(14)
                                        run.font.bold = True
                        else:
                            cell.text = cell.text.replace(key, value)
    
    # SalveazÄƒ
    filename = f"{cerere['name'].replace(' ', '-')}-{datetime.now().strftime('%Y%m%d')}.docx"
    docx_path = f'/var/www/html/concedii/cereri_pdf/{filename}'
    doc.save(docx_path)
    
    # ConverteÈ™te la PDF
    pdf_filename = filename.replace('.docx', '.pdf')
    subprocess.run([
        'libreoffice', '--headless', '--convert-to', 'pdf',
        '--outdir', '/var/www/html/concedii/cereri_pdf',
        docx_path
    ], check=True)
    
    return pdf_filename

@app.route('/api/cereri/<int:id>/pdf')
@login_required
def download_pdf(id):
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT pdf_path FROM cereri_concediu WHERE id = %s", (id,))
    cerere = cursor.fetchone()
    cursor.close()
    conn.close()
    
    if not cerere or not cerere['pdf_path']:
        return jsonify({'error': 'PDF negÄƒsit'}), 404
    
    pdf_path = f"/var/www/html/concedii/cereri_pdf/{cerere['pdf_path']}"
    
    if not os.path.exists(pdf_path):
        return jsonify({'error': 'FiÈ™ier PDF negÄƒsit'}), 404
    
    return send_file(pdf_path, as_attachment=True)

@app.route('/api/calendar')
@login_required
def get_calendar():
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    cursor.execute("""
        SELECT c.*, e1.name as name, e2.name as inlocuitor_name
        FROM cereri_concediu c
        LEFT JOIN employees e1 ON c.user_id = e1.id
        LEFT JOIN employees e2 ON c.inlocuitor_id = e2.id
    """)
    cereri = cursor.fetchall()
    cursor.close()
    conn.close()
    
    events = []
    for cerere in cereri:
        events.append({
            'title': cerere['name'],
            'start': cerere['data_start'].isoformat(),
            'end': (cerere['data_sfarsit'] + timedelta(days=1)).isoformat(),
            'color': '#667eea' if cerere['status'] == 'pending' else '#27ae60',
            'extendedProps': {
                'nr_zile': cerere['nr_zile'],
                'inlocuitor': cerere['inlocuitor_name'],
                'status': cerere['status']
            }
        })
    
    return jsonify(events)

@app.route('/api/cereri/<int:id>/aproba', methods=['POST'])
@login_required
def aproba_cerere(id):
    # Verifica daca user-ul are drept de aprobare
    user_role = session.get('role', 'user')
    username = session.get('username', '')
    
    # Doar admin sau useri specifici pot aproba
    allowed_users = ['admin', 'calin.lisovschi', 'rares.lisovschi']
    
    if user_role != 'admin' and username not in allowed_users:
        return jsonify({'error': 'Nu aveti dreptul sa aprobati cereri'}), 403
    
    conn = get_db_connection()
    cursor = conn.cursor(dictionary=True)
    
    # Verifica daca cererea exista si e semnata de ambii
    cursor.execute("SELECT * FROM cereri_concediu WHERE id = %s", (id,))
    cerere = cursor.fetchone()
    
    if not cerere:
        cursor.close()
        conn.close()
        return jsonify({'error': 'Cerere negasita'}), 404
    
    if not cerere['semnat_solicitant'] or not cerere['semnat_inlocuitor']:
        cursor.close()
        conn.close()
        return jsonify({'error': 'Cererea trebuie semnata de ambele parti inainte de aprobare'}), 400
    
    # Aproba cererea
    cursor.execute("""
        UPDATE cereri_concediu 
        SET status = 'approved', 
            data_aprobare = NOW(),
            aprobat_de = %s
        WHERE id = %s
    """, (session['name'], id))
    
    conn.commit()
    cursor.close()
    conn.close()

    # Regenereaza PDF cu status aprobat
    try:
        pdf_path = generate_pdf_with_signatures(id)
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("UPDATE cereri_concediu SET pdf_path = %s WHERE id = %s", (pdf_path, id))
        conn.commit()
        cursor.close()
        conn.close()
        print(f"? PDF regenerat la aprobare: {pdf_path}")
    except Exception as e:
        print(f"? Eroare regenerare PDF la aprobare: {e}")
    
    return jsonify({'success': True})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)
