<?php

namespace App\Services;

class CsvExportService
{
    /**
     * Export report data to CSV
     */
    public function export(string $reportType, array $data, string $fileName): string
    {
        $filePath = storage_path('app/temp/' . $fileName);
        
        // Ensure temp directory exists
        if (!file_exists(dirname($filePath))) {
            mkdir(dirname($filePath), 0755, true);
        }

        $file = fopen($filePath, 'w');
        
        // Add BOM for UTF-8
        fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
        
        // Write headers
        $headers = $this->getHeaders($reportType);
        fputcsv($file, $headers);
        
        // Write data
        $rows = $this->formatDataForCsv($reportType, $data);
        foreach ($rows as $row) {
            fputcsv($file, $row);
        }
        
        fclose($file);
        
        return $filePath;
    }

    /**
     * Get CSV headers
     */
    private function getHeaders(string $reportType): array
    {
        return match ($reportType) {
            'sales-summary' => ['Invoice', 'Date', 'Customer', 'Total Amount', 'Paid', 'Due', 'Status'],
            'sales-by-customer' => ['Customer Name', 'Phone', 'Total Sales', 'Total Amount', 'Total Paid', 'Total Due'],
            'sales-by-product' => ['Product Name', 'Quantity Sold', 'Total Sales', 'Average Price'],
            'payment-received' => ['Date', 'Invoice', 'Customer', 'Amount', 'Payment Method'],
            'purchase-summary' => ['Invoice', 'Date', 'Supplier', 'Total Amount', 'Paid', 'Due', 'Status'],
            'purchase-by-supplier' => ['Supplier Name', 'Phone', 'Total Purchases', 'Total Amount', 'Total Paid', 'Total Due'],
            'payment-made' => ['Date', 'Invoice', 'Supplier', 'Amount', 'Payment Method'],
            'stock-summary' => ['Product Name', 'Brand', 'Model', 'Stock Quantity', 'Total Value', 'Avg Cost'],
            'low-stock-alert' => ['Product Name', 'Brand', 'Model', 'Current Stock', 'Status'],
            'stock-movement' => ['Date', 'Product', 'Type', 'Quantity', 'Value'],
            'profit-loss' => ['Metric', 'Amount'],
            'cash-flow' => ['Metric', 'Amount'],
            'tax-summary' => ['Type', 'Amount'],
            'outstanding-receivables' => ['Invoice', 'Customer', 'Phone', 'Sale Date', 'Due Date', 'Amount', 'Paid', 'Due', 'Days Overdue', 'Status'],
            'outstanding-payables' => ['Invoice', 'Supplier', 'Phone', 'Purchase Date', 'Due Date', 'Amount', 'Paid', 'Due', 'Days Overdue', 'Status'],
            default => ['Data']
        };
    }

    /**
     * Format data for CSV
     */
    private function formatDataForCsv(string $reportType, array $data): array
    {
        return match ($reportType) {
            'sales-summary' => $this->formatSalesSummary($data),
            'sales-by-customer' => $this->formatSalesByCustomer($data),
            'sales-by-product' => $this->formatSalesByProduct($data),
            'payment-received' => $this->formatPaymentReceived($data),
            'purchase-summary' => $this->formatPurchaseSummary($data),
            'purchase-by-supplier' => $this->formatPurchaseBySupplier($data),
            'payment-made' => $this->formatPaymentMade($data),
            'stock-summary' => $this->formatStockSummary($data),
            'low-stock-alert' => $this->formatLowStockAlert($data),
            'stock-movement' => $this->formatStockMovement($data),
            'profit-loss' => $this->formatProfitLoss($data),
            'cash-flow' => $this->formatCashFlow($data),
            'tax-summary' => $this->formatTaxSummary($data),
            'outstanding-receivables' => $this->formatOutstandingReceivables($data),
            'outstanding-payables' => $this->formatOutstandingPayables($data),
            default => []
        };
    }

    private function formatSalesSummary(array $data): array
    {
        $rows = [];
        foreach ($data['sales'] ?? [] as $sale) {
            $rows[] = [
                $sale['invoice_number'] ?? '',
                $sale['sale_date'] ?? '',
                $sale['customer']['name'] ?? 'Walk-in',
                $sale['total_amount'] ?? 0,
                $sale['paid_amount'] ?? 0,
                $sale['due_amount'] ?? 0,
                $sale['status'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatSalesByCustomer(array $data): array
    {
        $rows = [];
        foreach ($data['customers'] ?? [] as $customer) {
            $rows[] = [
                $customer['customer_name'] ?? '',
                $customer['customer_phone'] ?? '',
                $customer['total_sales'] ?? 0,
                $customer['total_amount'] ?? 0,
                $customer['total_paid'] ?? 0,
                $customer['total_due'] ?? 0
            ];
        }
        return $rows;
    }

    private function formatSalesByProduct(array $data): array
    {
        $rows = [];
        foreach ($data['products'] ?? [] as $product) {
            $rows[] = [
                $product['product_name'] ?? '',
                $product['total_quantity'] ?? 0,
                $product['total_sales'] ?? 0,
                $product['average_price'] ?? 0
            ];
        }
        return $rows;
    }

    private function formatPaymentReceived(array $data): array
    {
        $rows = [];
        foreach ($data['payments'] ?? [] as $payment) {
            $rows[] = [
                $payment['payment_date'] ?? '',
                $payment['invoice_number'] ?? '',
                $payment['customer_name'] ?? 'Walk-in',
                $payment['amount'] ?? 0,
                $payment['payment_method'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatPurchaseSummary(array $data): array
    {
        $rows = [];
        foreach ($data['purchases'] ?? [] as $purchase) {
            $rows[] = [
                $purchase['invoice_number'] ?? '',
                $purchase['purchase_date'] ?? '',
                $purchase['supplier']['name'] ?? 'Unknown',
                $purchase['total_amount'] ?? 0,
                $purchase['paid_amount'] ?? 0,
                $purchase['due_amount'] ?? 0,
                $purchase['status'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatPurchaseBySupplier(array $data): array
    {
        $rows = [];
        foreach ($data['suppliers'] ?? [] as $supplier) {
            $rows[] = [
                $supplier['supplier_name'] ?? '',
                $supplier['supplier_phone'] ?? '',
                $supplier['total_purchases'] ?? 0,
                $supplier['total_amount'] ?? 0,
                $supplier['total_paid'] ?? 0,
                $supplier['total_due'] ?? 0
            ];
        }
        return $rows;
    }

    private function formatPaymentMade(array $data): array
    {
        $rows = [];
        foreach ($data['payments'] ?? [] as $payment) {
            $rows[] = [
                $payment['payment_date'] ?? '',
                $payment['invoice_number'] ?? '',
                $payment['supplier_name'] ?? 'Unknown',
                $payment['amount'] ?? 0,
                $payment['payment_method'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatStockSummary(array $data): array
    {
        $rows = [];
        foreach ($data['stock'] ?? [] as $item) {
            $rows[] = [
                $item['product_name'] ?? '',
                $item['brand'] ?? '',
                $item['model'] ?? '',
                $item['total_stock'] ?? 0,
                $item['total_value'] ?? 0,
                $item['average_cost'] ?? 0
            ];
        }
        return $rows;
    }

    private function formatLowStockAlert(array $data): array
    {
        $rows = [];
        foreach ($data['low_stock_products'] ?? [] as $product) {
            $rows[] = [
                $product['product_name'] ?? '',
                $product['brand'] ?? '',
                $product['model'] ?? '',
                $product['current_stock'] ?? 0,
                $product['status'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatStockMovement(array $data): array
    {
        $rows = [];
        foreach ($data['movements'] ?? [] as $movement) {
            $rows[] = [
                $movement['date'] ?? '',
                $movement['product_name'] ?? '',
                $movement['type'] ?? '',
                $movement['quantity'] ?? 0,
                $movement['total_cost'] ?? 0
            ];
        }
        return $rows;
    }

    private function formatProfitLoss(array $data): array
    {
        return [
            ['Revenue', $data['revenue'] ?? 0],
            ['Cost of Goods Sold', $data['cogs'] ?? 0],
            ['Gross Profit', $data['gross_profit'] ?? 0],
            ['Gross Profit Margin (%)', $data['gross_profit_margin'] ?? 0],
            ['Operating Expenses', $data['operating_expenses'] ?? 0],
            ['Net Profit', $data['net_profit'] ?? 0],
            ['Net Profit Margin (%)', $data['net_profit_margin'] ?? 0],
        ];
    }

    private function formatCashFlow(array $data): array
    {
        return [
            ['Cash In', $data['cash_in'] ?? 0],
            ['Cash Out', $data['cash_out'] ?? 0],
            ['Net Cash Flow', $data['net_cash_flow'] ?? 0],
        ];
    }

    private function formatTaxSummary(array $data): array
    {
        return [
            ['Sales Tax Collected', $data['sales_tax_collected'] ?? 0],
            ['Purchase Tax Paid', $data['purchase_tax_paid'] ?? 0],
            ['Net Tax Payable', $data['net_tax_payable'] ?? 0],
        ];
    }

    private function formatOutstandingReceivables(array $data): array
    {
        $rows = [];
        foreach ($data['receivables'] ?? [] as $receivable) {
            $rows[] = [
                $receivable['invoice_number'] ?? '',
                $receivable['customer_name'] ?? '',
                $receivable['customer_phone'] ?? '',
                $receivable['sale_date'] ?? '',
                $receivable['due_date'] ?? '',
                $receivable['total_amount'] ?? 0,
                $receivable['paid_amount'] ?? 0,
                $receivable['due_amount'] ?? 0,
                $receivable['days_overdue'] ?? 0,
                $receivable['status'] ?? ''
            ];
        }
        return $rows;
    }

    private function formatOutstandingPayables(array $data): array
    {
        $rows = [];
        foreach ($data['payables'] ?? [] as $payable) {
            $rows[] = [
                $payable['invoice_number'] ?? '',
                $payable['supplier_name'] ?? '',
                $payable['supplier_phone'] ?? '',
                $payable['purchase_date'] ?? '',
                $payable['due_date'] ?? '',
                $payable['total_amount'] ?? 0,
                $payable['paid_amount'] ?? 0,
                $payable['due_amount'] ?? 0,
                $payable['days_overdue'] ?? 0,
                $payable['status'] ?? ''
            ];
        }
        return $rows;
    }
}