<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Dompdf\Dompdf;
use Dompdf\Options;

require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/db.php';

class InvoiceSettings
{
    public static function get(): ?array
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        
        if (!$workspace || is_array($workspace)) {
            return null;
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return null;
        }
        
        // Get settings for this company
        $stmt = $pdo->prepare('SELECT * FROM invoice_settings WHERE company_id = ? ORDER BY id DESC LIMIT 1');
        $stmt->execute([$company['id']]);
        return $stmt->fetch() ?: null;
    }

    public static function save(array $data): bool
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return false;
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return false;
        }
        
        // Check if settings exist for this company
        $stmt = $pdo->prepare('SELECT id FROM invoice_settings WHERE company_id = ? ORDER BY id DESC LIMIT 1');
        $stmt->execute([$company['id']]);
        $existing = $stmt->fetch();
        
        if ($existing) {
            // Update existing
            $sql = "UPDATE invoice_settings SET 
                company_name = ?, company_legal_name = ?, tax_id = ?, tax_name = ?, company_registration_number = ?, custom_meta = ?,
                address_line_1 = ?, address_line_2 = ?, city = ?, state = ?, zip_code = ?, country = ?, company_email = ?, company_phone = ?,
                bank_name = ?, bank_account_name = ?, bank_account_number = ?, bank_routing_number = ?, bank_swift = ?, bank_details = ?,
                currency = ?, tax_inclusive = ?, payment_terms = ?, custom_payment_terms = ?,
                authorized_signatory_name = ?, authorized_signatory_designation = ?, authorized_signatory_signature_path = ?
                WHERE id = ?";
            
            $stmt = $pdo->prepare($sql);
            return $stmt->execute([
                $data['company_name'],
                $data['company_legal_name'] ?? null,
                $data['tax_id'] ?? null,
                $data['tax_name'] ?? null,
                $data['company_registration_number'] ?? null,
                $data['custom_meta'] ?? null,
                $data['address_line_1'] ?? null,
                $data['address_line_2'] ?? null,
                $data['city'] ?? null,
                $data['state'] ?? null,
                $data['zip_code'] ?? null,
                $data['country'] ?? null,
                $data['company_email'] ?? null,
                $data['company_phone'] ?? null,
                $data['bank_name'] ?? null,
                $data['bank_account_name'] ?? null,
                $data['bank_account_number'] ?? null,
                $data['bank_routing_number'] ?? null,
                $data['bank_swift'] ?? null,
                $data['bank_details'] ?? null,
                $data['currency'] ?? 'USD',
                ($data['tax_inclusive'] ?? false) ? 1 : 0,
                $data['payment_terms'] ?? 'Due on Receipt',
                $data['custom_payment_terms'] ?? null,
                $data['authorized_signatory_name'] ?? null,
                $data['authorized_signatory_designation'] ?? null,
                $data['authorized_signatory_signature_path'] ?? null,
                $existing['id']
            ]);
        } else {
            // Insert new
            $sql = "INSERT INTO invoice_settings (
                company_name, company_legal_name, tax_id, tax_name, company_id, company_registration_number, custom_meta,
                address_line_1, address_line_2, city, state, zip_code, country, company_email, company_phone,
                bank_name, bank_account_name, bank_account_number, bank_routing_number, bank_swift, bank_details,
                currency, tax_inclusive, payment_terms, custom_payment_terms,
                authorized_signatory_name, authorized_signatory_designation, authorized_signatory_signature_path
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            $stmt = $pdo->prepare($sql);
            return $stmt->execute([
                $data['company_name'],
                $data['company_legal_name'] ?? null,
                $data['tax_id'] ?? null,
                $data['tax_name'] ?? null,
                $company['id'],
                $data['company_registration_number'] ?? null,
                $data['custom_meta'] ?? null,
                $data['address_line_1'] ?? null,
                $data['address_line_2'] ?? null,
                $data['city'] ?? null,
                $data['state'] ?? null,
                $data['zip_code'] ?? null,
                $data['country'] ?? null,
                $data['company_email'] ?? null,
                $data['company_phone'] ?? null,
                $data['bank_name'] ?? null,
                $data['bank_account_name'] ?? null,
                $data['bank_account_number'] ?? null,
                $data['bank_routing_number'] ?? null,
                $data['bank_swift'] ?? null,
                $data['bank_details'] ?? null,
                $data['currency'] ?? 'USD',
                ($data['tax_inclusive'] ?? false) ? 1 : 0,
                $data['payment_terms'] ?? 'Due on Receipt',
                $data['custom_payment_terms'] ?? null,
                $data['authorized_signatory_name'] ?? null,
                $data['authorized_signatory_designation'] ?? null,
                $data['authorized_signatory_signature_path'] ?? null
            ]);
        }
    }

    public static function updateLogo(string $logoPath): bool
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return false;
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return false;
        }
        
        $stmt = $pdo->prepare('UPDATE invoice_settings SET company_logo_path = ? WHERE company_id = ?');
        return $stmt->execute([$logoPath, $company['id']]);
    }
}

class TaxBracket
{
    public static function all(): array
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return [];
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return [];
        }
        
        $stmt = $pdo->prepare('SELECT * FROM tax_brackets WHERE company_id = ? ORDER BY rate ASC');
        $stmt->execute([$company['id']]);
        return $stmt->fetchAll();
    }

    public static function find(int $id): ?array
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('SELECT * FROM tax_brackets WHERE id = ?');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public static function getActive(): array
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return [];
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return [];
        }
        
        $stmt = $pdo->prepare('SELECT * FROM tax_brackets WHERE company_id = ? AND is_active = 1 ORDER BY rate ASC');
        $stmt->execute([$company['id']]);
        return $stmt->fetchAll();
    }

    public static function create(array $data): bool
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return false;
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return false;
        }
        
        $sql = "INSERT INTO tax_brackets (company_id, name, rate, description, is_compound, is_active, jurisdiction, tax_id) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            $company['id'],
            $data['name'],
            $data['rate'],
            $data['description'] ?? null,
            ($data['is_compound'] ?? false) ? 1 : 0,
            ($data['is_active'] ?? true) ? 1 : 0,
            $data['jurisdiction'] ?? null,
            $data['tax_id'] ?? null
        ]);
    }

    public static function update(int $id, array $data): bool
    {
        $pdo = getPDO();
        $sql = "UPDATE tax_brackets SET 
                name = ?, rate = ?, description = ?, is_compound = ?, 
                is_active = ?, jurisdiction = ?, tax_id = ? 
                WHERE id = ?";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            $data['name'],
            $data['rate'],
            $data['description'] ?? null,
            ($data['is_compound'] ?? false) ? 1 : 0,
            ($data['is_active'] ?? true) ? 1 : 0,
            $data['jurisdiction'] ?? null,
            $data['tax_id'] ?? null,
            $id
        ]);
    }

    public static function delete(int $id): bool
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('DELETE FROM tax_brackets WHERE id = ?');
        return $stmt->execute([$id]);
    }

    public static function isInUse(int $id): bool
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('SELECT COUNT(*) as count FROM invoice_items WHERE default_tax_bracket_id = ?');
        $stmt->execute([$id]);
        $result = $stmt->fetch();
        return $result['count'] > 0;
    }
}

class InvoiceItem
{
    public static function all(): array
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return [];
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return [];
        }
        
        $stmt = $pdo->prepare('SELECT ii.* FROM invoice_items ii 
                              INNER JOIN invoices i ON ii.invoice_id = i.id 
                              WHERE i.company_id = ? 
                              ORDER BY ii.sort_order ASC, ii.description ASC');
        $stmt->execute([$company['id']]);
        return $stmt->fetchAll();
    }

    public static function find(int $id): ?array
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('SELECT * FROM invoice_items WHERE id = ?');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public static function create(array $data): bool
    {
        $pdo = getPDO();
        $sql = "INSERT INTO invoice_items (invoice_id, description, quantity, unit_price, tax_rate, total, sort_order) 
                VALUES (?, ?, ?, ?, ?, ?, ?)";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            $data['invoice_id'],
            $data['description'],
            $data['quantity'] ?? 1,
            $data['unit_price'],
            $data['tax_rate'] ?? 0,
            $data['total'] ?? ($data['unit_price'] * ($data['quantity'] ?? 1)),
            $data['sort_order'] ?? 0
        ]);
    }

    public static function update(int $id, array $data): bool
    {
        $pdo = getPDO();
        $sql = "UPDATE invoice_items SET 
                invoice_id = ?, description = ?, quantity = ?, unit_price = ?, tax_rate = ?, total = ?, sort_order = ?
                WHERE id = ?";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            $data['invoice_id'],
            $data['description'],
            $data['quantity'] ?? 1,
            $data['unit_price'],
            $data['tax_rate'] ?? 0,
            $data['total'] ?? ($data['unit_price'] * ($data['quantity'] ?? 1)),
            $data['sort_order'] ?? 0,
            $id
        ]);
    }

    public static function delete(int $id): bool
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('DELETE FROM invoice_items WHERE id = ?');
        return $stmt->execute([$id]);
    }
}

class ItemTemplate
{
    public static function all(): array
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return [];
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return [];
        }
        
        // For now, use invoice_items table with invoice_id = 0 as templates
        $stmt = $pdo->prepare('SELECT * FROM invoice_items WHERE invoice_id = 0 AND company_id = ? ORDER BY sort_order ASC, description ASC');
        $stmt->execute([$company['id']]);
        return $stmt->fetchAll();
    }

    public static function find(int $id): ?array
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare('SELECT * FROM invoice_items WHERE id = ? AND invoice_id = 0');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public static function create(array $data): bool
    {
        // Get workspace from URL parameter or session
        $workspace = $_GET['workspace'] ?? $_SESSION['workspace'] ?? null;
        if (!$workspace || is_array($workspace)) {
            return false;
        }

        $pdo = getPDO();
        
        // Get company from workspace
        $stmt = $pdo->prepare('SELECT * FROM companies WHERE username = ?');
        $stmt->execute([$workspace]);
        $company = $stmt->fetch();
        
        if (!$company) {
            return false;
        }
        
        $sql = "INSERT INTO invoice_items (invoice_id, company_id, description, sku, quantity, unit_price, tax_rate, default_tax_bracket_id, total, sort_order) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            0, // invoice_id = 0 for templates
            $company['id'],
            $data['description'],
            $data['sku'] ?? null,
            1, // default quantity for templates
            $data['unit_price'],
            $data['tax_rate'] ?? 0,
            $data['default_tax_bracket_id'] ?? 0,
            $data['unit_price'], // total = unit_price for templates
            $data['sort_order'] ?? 0
        ]);
    }

    public static function update(int $id, array $data): bool
    {
        $pdo = getPDO();
        $sql = "UPDATE invoice_items SET 
                description = ?, sku = ?, unit_price = ?, tax_rate = ?, default_tax_bracket_id = ?, total = ?, sort_order = ?
                WHERE id = ? AND invoice_id = 0";
        $stmt = $pdo->prepare($sql);
        return $stmt->execute([
            $data['description'],
            $data['sku'] ?? null,
            $data['unit_price'],
            $data['tax_rate'] ?? 0,
            $data['default_tax_bracket_id'] ?? 0,
            $data['unit_price'],
            $data['sort_order'] ?? 0,
            $id
        ]);
    }

    public static function delete(int $id): bool
    {
        $pdo = getPDO();
        $stmt = $pdo->prepare("DELETE FROM invoice_items WHERE id = ?");
        return $stmt->execute([$id]);
    }
}
