<?php
/**
 * PDF Service
 * Handles PDF generation for invoices, proposals, contracts, and reports
 * using the built-in FS_PDF library (clean PDF 1.4, no TCPDF dependency).
 *
 * @package Freelance_Studio
 * @since 3.9.3
 * @updated 7.1.0 - Replaced TCPDF with FS_PDF for security and Gmail compatibility
 */

if (!defined('ABSPATH')) {
    exit;
}

class FS_PDF_Service {

    private static function init_pdf() {
        if (class_exists('FS_PDF')) return true;
        $pdf_path = JEEB_FS_PLUGIN_DIR . 'includes/libraries/class-fs-pdf.php';
        if (file_exists($pdf_path)) {
            require_once($pdf_path);
            return class_exists('FS_PDF');
        }
        return false;
    }

    private static function image_to_path($url) {
        if (empty($url)) return false;
        if (strpos($url, '/') === 0 && file_exists($url)) return $url;
        $upload_dir = wp_upload_dir();
        if (strpos($url, $upload_dir['baseurl']) === 0) {
            $file_path = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $url);
            if (file_exists($file_path)) return $file_path;
        }
        return false;
    }

    private static function signature_to_temp_file($base64_data) {
        if (empty($base64_data)) return false;
        $data = $base64_data;
        if (strpos($base64_data, 'data:image') === 0) {
            $comma_pos = strpos($base64_data, ',');
            if ($comma_pos !== false) $data = substr($base64_data, $comma_pos + 1);
        }
        $image_data = base64_decode($data);
        if ($image_data === false) return false;
        $src_image = @imagecreatefromstring($image_data);
        if ($src_image === false) return false;
        $width = imagesx($src_image);
        $height = imagesy($src_image);
        $new_image = imagecreatetruecolor($width, $height);
        $white = imagecolorallocate($new_image, 255, 255, 255);
        imagefill($new_image, 0, 0, $white);
        imagealphablending($new_image, true);
        imagesavealpha($new_image, false);
        imagecopy($new_image, $src_image, 0, 0, 0, 0, $width, $height);
        $tmp_file = tempnam(sys_get_temp_dir(), 'fssig_') . '.png';
        imagepng($new_image, $tmp_file);
        imagedestroy($src_image);
        imagedestroy($new_image);
        return $tmp_file;
    }

    private static function get_business_settings() {
        return array(
            'business_name' => get_option('fs_business_name', 'Freelance Studio'),
            'business_email' => get_option('fs_business_email', ''),
            'business_phone' => get_option('fs_business_phone', ''),
            'business_address' => get_option('fs_business_address', ''),
            'business_city' => get_option('fs_business_city', ''),
            'business_state' => get_option('fs_business_state', ''),
            'business_zip' => get_option('fs_business_zip', ''),
            'business_country' => get_option('fs_business_country', ''),
            'business_website' => get_option('fs_business_website', ''),
            'business_logo' => get_option('fs_business_logo', ''),
            'business_logo_light' => get_option('fs_business_logo_light', ''),
            'primary_color' => get_option('fs_invoice_primary_color', '#2271b1'),
            'payment_instructions' => get_option('fs_payment_instructions', ''),
        );
    }

    private static function create_pdf($settings, $title) {
        $pdf = new FS_PDF('P', 'mm', 'A4');
        $pdf->SetMargins(20, 20, 20, 20);
        $pdf->SetAutoPageBreak(true, 20);
        $pdf->SetTitle($title);
        $pdf->SetAuthor($settings['business_name']);
        $pdf->SetCreator('Freelance Studio');
        return $pdf;
    }

    private static function render_header(&$pdf, $settings, $doc_type, $doc_number = '') {
        $pc = FS_PDF::hexToRGB($settings['primary_color']);
        $w = $pdf->GetPageWidth();
        $logo_path = self::image_to_path($settings['business_logo']);
        if ($logo_path) {
            $pdf->Image($logo_path, 20, 20, 40, 0);
            $pdf->SetY(38);
        }
        // Doc type right-aligned
        $pdf->SetXY(20, 20);
        $pdf->SetFont('Helvetica', '', 18);
        $pdf->SetTextColor($pc[0], $pc[1], $pc[2]);
        $pdf->Cell($w, 8, $doc_type, 0, 1, 'R');
        if ($doc_number) {
            $pdf->SetFont('Helvetica', '', 9);
            $pdf->SetTextColor(150, 150, 150);
            $pdf->Cell($w, 4, '#' . $doc_number, 0, 1, 'R');
        }
        // Business info below logo
        $y = max($logo_path ? 38 : 20, $pdf->GetY() + 2);
        $pdf->SetY($y);
        $pdf->SetFont('Helvetica', 'B', 11);
        $pdf->SetTextColor($pc[0], $pc[1], $pc[2]);
        $pdf->Cell($w * 0.6, 5, $settings['business_name'], 0, 1);
        $pdf->SetFont('Helvetica', '', 8);
        $pdf->SetTextColor(100, 100, 100);
        if (!empty($settings['business_email'])) $pdf->Cell($w * 0.6, 4, $settings['business_email'], 0, 1);
        if (!empty($settings['business_phone'])) $pdf->Cell($w * 0.6, 4, $settings['business_phone'], 0, 1);
        if (!empty($settings['business_address'])) $pdf->Cell($w * 0.6, 4, $settings['business_address'], 0, 1);
        $loc = array_filter(array($settings['business_city'], $settings['business_state'], $settings['business_zip']));
        if (!empty($loc)) $pdf->Cell($w * 0.6, 4, implode(', ', $loc), 0, 1);
        return $pdf->GetY();
    }

    private static function render_client_block(&$pdf, $client, $label = 'BILL TO:') {
        $pdf->SetFont('Helvetica', '', 8);
        $pdf->SetTextColor(150, 150, 150);
        $pdf->Cell(0, 4, $label, 0, 1);
        $pdf->SetFont('Helvetica', 'B', 11);
        $pdf->SetTextColor(0, 0, 0);
        $pdf->Cell(0, 5, $client->company_name ?: $client->name, 0, 1);
        $pdf->SetFont('Helvetica', '', 9);
        $pdf->SetTextColor(100, 100, 100);
        if (!empty($client->company_name) && !empty($client->name)) $pdf->Cell(0, 4, $client->name, 0, 1);
        if (!empty($client->email)) $pdf->Cell(0, 4, $client->email, 0, 1);
        if (!empty($client->address)) $pdf->Cell(0, 4, $client->address, 0, 1);
        $loc_parts = array();
        if (!empty($client->city)) $loc_parts[] = $client->city;
        if (!empty($client->state)) $loc_parts[] = $client->state;
        if (!empty($client->zip)) $loc_parts[] = $client->zip;
        if (!empty($loc_parts)) $pdf->Cell(0, 4, implode(', ', $loc_parts), 0, 1);
    }

    private static function render_status_badge(&$pdf, $status) {
        $colors = array(
            'paid' => array(209,250,229, 6,95,70), 'completed' => array(209,250,229, 6,95,70),
            'approved' => array(209,250,229, 6,95,70), 'partial' => array(254,243,199, 146,64,14),
            'overdue' => array(254,226,226, 153,27,27), 'rejected' => array(254,226,226, 153,27,27),
            'sent' => array(219,234,254, 30,64,175), 'viewed' => array(219,234,254, 30,64,175),
            'draft' => array(243,244,246, 55,65,81),
        );
        $c = $colors[$status] ?? array(243,244,246, 55,65,81);
        $label = strtoupper($status);
        $pdf->SetFont('Helvetica', 'B', 8);
        $badge_w = $pdf->GetStringWidth($label) + 8;
        $pdf->SetFillColor($c[0], $c[1], $c[2]);
        $pdf->SetTextColor($c[3], $c[4], $c[5]);
        $pdf->Rect($pdf->GetX(), $pdf->GetY(), $badge_w, 5.5, 'F');
        $pdf->Cell($badge_w, 5.5, $label, 0, 1, 'C');
    }

    private static function render_section_heading(&$pdf, $title, $primary_color) {
        $pc = FS_PDF::hexToRGB($primary_color);
        $pdf->SetFont('Helvetica', 'B', 12);
        $pdf->SetTextColor(17, 17, 17);
        $pdf->Cell(0, 6, $title, 0, 1);
        $y = $pdf->GetY();
        $pdf->SetDrawColor($pc[0], $pc[1], $pc[2]);
        $pdf->SetLineWidth(0.5);
        $pdf->Line(20, $y, 20 + $pdf->GetPageWidth(), $y);
        $pdf->SetLineWidth(0.2);
        $pdf->Ln(3);
    }

    private static function render_footer(&$pdf, $text) {
        $pdf->Ln(10);
        $pdf->SetFont('Helvetica', '', 8);
        $pdf->SetTextColor(150, 150, 150);
        $pdf->Cell(0, 5, $text, 0, 1, 'C');
    }

    private static function render_fallback($title, $subtitle) {
        while (ob_get_level()) ob_end_clean();
        header('Content-Type: text/html; charset=utf-8');
        echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>' . esc_html($title) . '</title>';
        echo '<style>@media print{@page{margin:.5in}body{margin:0}}body{font-family:Arial,sans-serif;padding:40px}</style>';
        echo '<script>window.onload=function(){window.print()}</script></head><body>';
        echo '<h1>' . esc_html($title) . '</h1><p>' . esc_html($subtitle) . '</p>';
        echo '<p>PDF library not available. Please use browser print to save as PDF.</p></body></html>';
        exit;
    }

    // ================================================================
    // PROPOSAL
    // ================================================================
    public static function generate_proposal($proposal, $client) {
        if (!self::init_pdf()) { self::render_fallback($proposal->title, 'Proposal #' . $proposal->proposal_number); return; }
        while (ob_get_level()) ob_end_clean();

        $settings = self::get_business_settings();
        $services = is_array($proposal->services) ? $proposal->services : array();
        $custom_sections = is_array($proposal->custom_sections) ? $proposal->custom_sections : array();
        $deposit_amount = FS_Proposal::calculate_deposit($proposal);
        $frequencies = FS_Proposal::get_billing_frequencies();
        $sections_before = array_filter($custom_sections, function($s) { return ($s['position'] ?? 'before_pricing') === 'before_pricing'; });
        $sections_after = array_filter($custom_sections, function($s) { return ($s['position'] ?? '') === 'after_pricing'; });

        $pdf = self::create_pdf($settings, 'Proposal ' . $proposal->proposal_number);
        $pdf->AddPage();
        $w = $pdf->GetPageWidth();

        self::render_header($pdf, $settings, 'PROPOSAL', $proposal->proposal_number);
        if ($proposal->status === 'approved') { self::render_status_badge($pdf, 'approved'); }
        $pdf->Ln(5);

        // Title
        $pdf->SetFont('Helvetica', 'B', 16);
        $pdf->SetTextColor(17, 17, 17);
        $pdf->MultiCell($w, 7, $proposal->title, 0, 'L');
        if (!empty($proposal->start_date)) {
            $pdf->SetFont('Helvetica', '', 9);
            $pdf->SetTextColor(100, 100, 100);
            $pdf->Cell(0, 5, 'Starts: ' . gmdate('F j, Y', strtotime($proposal->start_date)), 0, 1);
        }
        $pdf->Ln(5);

        // TO / FROM
        $col_w = $w / 2;
        $y_start = $pdf->GetY();
        self::render_client_block($pdf, $client, 'TO:');
        $y_left = $pdf->GetY();
        $pdf->SetXY(20 + $col_w, $y_start);
        $pdf->SetFont('Helvetica', '', 8); $pdf->SetTextColor(150,150,150);
        $pdf->Cell($col_w, 4, 'FROM:', 0, 2);
        $pdf->SetFont('Helvetica', 'B', 11); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($col_w, 5, $settings['business_name'], 0, 2);
        $pdf->SetFont('Helvetica', '', 9); $pdf->SetTextColor(100,100,100);
        if (!empty($settings['business_email'])) $pdf->Cell($col_w, 4, $settings['business_email'], 0, 2);
        if (!empty($settings['business_address'])) $pdf->Cell($col_w, 4, $settings['business_address'], 0, 2);
        $loc = array_filter(array($settings['business_city'], $settings['business_state'], $settings['business_zip']));
        if (!empty($loc)) $pdf->Cell($col_w, 4, implode(', ', $loc), 0, 2);
        $pdf->SetY(max($y_left, $pdf->GetY()) + 5);

        // Custom sections before pricing
        foreach ($sections_before as $section) {
            if (!empty($section['title'])) self::render_section_heading($pdf, $section['title'], $settings['primary_color']);
            if (!empty($section['content'])) { $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(68,68,68); $pdf->WriteHTML($section['content'], $w); }
            $pdf->Ln(3);
        }

        // Services
        self::render_section_heading($pdf, 'Services Summary', $settings['primary_color']);
        foreach ($services as $svc) {
            $name = $svc['name'] ?? 'Service';
            $amt = floatval($svc['total'] ?? $svc['amount'] ?? 0);
            $desc = $svc['description'] ?? '';
            $pdf->SetDrawColor(238,238,238);
            $pdf->SetFont('Helvetica', 'B', 10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w * 0.7, 6, $name, 0, 0);
            $pdf->Cell($w * 0.3, 6, '$' . number_format($amt, 2), 0, 1, 'R');
            if (!empty($desc)) { $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100); $pdf->MultiCell($w, 3.5, $desc, 0, 'L'); }
            $y = $pdf->GetY(); $pdf->Line(20, $y+1, 20+$w, $y+1); $pdf->Ln(3);
        }

        // Billing schedule
        if (!empty($proposal->billing_frequency) && $proposal->billing_frequency !== 'once') {
            $pdf->Ln(2); $pdf->SetFillColor(249,249,249);
            $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w, 6, 'Billing Schedule', 0, 1, 'L', true);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->Cell($w, 5, 'Frequency: ' . ($frequencies[$proposal->billing_frequency] ?? $proposal->billing_frequency), 0, 1, 'L', true);
            if (!empty($proposal->first_invoice_date)) $pdf->Cell($w, 5, 'First Invoice: ' . gmdate('F j, Y', strtotime($proposal->first_invoice_date)), 0, 1, 'L', true);
        }

        // Deposit
        if (!empty($proposal->deposit_required) && $deposit_amount > 0) {
            $pdf->Ln(3); $pdf->SetFillColor(255,251,235);
            $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(146,64,14);
            $dep = '$' . number_format($deposit_amount, 2);
            if (($proposal->deposit_type ?? '') === 'percentage') $dep .= ' (' . number_format($proposal->deposit_value, 0) . '%)';
            $pdf->Cell($w, 6, 'Deposit Required', 0, 1, 'L', true);
            $pdf->SetFont('Helvetica','B',13);
            $pdf->Cell($w, 7, $dep, 0, 1, 'L', true);
        }

        // Total
        $pdf->Ln(3);
        $y = $pdf->GetY(); $pdf->SetDrawColor(51,51,51); $pdf->SetLineWidth(0.5); $pdf->Line(20,$y,20+$w,$y); $pdf->SetLineWidth(0.2);
        $pdf->SetFont('Helvetica','B',13); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($w*0.7, 10, 'Total:', 0, 0);
        $pdf->SetFont('Helvetica','B',18);
        $pdf->Cell($w*0.3, 10, '$' . number_format($proposal->total_amount, 2), 0, 1, 'R');

        // Custom sections after pricing
        foreach ($sections_after as $section) {
            $pdf->Ln(3);
            if (!empty($section['title'])) self::render_section_heading($pdf, $section['title'], $settings['primary_color']);
            if (!empty($section['content'])) { $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(68,68,68); $pdf->WriteHTML($section['content'], $w); }
        }

        // Notes
        if (!empty($proposal->notes)) {
            $pdf->Ln(5); $pdf->SetFillColor(249,249,249);
            $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w, 6, 'Notes', 0, 1, 'L', true);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->MultiCell($w, 4, $proposal->notes, 0, 'L', true);
        }

        // Approval signature
        if ($proposal->status === 'approved' && !empty($proposal->signature_client)) {
            $pdf->Ln(5);
            self::render_section_heading($pdf, 'Approval', $settings['primary_color']);
            $sig_file = self::signature_to_temp_file($proposal->signature_client);
            if ($sig_file) { $pdf->Image($sig_file, null, null, 50, 0); wp_delete_file($sig_file); }
            $pdf->Ln(2);
            $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell(0, 5, $proposal->signature_client_name ?? '', 0, 1);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            if (!empty($client->company_name)) $pdf->Cell(0, 4, $client->company_name, 0, 1);
            if (!empty($proposal->signature_date)) $pdf->Cell(0, 4, gmdate('F j, Y', strtotime($proposal->signature_date)), 0, 1);
        }

        self::render_footer($pdf, 'Proposal #' . $proposal->proposal_number . '  |  ' . $settings['business_name']);
        $pdf->Output('proposal-' . $proposal->proposal_number . '.pdf', 'I');
        exit;
    }

    // ================================================================
    // INVOICE
    // ================================================================
    public static function generate_invoice($invoice, $client, $project = null) {
        if (!self::init_pdf()) { self::render_fallback('Invoice #' . $invoice->invoice_number, ''); return; }
        while (ob_get_level()) ob_end_clean();

        $settings = self::get_business_settings();
        $items = is_array($invoice->items) ? $invoice->items : (json_decode($invoice->items, true) ?: array());

        $pdf = self::create_pdf($settings, 'Invoice ' . $invoice->invoice_number);
        $pdf->AddPage();
        $w = $pdf->GetPageWidth();
        $pc = FS_PDF::hexToRGB($settings['primary_color']);

        self::render_header($pdf, $settings, 'INVOICE', $invoice->invoice_number);

        // Invoice meta right side
        $detail_x = 20 + $w * 0.55;
        $detail_w = $w * 0.45;
        $pdf->SetXY($detail_x, max($pdf->GetY() - 10, 50));
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
        $half = $detail_w / 2;
        $pdf->Cell($half, 5, 'Date:', 0, 0, 'R'); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($half, 5, gmdate('M j, Y', strtotime($invoice->invoice_date ?? $invoice->issue_date ?? 'now')), 0, 1, 'R');
        $pdf->SetX($detail_x); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($half, 5, 'Due:', 0, 0, 'R'); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($half, 5, gmdate('M j, Y', strtotime($invoice->due_date)), 0, 1, 'R');
        if ($invoice->status !== 'draft') { $pdf->SetX($detail_x + $detail_w - 25); self::render_status_badge($pdf, $invoice->status); }

        $pdf->SetY(max($pdf->GetY() + 3, 75));
        self::render_client_block($pdf, $client, 'BILL TO:');
        $pdf->Ln(5);

        // Project name
        if (!empty($project) && !empty($project->name)) {
            $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
            $pdf->Cell($w, 4, 'PROJECT', 0, 1, 'L');
            $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w, 6, $project->name, 0, 1, 'L');
            $pdf->Ln(4);
        }

        // Line items table
        $pdf->SetFillColor(243,244,246); $pdf->SetDrawColor($pc[0],$pc[1],$pc[2]);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $wd = $w*0.50; $wr = $w*0.15; $wq = $w*0.15; $wa = $w*0.20;
        $pdf->Cell($wd, 8, 'Description', 'B', 0, 'L', true);
        $pdf->Cell($wr, 8, 'Rate', 'B', 0, 'R', true);
        $pdf->Cell($wq, 8, 'Qty/Hrs', 'B', 0, 'R', true);
        $pdf->Cell($wa, 8, 'Amount', 'B', 1, 'R', true);

        $pdf->SetDrawColor(229,231,235); $pdf->SetFont('Helvetica','',9);
        foreach ($items as $item) {
            $desc = $item['description'] ?? $item['name'] ?? 'Item';
            $rate = floatval($item['rate'] ?? $item['unit_price'] ?? 0);
            $qty = floatval($item['quantity'] ?? $item['hours'] ?? 1);
            $amt = floatval($item['total'] ?? $item['amount'] ?? ($rate * $qty));
            $pdf->SetTextColor(0,0,0); $pdf->Cell($wd, 7, $desc, 'B', 0, 'L');
            $pdf->SetTextColor(100,100,100); $pdf->Cell($wr, 7, '$'.number_format($rate,2), 'B', 0, 'R');
            $pdf->Cell($wq, 7, number_format($qty,2), 'B', 0, 'R');
            $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($wa, 7, '$'.number_format($amt,2), 'B', 1, 'R');
            $pdf->SetFont('Helvetica','',9);
        }
        $pdf->Ln(3);

        // Totals
        $lw = $wd + $wr; $vl = $wq; $vw = $wa;
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($lw,5,'',0,0); $pdf->Cell($vl,5,'Subtotal:',0,0,'R');
        $pdf->SetTextColor(0,0,0); $pdf->Cell($vw,5,'$'.number_format($invoice->subtotal ?? $invoice->total,2),0,1,'R');

        if (!empty($invoice->tax_amount) && $invoice->tax_amount > 0) {
            $pdf->SetTextColor(100,100,100); $pdf->Cell($lw,5,'',0,0);
            $tl = 'Tax'; if (!empty($invoice->tax_rate)) $tl .= ' ('.number_format($invoice->tax_rate,1).'%)';
            $pdf->Cell($vl,5,$tl.':',0,0,'R'); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($vw,5,'$'.number_format($invoice->tax_amount,2),0,1,'R');
        }
        if (!empty($invoice->discount_amount) && $invoice->discount_amount > 0) {
            $pdf->SetTextColor(100,100,100); $pdf->Cell($lw,5,'',0,0);
            $pdf->Cell($vl,5,'Discount:',0,0,'R'); $pdf->SetTextColor(5,150,105);
            $pdf->Cell($vw,5,'-$'.number_format($invoice->discount_amount,2),0,1,'R');
        }

        // Total line
        $y = $pdf->GetY(); $pdf->SetDrawColor(51,51,51); $pdf->Line(20+$lw,$y,20+$w,$y);
        $pdf->SetFont('Helvetica','B',12); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($lw,8,'',0,0); $pdf->Cell($vl,8,'Total:',0,0,'R');
        $pdf->SetFont('Helvetica','B',14); $pdf->Cell($vw,8,'$'.number_format($invoice->total,2),0,1,'R');

        if ($invoice->amount_paid > 0) {
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(5,150,105);
            $pdf->Cell($lw,5,'',0,0); $pdf->Cell($vl,5,'Paid:',0,0,'R');
            $pdf->Cell($vw,5,'-$'.number_format($invoice->amount_paid,2),0,1,'R');
            $bal = $invoice->total - $invoice->amount_paid;
            $pdf->SetFont('Helvetica','B',12); $pdf->SetTextColor($pc[0],$pc[1],$pc[2]);
            $pdf->Cell($lw,7,'',0,0); $pdf->Cell($vl,7,'Balance Due:',0,0,'R');
            $pdf->SetFont('Helvetica','B',14); $pdf->Cell($vw,7,'$'.number_format($bal,2),0,1,'R');
        }

        // Payment instructions
        if (!empty($settings['payment_instructions'])) {
            $pdf->Ln(8); $pdf->SetFillColor(249,249,249);
            $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w, 6, 'Payment Instructions', 0, 1, 'L', true);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->MultiCell($w, 4, wp_strip_all_tags($settings['payment_instructions']), 0, 'L', true);
        }

        // Notes
        if (!empty($invoice->notes)) {
            $pdf->Ln(5); $pdf->SetFillColor(249,249,249);
            $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w, 6, 'Notes', 0, 1, 'L', true);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->MultiCell($w, 4, $invoice->notes, 0, 'L', true);
        }

        self::render_footer($pdf, 'Thank you for your business!');
        $pdf->Output('invoice-' . $invoice->invoice_number . '.pdf', 'I');
        exit;
    }

    // ================================================================
    // CONTRACT
    // ================================================================
    public static function generate_contract($contract, $client) {
        if (!self::init_pdf()) { self::render_fallback($contract->title, 'Contract #' . ($contract->contract_number ?? '')); return; }
        while (ob_get_level()) ob_end_clean();

        $settings = self::get_business_settings();
        $services = is_array($contract->services) ? $contract->services : (json_decode($contract->services, true) ?: array());
        $enabled_sections = is_array($contract->enabled_sections) ? $contract->enabled_sections : (json_decode($contract->enabled_sections, true) ?: array());

        $pdf = self::create_pdf($settings, 'Contract ' . ($contract->contract_number ?? ''));
        $pdf->AddPage();
        $w = $pdf->GetPageWidth();

        self::render_header($pdf, $settings, 'CONTRACT', $contract->contract_number ?? '');
        if (!empty($contract->status) && $contract->status !== 'draft') { self::render_status_badge($pdf, $contract->status); }
        $pdf->Ln(5);

        // Title
        $pdf->SetFont('Helvetica','B',16); $pdf->SetTextColor(17,17,17);
        $pdf->MultiCell($w, 7, $contract->title, 0, 'L');
        $dates = array();
        if (!empty($contract->start_date) && strtotime($contract->start_date) > 0) $dates[] = 'Start: ' . gmdate('F j, Y', strtotime($contract->start_date));
        if (!empty($contract->end_date) && strtotime($contract->end_date) > 0) $dates[] = 'End: ' . gmdate('F j, Y', strtotime($contract->end_date));
        if (!empty($dates)) { $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100); $pdf->Cell(0,5,implode('  |  ',$dates),0,1); }
        $pdf->Ln(5);

        // Parties
        self::render_section_heading($pdf, 'Parties', $settings['primary_color']);
        $col_w = ($w - 5) / 2;
        $y_start = $pdf->GetY();
        // Client - use contact override if set
        $dc = FS_Contract::get_display_contact($contract, $client);
        $pdf->SetFillColor(249,249,249);
        $pdf->SetFont('Helvetica','B',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($col_w, 5, 'CLIENT', 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($col_w, 5, $dc->company_name ?: $dc->name, 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        if (!empty($dc->company_name) && !empty($dc->name)) $pdf->Cell($col_w, 4, $dc->name, 0, 2, 'L', true);
        if (!empty($dc->email)) $pdf->Cell($col_w, 4, $dc->email, 0, 2, 'L', true);
        if (!empty($dc->phone)) $pdf->Cell($col_w, 4, $dc->phone, 0, 2, 'L', true);
        if ($client && !empty($client->address)) $pdf->Cell($col_w, 4, $client->address, 0, 2, 'L', true);
        $y_left = $pdf->GetY();
        // Contractor
        $pdf->SetXY(20 + $col_w + 5, $y_start);
        $pdf->SetFont('Helvetica','B',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($col_w, 5, 'CONTRACTOR', 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($col_w, 5, $settings['business_name'], 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        if (!empty($settings['business_email'])) $pdf->Cell($col_w, 4, $settings['business_email'], 0, 2, 'L', true);
        if (!empty($settings['business_phone'])) $pdf->Cell($col_w, 4, $settings['business_phone'], 0, 2, 'L', true);
        if (!empty($settings['business_address'])) $pdf->Cell($col_w, 4, $settings['business_address'], 0, 2, 'L', true);
        $loc = array_filter(array($settings['business_city'], $settings['business_state'], $settings['business_zip']));
        if (!empty($loc)) $pdf->Cell($col_w, 4, implode(', ', $loc), 0, 2, 'L', true);
        $pdf->SetY(max($y_left, $pdf->GetY()) + 5);

        // Services
        if (!empty($services)) {
            self::render_section_heading($pdf, 'Services', $settings['primary_color']);
            $pdf->SetDrawColor(238,238,238);
            foreach ($services as $svc) {
                $name = $svc['name'] ?? 'Service';
                $amt = floatval($svc['total'] ?? $svc['amount'] ?? 0);
                $desc = $svc['description'] ?? '';
                $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
                $pdf->Cell($w*0.7, 6, $name, 0, 0);
                $pdf->Cell($w*0.3, 6, '$'.number_format($amt,2), 0, 1, 'R');
                if (!empty($desc)) { $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100); $pdf->MultiCell($w, 3.5, $desc, 0, 'L'); }
                $y = $pdf->GetY(); $pdf->Line(20,$y+1,20+$w,$y+1); $pdf->Ln(3);
            }
            // Total
            $y = $pdf->GetY(); $pdf->SetDrawColor(51,51,51); $pdf->Line(20,$y,20+$w,$y);
            $pdf->SetFont('Helvetica','B',11); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w*0.7, 7, 'Total:', 0, 0);
            $pdf->SetFont('Helvetica','B',14);
            $pdf->Cell($w*0.3, 7, '$'.number_format($contract->total_amount ?? 0, 2), 0, 1, 'R');
            $pdf->Ln(3);
        }

        // Terms and Conditions (rich HTML from contract sections)
        $terms_html = '';
        if (!empty($contract->terms_content)) {
            $terms_html = $contract->terms_content;
        } elseif (!empty($enabled_sections)) {
            if (class_exists('FS_Contract_Section') && method_exists('FS_Contract_Section', 'build_terms_html')) {
                $terms_html = FS_Contract_Section::build_terms_html($enabled_sections, array(
                    'client_name' => $client->company_name ?: $client->name,
                    'designer_name' => $settings['business_name'],
                    'project_name' => $contract->title,
                ));
            }
        }
        if (!empty($terms_html)) {
            self::render_section_heading($pdf, 'Terms and Conditions', $settings['primary_color']);
            $pdf->SetFont('Helvetica', '', 8);
            $pdf->SetTextColor(68, 68, 68);
            $pdf->WriteHTML($terms_html, $w);
            $pdf->Ln(3);
        }

        // Notes
        if (!empty($contract->notes)) {
            self::render_section_heading($pdf, 'Notes', $settings['primary_color']);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->MultiCell($w, 4, $contract->notes, 0, 'L');
            $pdf->Ln(3);
        }

        // Signatures
        self::render_section_heading($pdf, 'Signatures', $settings['primary_color']);
        $sig_w = ($w - 10) / 2;
        $y_sig = $pdf->GetY();

        // Contractor signature
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(0,0,0);
        if (!empty($contract->signature_freelancer)) {
            $sig_file = self::signature_to_temp_file($contract->signature_freelancer);
            if ($sig_file) { $pdf->Image($sig_file, 20, $y_sig, 50, 0); wp_delete_file($sig_file); }
        }
        $pdf->SetY($y_sig + 18);
        $pdf->SetDrawColor(200,200,200); $pdf->Line(20, $pdf->GetY(), 20+$sig_w, $pdf->GetY()); $pdf->Ln(2);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($sig_w, 4, $contract->signature_freelancer_name ?? $settings['business_name'], 0, 1);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($sig_w, 4, 'Contractor', 0, 1);
        if (!empty($contract->signature_freelancer_date)) $pdf->Cell($sig_w, 4, gmdate('F j, Y', strtotime($contract->signature_freelancer_date)), 0, 1);
        $y_end_left = $pdf->GetY();

        // Client signature
        $pdf->SetXY(20 + $sig_w + 10, $y_sig);
        if (!empty($contract->signature_client)) {
            $sig_file = self::signature_to_temp_file($contract->signature_client);
            if ($sig_file) { $pdf->Image($sig_file, 20+$sig_w+10, $y_sig, 50, 0); wp_delete_file($sig_file); }
        }
        $pdf->SetY($y_sig + 18);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->Line(20+$sig_w+10, $pdf->GetY(), 20+$w, $pdf->GetY()); $pdf->Ln(2);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($sig_w, 4, $contract->signature_client_name ?? '', 0, 1);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($sig_w, 4, $client->company_name ?: 'Client', 0, 1);
        if (!empty($contract->signed_at ?? $contract->client_signed_at ?? '')) {
            $pdf->SetX(20 + $sig_w + 10);
            $pdf->Cell($sig_w, 4, gmdate('F j, Y', strtotime($contract->signed_at ?? $contract->client_signed_at)), 0, 1);
        }

        $pdf->SetY(max($y_end_left, $pdf->GetY()));
        self::render_footer($pdf, 'Contract #' . ($contract->contract_number ?? '') . '  |  Generated by Freelance Studio');
        $pdf->Output('contract-' . ($contract->contract_number ?? 'draft') . '.pdf', 'I');
        exit;
    }

    private static function fallback_print_contract($contract, $client) {
        self::render_fallback($contract->title, 'Contract #' . ($contract->contract_number ?? ''));
    }

    // ================================================================
    // INCOME SUMMARY REPORT
    // ================================================================
    public function generate_income_summary_report($year, $clients_data, $settings_arg = array()) {
        if (!self::init_pdf()) return false;

        $settings = self::get_business_settings();
        $pdf = self::create_pdf($settings, 'Income Summary Report - ' . $year);
        $pdf->SetMargins(15, 15, 15, 15);
        $pdf->AddPage();
        $w = $pdf->GetPageWidth();

        // Logo
        $logo_path = self::image_to_path($settings['business_logo']);
        if ($logo_path) { $pdf->Image($logo_path, 15, 15, 40, 0); $pdf->SetY(35); }

        // Header
        $pdf->SetFont('Helvetica','B',11); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($w*0.5, 5, $settings['business_name'], 0, 0);
        $pdf->SetFont('Helvetica','B',16);
        $pdf->Cell($w*0.5, 5, 'Income Summary Report', 0, 1, 'R');
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
        if (!empty($settings['business_address'])) { $pdf->Cell($w*0.5, 4, $settings['business_address'], 0, 0); }
        else { $pdf->Cell($w*0.5, 4, '', 0, 0); }
        $pdf->Cell($w*0.5, 4, 'Tax Year ' . $year, 0, 1, 'R');
        $pdf->Ln(5);

        $total_income = array_sum(array_column($clients_data, 'total_received'));

        // Summary box
        $pdf->SetFillColor(224, 247, 243);
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($w*0.6, 7, 'Number of Clients:', 0, 0, 'L', true);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($w*0.4, 7, (string)count($clients_data), 0, 1, 'R', true);
        $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($w*0.6, 8, 'Total Income Received:', 0, 0, 'L', true);
        $pdf->SetFont('Helvetica','B',13); $pdf->SetTextColor(43,168,145);
        $pdf->Cell($w*0.4, 8, '$' . number_format($total_income, 2), 0, 1, 'R', true);
        $pdf->Ln(5);

        // Client table header
        $pdf->SetFillColor(245,247,250); $pdf->SetDrawColor(226,230,236);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $wc = $w*0.40; $wa = $w*0.35; $wm = $w*0.25;
        $pdf->Cell($wc, 7, 'Client', 'B', 0, 'L', true);
        $pdf->Cell($wa, 7, 'Address', 'B', 0, 'L', true);
        $pdf->Cell($wm, 7, 'Amount Received', 'B', 1, 'R', true);

        // Client rows
        $pdf->SetFont('Helvetica','',9);
        foreach ($clients_data as $cd) {
            $pdf->SetTextColor(0,0,0); $pdf->SetFont('Helvetica','B',9);
            $name = $cd['company_name'] ?: $cd['name'];
            $pdf->Cell($wc, 6, $name, 'B', 0, 'L');
            $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
            $addr_parts = array_filter(array($cd['address'] ?? '', implode(', ', array_filter(array($cd['city'] ?? '', $cd['state'] ?? '', $cd['zip'] ?? '')))));
            $pdf->Cell($wa, 6, implode(', ', $addr_parts) ?: '-', 'B', 0, 'L');
            $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(43,168,145);
            $pdf->Cell($wm, 6, '$' . number_format($cd['total_received'], 2), 'B', 1, 'R');
        }
        $pdf->Ln(8);

        // Tax note box
        $pdf->SetFillColor(240, 249, 255); $pdf->SetDrawColor(14, 165, 233);
        $pdf->SetLineWidth(0.3);
        $y_note = $pdf->GetY();
        $pdf->Rect(15, $y_note, $w, 18, 'F');
        $pdf->Line(15, $y_note, 15, $y_note + 18); // left accent
        $pdf->SetLineWidth(0.2);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(12,74,110);
        $pdf->Cell($w, 5, 'For Your Tax Records', 0, 1);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(12,74,110);
        $pdf->MultiCell($w, 3.5, 'This report summarizes all income you received from clients during ' . $year . '. Keep this for your records when preparing your tax return. If any client paid you $600 or more, they may issue you a 1099-NEC form. Consult with a tax professional for specific guidance.', 0, 'L');

        $pdf->Ln(5);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(150,150,150);
        $pdf->Cell(0, 5, 'Generated on ' . gmdate('F j, Y \a\t g:i A') . ' by Freelance Studio', 0, 1, 'C');

        // Save to file
        $upload_dir = wp_upload_dir();
        $reports_dir = $upload_dir['basedir'] . '/freelance-studio/reports';
        if (!file_exists($reports_dir)) wp_mkdir_p($reports_dir);
        $filename = 'income-summary-' . $year . '-' . gmdate('Y-m-d-His') . '.pdf';
        $filepath = $reports_dir . '/' . $filename;
        $pdf->Output($filepath, 'F');
        if (file_exists($filepath)) return $upload_dir['baseurl'] . '/freelance-studio/reports/' . $filename;
        return false;
    }

    /**
     * Save a signed contract as PDF to the uploads directory
     *
     * @param object $contract Contract object
     * @param object $client   Client object
     * @return string|false Relative path to saved PDF, or false on failure
     */
    public static function save_signed_contract_pdf($contract, $client) {
        if (!self::init_pdf()) {
            return false;
        }

        $settings = self::get_business_settings();
        $upload_dir = wp_upload_dir();
        $contracts_dir = $upload_dir['basedir'] . '/freelance-studio/contracts';
        
        if (!file_exists($contracts_dir)) {
            wp_mkdir_p($contracts_dir);
        }

        $contract_number = $contract->contract_number ?? ('CON-' . $contract->id);
        $filename = sanitize_file_name('contract-' . $contract_number . '-signed-' . gmdate('Ymd') . '.pdf');
        $filepath = $contracts_dir . '/' . $filename;

        $services = is_array($contract->services) ? $contract->services : (json_decode($contract->services, true) ?: array());
        $enabled_sections = is_array($contract->enabled_sections) ? $contract->enabled_sections : (json_decode($contract->enabled_sections, true) ?: array());

        $pdf = self::create_pdf($settings, 'Contract ' . $contract_number);
        $pdf->AddPage();
        $w = $pdf->GetPageWidth();

        self::render_header($pdf, $settings, 'CONTRACT', $contract_number);
        self::render_status_badge($pdf, 'signed');
        $pdf->Ln(5);

        // Title
        $pdf->SetFont('Helvetica','B',16); $pdf->SetTextColor(17,17,17);
        $pdf->MultiCell($w, 7, $contract->title, 0, 'L');
        $dates = array();
        if (!empty($contract->start_date) && strtotime($contract->start_date) > 0) $dates[] = 'Start: ' . gmdate('F j, Y', strtotime($contract->start_date));
        if (!empty($contract->end_date) && strtotime($contract->end_date) > 0) $dates[] = 'End: ' . gmdate('F j, Y', strtotime($contract->end_date));
        if (!empty($dates)) { $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100); $pdf->Cell(0,5,implode('  |  ',$dates),0,1); }
        $pdf->Ln(5);

        // Parties
        self::render_section_heading($pdf, 'Parties', $settings['primary_color']);
        $col_w = ($w - 5) / 2;
        $y_start = $pdf->GetY();
        $dc = FS_Contract::get_display_contact($contract, $client);
        $pdf->SetFillColor(249,249,249);
        $pdf->SetFont('Helvetica','B',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($col_w, 5, 'CLIENT', 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($col_w, 5, $dc->company_name ?: $dc->name, 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        if (!empty($dc->company_name) && !empty($dc->name)) $pdf->Cell($col_w, 4, $dc->name, 0, 2, 'L', true);
        if (!empty($dc->email)) $pdf->Cell($col_w, 4, $dc->email, 0, 2, 'L', true);
        if (!empty($dc->phone)) $pdf->Cell($col_w, 4, $dc->phone, 0, 2, 'L', true);
        if ($client && !empty($client->address)) $pdf->Cell($col_w, 4, $client->address, 0, 2, 'L', true);
        $y_left = $pdf->GetY();
        $pdf->SetXY(20 + $col_w + 5, $y_start);
        $pdf->SetFont('Helvetica','B',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($col_w, 5, 'CONTRACTOR', 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($col_w, 5, $settings['business_name'], 0, 2, 'L', true);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        if (!empty($settings['business_email'])) $pdf->Cell($col_w, 4, $settings['business_email'], 0, 2, 'L', true);
        if (!empty($settings['business_phone'])) $pdf->Cell($col_w, 4, $settings['business_phone'], 0, 2, 'L', true);
        if (!empty($settings['business_address'])) $pdf->Cell($col_w, 4, $settings['business_address'], 0, 2, 'L', true);
        $loc = array_filter(array($settings['business_city'] ?? '', $settings['business_state'] ?? '', $settings['business_zip'] ?? ''));
        if (!empty($loc)) $pdf->Cell($col_w, 4, implode(', ', $loc), 0, 2, 'L', true);
        $pdf->SetY(max($y_left, $pdf->GetY()) + 5);

        // Services (with descriptions and total)
        if (!empty($services)) {
            self::render_section_heading($pdf, 'Services', $settings['primary_color']);
            $pdf->SetDrawColor(238,238,238);
            foreach ($services as $svc) {
                $name = $svc['name'] ?? 'Service';
                $amt = floatval($svc['total'] ?? $svc['amount'] ?? 0);
                $desc = $svc['description'] ?? '';
                $pdf->SetFont('Helvetica','B',10); $pdf->SetTextColor(0,0,0);
                $pdf->Cell($w*0.7, 6, $name, 0, 0);
                $pdf->Cell($w*0.3, 6, '$'.number_format($amt,2), 0, 1, 'R');
                if (!empty($desc)) { $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100); $pdf->MultiCell($w, 3.5, $desc, 0, 'L'); }
                $y = $pdf->GetY(); $pdf->Line(20,$y+1,20+$w,$y+1); $pdf->Ln(3);
            }
            // Total
            $y = $pdf->GetY(); $pdf->SetDrawColor(51,51,51); $pdf->Line(20,$y,20+$w,$y);
            $pdf->SetFont('Helvetica','B',11); $pdf->SetTextColor(0,0,0);
            $pdf->Cell($w*0.7, 7, 'Total:', 0, 0);
            $pdf->SetFont('Helvetica','B',14);
            $pdf->Cell($w*0.3, 7, '$'.number_format($contract->total_amount ?? 0, 2), 0, 1, 'R');
            $pdf->Ln(3);
        }

        // Terms and Conditions (rich HTML from contract sections)
        $terms_html = '';
        if (!empty($contract->terms_content)) {
            $terms_html = $contract->terms_content;
        } elseif (!empty($enabled_sections)) {
            if (class_exists('FS_Contract_Section') && method_exists('FS_Contract_Section', 'build_terms_html')) {
                $terms_html = FS_Contract_Section::build_terms_html($enabled_sections, array(
                    'client_name' => $client->company_name ?: $client->name,
                    'designer_name' => $settings['business_name'],
                    'project_name' => $contract->title,
                ));
            }
        }
        if (!empty($terms_html)) {
            self::render_section_heading($pdf, 'Terms and Conditions', $settings['primary_color']);
            $pdf->SetFont('Helvetica', '', 8);
            $pdf->SetTextColor(68, 68, 68);
            $pdf->WriteHTML($terms_html, $w);
            $pdf->Ln(3);
        }

        // Notes
        if (!empty($contract->notes)) {
            self::render_section_heading($pdf, 'Notes', $settings['primary_color']);
            $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(100,100,100);
            $pdf->MultiCell($w, 4, $contract->notes, 0, 'L');
            $pdf->Ln(3);
        }

        // Signatures
        self::render_section_heading($pdf, 'Signatures', $settings['primary_color']);
        $sig_w = ($w - 10) / 2;
        $y_sig = $pdf->GetY();

        // Contractor signature
        $pdf->SetFont('Helvetica','',9); $pdf->SetTextColor(0,0,0);
        if (!empty($contract->signature_freelancer)) {
            $sig_file = self::signature_to_temp_file($contract->signature_freelancer);
            if ($sig_file) { $pdf->Image($sig_file, 20, $y_sig, 50, 0); wp_delete_file($sig_file); }
        }
        $pdf->SetY($y_sig + 18);
        $pdf->SetDrawColor(200,200,200); $pdf->Line(20, $pdf->GetY(), 20+$sig_w, $pdf->GetY()); $pdf->Ln(2);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($sig_w, 4, $contract->signature_freelancer_name ?? $settings['business_name'], 0, 1);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($sig_w, 4, 'Contractor', 0, 1);
        if (!empty($contract->signature_freelancer_date)) $pdf->Cell($sig_w, 4, gmdate('F j, Y', strtotime($contract->signature_freelancer_date)), 0, 1);
        $y_end_left = $pdf->GetY();

        // Client signature
        $pdf->SetXY(20 + $sig_w + 10, $y_sig);
        if (!empty($contract->signature_client)) {
            $sig_file = self::signature_to_temp_file($contract->signature_client);
            if ($sig_file) { $pdf->Image($sig_file, 20+$sig_w+10, $y_sig, 50, 0); wp_delete_file($sig_file); }
        }
        $pdf->SetY($y_sig + 18);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->Line(20+$sig_w+10, $pdf->GetY(), 20+$w, $pdf->GetY()); $pdf->Ln(2);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->SetFont('Helvetica','B',9); $pdf->SetTextColor(0,0,0);
        $pdf->Cell($sig_w, 4, $contract->signature_client_name ?? '', 0, 1);
        $pdf->SetX(20 + $sig_w + 10);
        $pdf->SetFont('Helvetica','',8); $pdf->SetTextColor(100,100,100);
        $pdf->Cell($sig_w, 4, $client->company_name ?: 'Client', 0, 1);
        if (!empty($contract->signature_client_date)) {
            $pdf->SetX(20 + $sig_w + 10);
            $pdf->Cell($sig_w, 4, gmdate('F j, Y', strtotime($contract->signature_client_date)), 0, 1);
        }

        $pdf->SetY(max($y_end_left, $pdf->GetY()));
        self::render_footer($pdf, 'Contract #' . $contract_number . '  |  Generated by Freelance Studio');
        $pdf->Output($filepath, 'F');
        
        if (file_exists($filepath)) {
            return 'freelance-studio/contracts/' . $filename;
        }
        return false;
    }
}
