from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_required, current_user
from app import db
from app.models import Project, ProjectBudget, ProjectCost, RevenueRecognition
from datetime import datetime, date
from decimal import Decimal

projects_bp = Blueprint('projects', __name__)

def generate_project_code():
    year = datetime.now().year
    count = Project.query.filter(Project.project_code.like(f'PRJ-{year}-%')).count() + 1
    return f'PRJ-{year}-{count:04d}'

@projects_bp.route('/')
@login_required
def index():
    status = request.args.get('status', 'all')
    query = Project.query
    if status != 'all':
        query = query.filter_by(status=status)
    projects = query.order_by(Project.created_at.desc()).all()
    return render_template('projects/index.html', projects=projects, current_status=status)

@projects_bp.route('/create', methods=['GET', 'POST'])
@login_required
def create():
    if request.method == 'POST':
        project = Project(
            project_code=generate_project_code(),
            project_name=request.form['project_name'],
            client_name=request.form['client_name'],
            contract_number=request.form.get('contract_number'),
            contract_date=datetime.strptime(request.form['contract_date'], '%Y-%m-%d').date() if request.form.get('contract_date') else None,
            start_date=datetime.strptime(request.form['start_date'], '%Y-%m-%d').date(),
            end_date=datetime.strptime(request.form['end_date'], '%Y-%m-%d').date(),
            contract_value=Decimal(request.form['contract_value'].replace(',', '')),
            description=request.form.get('description'),
            performance_obligation=request.form.get('performance_obligation'),
            satisfaction_method=request.form.get('satisfaction_method', 'overtime'),
            created_by=current_user.id
        )
        db.session.add(project)
        db.session.commit()
        flash(f'Proyek {project.project_code} berhasil dibuat!', 'success')
        return redirect(url_for('projects.detail', id=project.id))
    return render_template('projects/create.html')

@projects_bp.route('/<int:id>')
@login_required
def detail(id):
    project = Project.query.get_or_404(id)
    budgets = ProjectBudget.query.filter_by(project_id=id).all()
    costs = ProjectCost.query.filter_by(project_id=id).order_by(ProjectCost.transaction_date.desc()).all()
    revenues = RevenueRecognition.query.filter_by(project_id=id).order_by(RevenueRecognition.recognition_date.desc()).all()
    return render_template('projects/detail.html', project=project, budgets=budgets, costs=costs, revenues=revenues)

@projects_bp.route('/<int:id>/budget/add', methods=['POST'])
@login_required
def add_budget(id):
    project = Project.query.get_or_404(id)
    qty = Decimal(request.form.get('quantity', '1'))
    unit_price = Decimal(request.form.get('unit_price', '0').replace(',', ''))
    budget = ProjectBudget(
        project_id=id,
        cost_category=request.form['cost_category'],
        description=request.form['description'],
        quantity=qty,
        unit=request.form.get('unit', 'unit'),
        unit_price=unit_price,
        amount=qty * unit_price,
        created_by=current_user.id
    )
    db.session.add(budget)
    db.session.commit()
    flash('Anggaran berhasil ditambahkan!', 'success')
    return redirect(url_for('projects.detail', id=id))

@projects_bp.route('/<int:id>/cost/add', methods=['POST'])
@login_required
def add_cost(id):
    project = Project.query.get_or_404(id)
    cost = ProjectCost(
        project_id=id,
        cost_category=request.form['cost_category'],
        description=request.form['description'],
        amount=Decimal(request.form['amount'].replace(',', '')),
        transaction_date=datetime.strptime(request.form['transaction_date'], '%Y-%m-%d').date(),
        reference_number=request.form.get('reference_number'),
        vendor_name=request.form.get('vendor_name'),
        created_by=current_user.id
    )
    db.session.add(cost)
    db.session.commit()
    flash('Biaya proyek berhasil dicatat!', 'success')
    return redirect(url_for('projects.detail', id=id))

@projects_bp.route('/<int:id>/revenue/recognize', methods=['POST'])
@login_required
def recognize_revenue(id):
    """PSAK 72 - Pengakuan Pendapatan berdasarkan metode persentase penyelesaian"""
    project = Project.query.get_or_404(id)
    completion_pct = Decimal(request.form['completion_percentage'])
    period = request.form['period']
    if completion_pct < 0 or completion_pct > 100:
        flash('Persentase penyelesaian harus antara 0 dan 100!', 'danger')
        return redirect(url_for('projects.detail', id=id))
    cumulative_target = project.contract_value * (completion_pct / 100)
    if cumulative_target < project.recognized_revenue:
        flash(f'Persentase penyelesaian terlalu kecil. Total pendapatan yang sudah diakui adalah Rp {project.recognized_revenue:,.0f} ({project.recognized_revenue / project.contract_value * 100:.2f}%).', 'danger')
        return redirect(url_for('projects.detail', id=id))
    recognized = cumulative_target - project.recognized_revenue
    revenue = RevenueRecognition(
        project_id=id,
        recognition_date=datetime.strptime(request.form['recognition_date'], '%Y-%m-%d').date(),
        period=period,
        completion_percentage=completion_pct,
        contract_value=project.contract_value,
        recognized_amount=recognized,
        cumulative_recognized=project.recognized_revenue + recognized,
        notes=request.form.get('notes'),
        created_by=current_user.id
    )
    db.session.add(revenue)
    db.session.commit()
    flash(f'Pendapatan sebesar Rp {recognized:,.0f} berhasil diakui (PSAK 72)!', 'success')
    return redirect(url_for('projects.detail', id=id))

@projects_bp.route('/<int:id>/update-status', methods=['POST'])
@login_required
def update_status(id):
    project = Project.query.get_or_404(id)
    project.status = request.form['status']
    db.session.commit()
    flash('Status proyek berhasil diperbarui!', 'success')
    return redirect(url_for('projects.detail', id=id))
