<?php
/**
 * Tax Calculator Model
 * Handles tax calculations for quarterly estimates and reporting
 *
 * @package Freelance_Studio
 */

class FS_Tax_Calculator {
    
    /**
     * Self-employment tax rate (Social Security + Medicare)
     */
    const SELF_EMPLOYMENT_TAX_RATE = 15.3;
    
    /**
     * Calculate comprehensive tax information
     * 
     * @param float  $income          Total 1099 income
     * @param string $state           State code
     * @param float  $federal_bracket Federal tax bracket percentage
     * @param float  $expenses        Total deductible expenses
     * @param float  $annual_deductions Total annual estimated deductions
     * @return array Tax calculation results
     */
    public static function calculate_tax_liability($income, $state, $federal_bracket, $expenses = 0, $annual_deductions = 0) {
        $state_rate = FS_Tax_Rates::get_state_rate($state);
        
        // Calculate total deductions (actual expenses + annual deductions)
        $total_deductions = $expenses + $annual_deductions;
        
        // Calculate net income after all deductions
        $net_income = $income - $total_deductions;
        if ($net_income < 0) {
            $net_income = 0;
        }
        
        // Calculate taxes
        $tax_breakdown = self::calculate_taxes($net_income, $federal_bracket, $state_rate);
        
        // Get quarterly payment information
        $quarterly_info = self::get_quarterly_payment_info($tax_breakdown['total_tax']);
        
        return array(
            'gross_income' => $income,
            'expenses' => $expenses,
            'annual_deductions' => $annual_deductions,
            'total_deductions' => $total_deductions,
            'net_income' => $net_income,
            'tax_breakdown' => $tax_breakdown,
            'quarterly' => $quarterly_info,
            'state_rate' => $state_rate,
            'federal_bracket' => $federal_bracket
        );
    }
    
    /**
     * Calculate taxes on income
     *
     * @param float $income          Net income
     * @param float $federal_bracket Federal tax bracket %
     * @param float $state_rate      State tax rate %
     * @return array
     */
    private static function calculate_taxes($income, $federal_bracket, $state_rate) {
        // Self-employment tax (15.3%)
        $self_employment_tax = $income * (self::SELF_EMPLOYMENT_TAX_RATE / 100);
        
        // Deductible portion of SE tax (50%)
        $se_tax_deduction = $self_employment_tax * 0.5;
        
        // Taxable income after SE tax deduction
        $taxable_income = $income - $se_tax_deduction;
        if ($taxable_income < 0) {
            $taxable_income = 0;
        }
        
        // Federal income tax
        $federal_tax = $taxable_income * ($federal_bracket / 100);
        
        // State income tax
        $state_tax = $taxable_income * ($state_rate / 100);
        
        // Total tax liability
        $total_tax = $self_employment_tax + $federal_tax + $state_tax;
        
        return array(
            'self_employment_tax' => round($self_employment_tax, 2),
            'se_tax_deduction' => round($se_tax_deduction, 2),
            'taxable_income' => round($taxable_income, 2),
            'federal_tax' => round($federal_tax, 2),
            'state_tax' => round($state_tax, 2),
            'total_tax' => round($total_tax, 2),
            'effective_rate' => $income > 0 ? round(($total_tax / $income) * 100, 1) : 0
        );
    }
    
    /**
     * Get quarterly payment information
     *
     * @param float $annual_tax_liability Annual tax amount
     * @return array
     */
    private static function get_quarterly_payment_info($annual_tax_liability) {
        $current_year = gmdate('Y');
        $current_date = current_time('Y-m-d');
        
        // Quarterly payment deadlines
        $deadlines = array(
            'Q1' => array(
                'date' => $current_year . '-04-15',
                'label' => __('Q1 (Jan-Mar)', 'freelance-studio'),
                'period' => 'January 1 - March 31'
            ),
            'Q2' => array(
                'date' => $current_year . '-06-15',
                'label' => __('Q2 (Apr-May)', 'freelance-studio'),
                'period' => 'April 1 - May 31'
            ),
            'Q3' => array(
                'date' => $current_year . '-09-15',
                'label' => __('Q3 (Jun-Aug)', 'freelance-studio'),
                'period' => 'June 1 - August 31'
            ),
            'Q4' => array(
                'date' => ($current_year + 1) . '-01-15',
                'label' => __('Q4 (Sep-Dec)', 'freelance-studio'),
                'period' => 'September 1 - December 31'
            )
        );
        
        // Recommended quarterly payment (divide by 4)
        $recommended_quarterly = round($annual_tax_liability / 4, 2);
        
        // Find next payment deadline
        $next_deadline = null;
        $next_quarter = null;
        foreach ($deadlines as $quarter => $info) {
            if ($current_date < $info['date']) {
                $next_deadline = $info['date'];
                $next_quarter = $quarter;
                break;
            }
        }
        
        // If no upcoming deadline this year, use Q1 next year
        if (!$next_deadline) {
            $next_year = $current_year + 1;
            $next_deadline = $next_year . '-04-15';
            $next_quarter = 'Q1';
            // Update deadlines for next year
            $deadlines = array(
                'Q1' => array(
                    'date' => $next_year . '-04-15',
                    'label' => __('Q1 (Jan-Mar)', 'freelance-studio'),
                    'period' => 'January 1 - March 31'
                )
            );
        }
        
        // Calculate days until next deadline
        $days_until = floor((strtotime($next_deadline) - strtotime($current_date)) / 86400);
        
        return array(
            'recommended_quarterly' => $recommended_quarterly,
            'next_deadline' => $next_deadline,
            'next_deadline_formatted' => gmdate('F j, Y', strtotime($next_deadline)),
            'next_quarter' => $next_quarter,
            'days_until' => max(0, $days_until),
            'deadlines' => $deadlines,
            'annual_liability' => $annual_tax_liability
        );
    }
    
    /**
     * Get quarterly payments made
     *
     * @param int $year Year
     * @return array
     */
    public static function get_quarterly_payments_made($year = null) {
        global $wpdb;
        
        if (!$year) {
            $year = gmdate('Y');
        }
        
        $table = $wpdb->prefix . 'fs_quarterly_tax_payments';
        $user_id = get_current_user_id();
        
        $payments = $wpdb->get_results($wpdb->prepare(
            "SELECT quarter, actual_payment, payment_date, notes 
             FROM {$table} 
             WHERE user_id = %d AND year = %d 
             ORDER BY quarter ASC",
            $user_id,
            $year
        ));
        
        $total_paid = 0;
        $payments_by_quarter = array(
            'Q1' => 0,
            'Q2' => 0,
            'Q3' => 0,
            'Q4' => 0
        );
        
        foreach ($payments as $payment) {
            $amount = floatval($payment->actual_payment);
            $total_paid += $amount;
            $payments_by_quarter[$payment->quarter] = $amount;
        }
        
        return array(
            'total_paid' => $total_paid,
            'by_quarter' => $payments_by_quarter,
            'payments' => $payments
        );
    }
    
    /**
     * Record a quarterly tax payment
     *
     * @param int    $year    Year
     * @param string $quarter Quarter (Q1, Q2, Q3, Q4)
     * @param float  $amount  Payment amount
     * @param string $date    Payment date
     * @param string $notes   Optional notes
     * @return bool
     */
    public static function record_payment($year, $quarter, $amount, $date = null, $notes = '') {
        global $wpdb;
        
        $table = $wpdb->prefix . 'fs_quarterly_tax_payments';
        $user_id = get_current_user_id();
        
        // Check if record exists
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT id FROM {$table} WHERE user_id = %d AND year = %d AND quarter = %s",
            $user_id,
            $year,
            $quarter
        ));
        
        $data = array(
            'user_id' => $user_id,
            'year' => $year,
            'quarter' => $quarter,
            'actual_payment' => floatval($amount),
            'payment_date' => $date ?: current_time('Y-m-d'),
            'notes' => sanitize_textarea_field($notes)
        );
        
        if ($existing) {
            return $wpdb->update($table, $data, array('id' => $existing)) !== false;
        } else {
            return $wpdb->insert($table, $data) !== false;
        }
    }
    
    /**
     * Calculate YTD income (invoices + other income)
     *
     * @param int $year Year
     * @return float
     */
    public static function get_ytd_income($year = null) {
        if (!$year) {
            $year = gmdate('Y');
        }
        
        $start_date = $year . '-01-01';
        $end_date = $year . '-12-31';
        
        // Get invoice revenue
        $invoice_income = FS_Invoice::get_total_revenue($start_date, $end_date);
        
        // Get other income (manual income entries)
        $other_income = FS_Manual_Income::get_total($start_date, $end_date);
        
        return $invoice_income + $other_income;
    }
    
    /**
     * Calculate YTD expenses
     *
     * @param int $year Year
     * @return float
     */
    public static function get_ytd_expenses($year = null) {
        if (!$year) {
            $year = gmdate('Y');
        }
        
        $start_date = $year . '-01-01';
        $end_date = $year . '-12-31';
        
        return FS_Expense::get_total($start_date, $end_date);
    }
    
    /**
     * Get total annual deductions for a year
     *
     * @param int $year Year
     * @return float
     */
    public static function get_annual_deductions($year = null) {
        if (!$year) {
            $year = gmdate('Y');
        }
        
        return FS_Annual_Deduction::get_total($year);
    }
    
    /**
     * Get tax insights and recommendations
     *
     * @param array $tax_data     Tax calculation data
     * @param array $payments_made Payments made data
     * @return array
     */
    public static function get_tax_insights($tax_data, $payments_made) {
        $insights = array();
        
        $annual_liability = $tax_data['tax_breakdown']['total_tax'];
        $remaining = $annual_liability - $payments_made['total_paid'];
        $days_until = $tax_data['quarterly']['days_until'];
        
        // Payment status insight
        if ($remaining > 0) {
            if ($days_until < 14) {
                $insights[] = array(
                    'type' => 'warning',
                    'icon' => '⚠️',
                    'title' => __('Payment Due Soon', 'freelance-studio'),
                    'message' => sprintf(
                        /* translators: 1. number of days, 2. estimated amount */
                        __('Quarterly payment due in %1$d days. Remaining liability: $%2$s', 'freelance-studio'),
                        $days_until,
                        number_format($remaining, 2)
                    )
                );
            } elseif ($days_until < 30) {
                $insights[] = array(
                    'type' => 'info',
                    'icon' => '📅',
                    'title' => __('Upcoming Payment', 'freelance-studio'),
                    'message' => sprintf(
                        /* translators: 1. number of days, 2. estimated amount */
                        __('Next quarterly payment due in %1$d days. Estimated: $%2$s', 'freelance-studio'),
                        $days_until,
                        number_format($tax_data['quarterly']['recommended_quarterly'], 2)
                    )
                );
            }
        } else {
            $insights[] = array(
                'type' => 'success',
                'icon' => '✅',
                'title' => __('On Track', 'freelance-studio'),
                'message' => __('You\'re ahead on your estimated tax payments!', 'freelance-studio')
            );
        }
        
        // Monthly savings recommendation
        $months_remaining = 12 - gmdate('n') + 1;
        if ($remaining > 0 && $months_remaining > 0) {
            $monthly_savings = $remaining / $months_remaining;
            $insights[] = array(
                'type' => 'tip',
                'icon' => '💰',
                'title' => __('Savings Goal', 'freelance-studio'),
                'message' => sprintf(
                    /* translators: 1. date/time */
                    __('Set aside approximately $%s per month for remaining taxes.', 'freelance-studio'),
                    number_format($monthly_savings, 2)
                )
            );
        }
        
        // Effective tax rate insight
        if ($tax_data['tax_breakdown']['effective_rate'] > 0) {
            $insights[] = array(
                'type' => 'info',
                'icon' => '📊',
                'title' => __('Effective Tax Rate', 'freelance-studio'),
                'message' => sprintf(
                    /* translators: 1. date/time */
                    __('Your effective tax rate is %s%% of gross income.', 'freelance-studio'),
                    $tax_data['tax_breakdown']['effective_rate']
                )
            );
        }
        
        // SE tax deduction reminder
        if ($tax_data['tax_breakdown']['se_tax_deduction'] > 0) {
            $insights[] = array(
                'type' => 'tip',
                'icon' => '📝',
                'title' => __('Deduction Reminder', 'freelance-studio'),
                'message' => sprintf(
                    /* translators: 1. amount */
                    __('Remember: You can deduct $%s (50%% of SE tax) on your return.', 'freelance-studio'),
                    number_format($tax_data['tax_breakdown']['se_tax_deduction'], 2)
                )
            );
        }
        
        return $insights;
    }
}
