<?php
namespace ComptaFlowUK\Admin\Screens;

use ComptaFlowUK\Services\InvoiceService;
use ComptaFlowUK\Services\ClientService;
use ComptaFlowUK\Services\JournalEntryGenerator;
use ComptaFlowUK\Services\DB;

defined('ABSPATH') || exit;

class InvoicesScreen {

    public static function render(): void {
        if (!current_user_can('manage_options')) {
            wp_die(esc_html__('You do not have sufficient permissions.', 'comptaflow-uk-by-meetempo'));
        }

        self::handleActions();

        $action = isset($_GET['action']) ? sanitize_key($_GET['action']) : 'list';

        echo '<div class="wrap">';
        echo '<h1 class="wp-heading-inline">' . esc_html__('Invoices', 'comptaflow-uk-by-meetempo') . '</h1>';

        if ($action === 'list') {
            echo '<a href="?page=comptaflow-uk-invoices&action=new" class="page-title-action">' . esc_html__('New Invoice', 'comptaflow-uk-by-meetempo') . '</a>';
        }

        settings_errors('comptaflow_uk_invoices');

        if ($action === 'new' || $action === 'edit') {
            self::renderForm($action);
        } else {
            self::renderList();
        }

        echo '</div>';
    }

    private static function handleActions(): void {
        $get_action = isset($_GET['action']) ? sanitize_key($_GET['action']) : '';

        if ($get_action === 'delete' && isset($_GET['id'])) {
            $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
            if (wp_verify_nonce($nonce, 'comptaflow_uk_delete_invoice')) {
                InvoiceService::delete(absint($_GET['id']));
                add_settings_error('comptaflow_uk_invoices', 'deleted', __('Invoice deleted.', 'comptaflow-uk-by-meetempo'), 'updated');
            }
            return;
        }

        if ($get_action === 'mark_sent' && isset($_GET['id'])) {
            $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
            if (wp_verify_nonce($nonce, 'comptaflow_uk_invoice_action')) {
                InvoiceService::markAsSent(absint($_GET['id']));
                add_settings_error('comptaflow_uk_invoices', 'sent', __('Invoice marked as sent.', 'comptaflow-uk-by-meetempo'), 'updated');
            }
            return;
        }

        if ($get_action === 'mark_paid' && isset($_GET['id'])) {
            $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
            if (wp_verify_nonce($nonce, 'comptaflow_uk_invoice_action')) {
                InvoiceService::markAsPaid(absint($_GET['id']));
                add_settings_error('comptaflow_uk_invoices', 'paid', __('Invoice marked as paid. Payment entry generated.', 'comptaflow-uk-by-meetempo'), 'updated');
            }
            return;
        }

        if ($get_action === 'cancel' && isset($_GET['id'])) {
            $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
            if (wp_verify_nonce($nonce, 'comptaflow_uk_invoice_action')) {
                InvoiceService::markAsCancelled(absint($_GET['id']));
                add_settings_error('comptaflow_uk_invoices', 'cancelled', __('Invoice cancelled.', 'comptaflow-uk-by-meetempo'), 'updated');
            }
            return;
        }

        if (!isset($_POST['_wpnonce'])) {
            return;
        }

        $nonce = sanitize_text_field(wp_unslash($_POST['_wpnonce']));
        if (!wp_verify_nonce($nonce, 'comptaflow_uk_invoice_save')) {
            return;
        }

        $data = [
            'client_id' => isset($_POST['client_id']) ? absint($_POST['client_id']) : null,
            'issue_date' => isset($_POST['issue_date']) ? sanitize_text_field(wp_unslash($_POST['issue_date'])) : gmdate('Y-m-d'),
            'due_date' => isset($_POST['due_date']) ? sanitize_text_field(wp_unslash($_POST['due_date'])) : '',
            'payment_terms' => isset($_POST['payment_terms']) ? absint($_POST['payment_terms']) : 30,
            'currency' => 'GBP',
            'notes' => isset($_POST['notes']) ? sanitize_textarea_field(wp_unslash($_POST['notes'])) : '',
            'terms' => isset($_POST['terms']) ? sanitize_textarea_field(wp_unslash($_POST['terms'])) : '',
            'payment_instructions' => isset($_POST['payment_instructions']) ? sanitize_textarea_field(wp_unslash($_POST['payment_instructions'])) : '',
            'status' => isset($_POST['status']) ? sanitize_text_field(wp_unslash($_POST['status'])) : 'DRAFT',
        ];

        $lines = self::parseLines();

        $id = isset($_POST['invoice_id']) ? absint($_POST['invoice_id']) : 0;
        if ($id) {
            InvoiceService::update($id, $data, $lines);
            add_settings_error('comptaflow_uk_invoices', 'updated', __('Invoice updated.', 'comptaflow-uk-by-meetempo'), 'updated');
        } else {
            $new_id = InvoiceService::create($data, $lines);
            $invoice = InvoiceService::getById($new_id);
            $saved_lines = InvoiceService::getLines($new_id);
            JournalEntryGenerator::generateInvoiceEntries($invoice, $saved_lines);
            add_settings_error('comptaflow_uk_invoices', 'created', __('Invoice created. Journal entries generated.', 'comptaflow-uk-by-meetempo'), 'updated');
        }
    }

    // phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce verified in handleActions() before calling this method
    private static function parseLines(): array {
        $lines = [];
        if (!isset($_POST['line_description']) || !is_array($_POST['line_description'])) {
            return $lines;
        }

        $descriptions = array_map('sanitize_text_field', wp_unslash($_POST['line_description']));
        $quantities = isset($_POST['line_quantity']) ? array_map('floatval', wp_unslash($_POST['line_quantity'])) : [];
        $prices = isset($_POST['line_unit_price']) ? array_map('floatval', wp_unslash($_POST['line_unit_price'])) : [];
        $vat_rates = isset($_POST['line_vat_rate']) ? array_map('floatval', wp_unslash($_POST['line_vat_rate'])) : [];
        $vat_codes = isset($_POST['line_vat_code']) ? array_map('sanitize_text_field', wp_unslash($_POST['line_vat_code'])) : [];
        $account_codes = isset($_POST['line_account_code']) ? array_map('sanitize_text_field', wp_unslash($_POST['line_account_code'])) : [];

        foreach ($descriptions as $i => $desc) {
            if (empty($desc)) {
                continue;
            }
            $lines[] = [
                'description' => $desc,
                'quantity' => $quantities[$i] ?? 1,
                'unit_price' => $prices[$i] ?? 0,
                'vat_rate' => $vat_rates[$i] ?? 20,
                'vat_code' => $vat_codes[$i] ?? 'GB-20',
                'account_code' => $account_codes[$i] ?? '4010',
            ];
        }

        return $lines;
    }
    // phpcs:enable WordPress.Security.NonceVerification.Missing

    private static function renderForm(string $action): void {
        $invoice = [];
        $lines = [];
        if ($action === 'edit' && isset($_GET['id'])) {
            $invoice = InvoiceService::getById(absint($_GET['id']));
            $lines = InvoiceService::getLines(absint($_GET['id']));
        }

        $clients = ClientService::getAll(0, '', 200, 0);
        $vat_rates = DB::getActiveVATRates('GB');
        if (empty($vat_rates)) {
            $vat_rates = [
                ['rate_value' => 20.00, 'rate_code' => 'GB-20', 'rate_name' => 'Standard 20%'],
                ['rate_value' => 5.00, 'rate_code' => 'GB-5', 'rate_name' => 'Reduced 5%'],
                ['rate_value' => 0.00, 'rate_code' => 'GB-0', 'rate_name' => 'Zero 0%'],
            ];
        }

        echo '<h2>' . ($action === 'edit' ? esc_html__('Edit Invoice', 'comptaflow-uk-by-meetempo') : esc_html__('New Invoice', 'comptaflow-uk-by-meetempo')) . '</h2>';
        echo '<form method="post" id="invoice-form">';
        wp_nonce_field('comptaflow_uk_invoice_save');
        if (!empty($invoice['id'])) {
            echo '<input type="hidden" name="invoice_id" value="' . esc_attr($invoice['id']) . '">';
        }

        echo '<table class="form-table">';

        echo '<tr><th>' . esc_html__('Client', 'comptaflow-uk-by-meetempo') . '</th><td>';
        echo '<select name="client_id">';
        echo '<option value="">' . esc_html__('-- Select a client --', 'comptaflow-uk-by-meetempo') . '</option>';
        foreach ($clients as $c) {
            $name = ClientService::getDisplayName($c);
            echo '<option value="' . esc_attr($c['id']) . '"' . selected($invoice['client_id'] ?? '', $c['id'], false) . '>' . esc_html($name) . '</option>';
        }
        echo '</select>';
        echo ' <a href="?page=comptaflow-uk-clients&action=new" class="button button-small">' . esc_html__('+ New Client', 'comptaflow-uk-by-meetempo') . '</a>';
        echo '</td></tr>';

        echo '<tr><th>' . esc_html__('Invoice Date', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<td><input type="date" name="issue_date" value="' . esc_attr($invoice['issue_date'] ?? gmdate('Y-m-d')) . '" required></td></tr>';

        echo '<tr><th>' . esc_html__('Payment Terms (days)', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<td><input type="number" name="payment_terms" value="' . esc_attr($invoice['payment_terms'] ?? 30) . '" min="0" style="width:80px"></td></tr>';

        echo '<tr><th>' . esc_html__('Due Date', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<td><input type="date" name="due_date" value="' . esc_attr($invoice['due_date'] ?? '') . '"></td></tr>';

        echo '<tr><th>' . esc_html__('Status', 'comptaflow-uk-by-meetempo') . '</th><td>';
        echo '<select name="status">';
        $statuses = ['DRAFT' => 'Draft', 'SENT' => 'Sent'];
        foreach ($statuses as $k => $v) {
            echo '<option value="' . esc_attr($k) . '"' . selected($invoice['status'] ?? 'DRAFT', $k, false) . '>' . esc_html($v) . '</option>';
        }
        echo '</select></td></tr>';

        echo '</table>';

        echo '<h3>' . esc_html__('Invoice Lines', 'comptaflow-uk-by-meetempo') . '</h3>';
        echo '<table class="wp-list-table widefat" id="invoice-lines-table">';
        echo '<thead><tr>';
        echo '<th style="width:30%">' . esc_html__('Description', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:8%">' . esc_html__('Qty', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:12%">' . esc_html__('Unit Price', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:12%">' . esc_html__('VAT Rate', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:10%">' . esc_html__('Account', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:10%" class="right">' . esc_html__('Net', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:10%" class="right">' . esc_html__('VAT', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th style="width:4%"></th>';
        echo '</tr></thead><tbody id="invoice-lines-body">';

        if (empty($lines)) {
            $lines = [['description' => '', 'quantity' => 1, 'unit_price' => 0, 'vat_rate' => 20, 'vat_code' => 'GB-20', 'account_code' => '4010', 'line_total' => 0, 'vat_amount' => 0]];
        }

        foreach ($lines as $i => $line) {
            self::renderLineRow($i, $line, $vat_rates);
        }

        echo '</tbody></table>';

        echo '<p><button type="button" id="add-invoice-line" class="button">' . esc_html__('+ Add Line', 'comptaflow-uk-by-meetempo') . '</button></p>';

        echo '<div style="max-width:350px; margin-left:auto; background:#f8f9fa; padding:15px; border:1px solid #ddd; border-radius:4px;">';
        echo '<table style="width:100%">';
        echo '<tr><td>' . esc_html__('Subtotal:', 'comptaflow-uk-by-meetempo') . '</td><td class="right" id="inv-subtotal">&pound;0.00</td></tr>';
        echo '<tr><td>' . esc_html__('Total VAT:', 'comptaflow-uk-by-meetempo') . '</td><td class="right" id="inv-totalvat">&pound;0.00</td></tr>';
        echo '<tr style="font-size:16px;font-weight:bold;"><td>' . esc_html__('Total:', 'comptaflow-uk-by-meetempo') . '</td><td class="right" id="inv-total">&pound;0.00</td></tr>';
        echo '</table></div>';

        echo '<table class="form-table">';
        echo '<tr><th>' . esc_html__('Notes', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<td><textarea name="notes" rows="2" class="large-text">' . esc_textarea($invoice['notes'] ?? '') . '</textarea></td></tr>';
        echo '<tr><th>' . esc_html__('Terms & Conditions', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<td><textarea name="terms" rows="2" class="large-text">' . esc_textarea($invoice['terms'] ?? '') . '</textarea></td></tr>';
        echo '</table>';

        submit_button($action === 'edit' ? esc_html__('Update Invoice', 'comptaflow-uk-by-meetempo') : esc_html__('Create Invoice', 'comptaflow-uk-by-meetempo'));
        echo '</form>';

        // Pass VAT rates to JS
        wp_localize_script('comptaflow-uk-invoices', 'comptaflow_uk_invoice_data', [
            'vat_rates' => $vat_rates,
        ]);
    }

    private static function renderLineRow(int $i, array $line, array $vat_rates): void {
        echo '<tr class="invoice-line-row">';
        echo '<td><input type="text" name="line_description[]" value="' . esc_attr($line['description']) . '" class="regular-text" style="width:100%" required></td>';
        echo '<td><input type="number" name="line_quantity[]" value="' . esc_attr($line['quantity']) . '" step="0.001" min="0" style="width:100%" class="line-qty"></td>';
        echo '<td><input type="number" name="line_unit_price[]" value="' . esc_attr($line['unit_price']) . '" step="0.01" min="0" style="width:100%" class="line-price"></td>';
        echo '<td><select name="line_vat_rate[]" class="line-vat-rate" style="width:100%">';
        foreach ($vat_rates as $rate) {
            $is_selected = (abs(floatval($rate['rate_value']) - floatval($line['vat_rate'])) < 0.01);
            echo '<option value="' . esc_attr($rate['rate_value']) . '" data-code="' . esc_attr($rate['rate_code']) . '"' . ($is_selected ? ' selected' : '') . '>';
            echo esc_html(number_format($rate['rate_value'], 0) . '% - ' . $rate['rate_name']);
            echo '</option>';
        }
        echo '</select>';
        echo '<input type="hidden" name="line_vat_code[]" value="' . esc_attr($line['vat_code'] ?? 'GB-20') . '" class="line-vat-code">';
        echo '</td>';
        echo '<td><input type="text" name="line_account_code[]" value="' . esc_attr($line['account_code'] ?? '4010') . '" style="width:100%"></td>';
        echo '<td class="right line-net">&pound;' . esc_html(number_format(floatval($line['line_total'] ?? 0), 2)) . '</td>';
        echo '<td class="right line-vat-amount">&pound;' . esc_html(number_format(floatval($line['vat_amount'] ?? 0), 2)) . '</td>';
        echo '<td><button type="button" class="button remove-invoice-line" title="' . esc_attr__('Remove', 'comptaflow-uk-by-meetempo') . '">&times;</button></td>';
        echo '</tr>';
    }

    private static function renderList(): void {
        $search = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
        $status = isset($_GET['status']) ? sanitize_text_field(wp_unslash($_GET['status'])) : '';
        $page_num = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
        $per_page = 20;
        $offset = ($page_num - 1) * $per_page;

        $invoices = InvoiceService::getAll('INVOICE', $search, $status, $per_page, $offset);
        $total = InvoiceService::count('INVOICE', $search, $status);

        echo '<div class="tablenav top">';
        echo '<div class="alignleft actions">';
        echo '<select name="status_filter" id="cfuk-status-filter">';
        echo '<option value="">' . esc_html__('All statuses', 'comptaflow-uk-by-meetempo') . '</option>';
        foreach (['DRAFT', 'SENT', 'PAID', 'OVERDUE', 'CANCELLED'] as $s) {
            echo '<option value="' . esc_attr($s) . '"' . selected($status, $s, false) . '>' . esc_html($s) . '</option>';
        }
        echo '</select>';
        echo '</div>';
        echo '<form method="get" class="search-box" style="display:inline">';
        echo '<input type="hidden" name="page" value="comptaflow-uk-invoices">';
        echo '<input type="search" name="s" value="' . esc_attr($search) . '">';
        echo '<input type="submit" class="button" value="' . esc_attr__('Search', 'comptaflow-uk-by-meetempo') . '">';
        echo '</form>';
        echo '</div>';

        echo '<table class="wp-list-table widefat fixed striped">';
        echo '<thead><tr>';
        echo '<th>' . esc_html__('Number', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Client', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Date', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Due Date', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Total', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Status', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '<th>' . esc_html__('Actions', 'comptaflow-uk-by-meetempo') . '</th>';
        echo '</tr></thead><tbody>';

        if (empty($invoices)) {
            echo '<tr><td colspan="7">' . esc_html__('No invoices found.', 'comptaflow-uk-by-meetempo') . '</td></tr>';
        }

        foreach ($invoices as $inv) {
            $edit_url = admin_url('admin.php?page=comptaflow-uk-invoices&action=edit&id=' . $inv['id']);
            $delete_url = wp_nonce_url(admin_url('admin.php?page=comptaflow-uk-invoices&action=delete&id=' . $inv['id']), 'comptaflow_uk_delete_invoice');
            $pdf_url = wp_nonce_url(admin_url('admin-post.php?action=comptaflow_uk_pdf_view&id=' . $inv['id']), 'comptaflow_uk_pdf');
            $download_url = wp_nonce_url(admin_url('admin-post.php?action=comptaflow_uk_pdf_download&id=' . $inv['id']), 'comptaflow_uk_pdf');
            $action_url = wp_nonce_url(admin_url('admin.php?page=comptaflow-uk-invoices&id=' . $inv['id']), 'comptaflow_uk_invoice_action');

            $client_name = '';
            if (!empty($inv['company_name'])) {
                $client_name = $inv['company_name'];
            } elseif (!empty($inv['contact_name'])) {
                $client_name = $inv['contact_name'];
            }

            $status_class = 'cfuk-status-' . strtolower($inv['status']);

            echo '<tr>';
            echo '<td><strong><a href="' . esc_url($edit_url) . '">' . esc_html($inv['invoice_number']) . '</a></strong></td>';
            echo '<td>' . esc_html($client_name) . '</td>';
            echo '<td>' . esc_html(date_i18n('d/m/Y', strtotime($inv['issue_date']))) . '</td>';
            echo '<td>' . ($inv['due_date'] ? esc_html(date_i18n('d/m/Y', strtotime($inv['due_date']))) : '-') . '</td>';
            echo '<td>&pound;' . esc_html(number_format(floatval($inv['total']), 2)) . '</td>';
            echo '<td><span class="cfuk-invoice-badge ' . esc_attr($status_class) . '">' . esc_html($inv['status']) . '</span></td>';
            echo '<td>';

            $actions_html = [];
            $actions_html[] = '<a href="' . esc_url($pdf_url) . '" target="_blank">' . esc_html__('PDF', 'comptaflow-uk-by-meetempo') . '</a>';
            $actions_html[] = '<a href="' . esc_url($download_url) . '">' . esc_html__('Download', 'comptaflow-uk-by-meetempo') . '</a>';

            if ($inv['status'] === 'DRAFT') {
                $actions_html[] = '<a href="' . esc_url($action_url . '&action=mark_sent') . '">' . esc_html__('Mark Sent', 'comptaflow-uk-by-meetempo') . '</a>';
            }
            if (in_array($inv['status'], ['SENT', 'OVERDUE'], true)) {
                $actions_html[] = '<a href="' . esc_url($action_url . '&action=mark_paid') . '" class="button button-small button-primary">' . esc_html__('Mark Paid', 'comptaflow-uk-by-meetempo') . '</a>';
            }
            if ($inv['status'] !== 'CANCELLED' && $inv['status'] !== 'PAID') {
                $actions_html[] = '<a href="' . esc_url($delete_url) . '" onclick="return confirm(\'' . esc_js(__('Delete this invoice?', 'comptaflow-uk-by-meetempo')) . '\')">' . esc_html__('Delete', 'comptaflow-uk-by-meetempo') . '</a>';
            }

            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- each element is already escaped above
            echo wp_kses_post(implode(' | ', $actions_html));
            echo '</td>';
            echo '</tr>';
        }

        echo '</tbody></table>';

        $total_pages = ceil($total / $per_page);
        if ($total_pages > 1) {
            echo '<div class="tablenav"><div class="tablenav-pages">';
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
            echo paginate_links([
                'base' => add_query_arg('paged', '%#%'),
                'format' => '',
                'current' => $page_num,
                'total' => $total_pages,
            ]);
            echo '</div></div>';
        }
    }
}
