<?php

namespace App\Services;

use App\Models\ExportRequest;
use Carbon\Carbon;

class DHLCSVService
{
    public function validate(ExportRequest $exportRequest): array
    {
        $missingFields = [];
        $user = auth()->user();
        $shipTo = $exportRequest->shipToAddress;

        // User Validation (Row 1 & 7)
        if (empty($user->name)) $missingFields[] = 'User Name';
        if (empty($user->email)) $missingFields[] = 'User Email';
        if (empty($user->phone)) $missingFields[] = 'User Phone';

        // Ship To Validation (Row 2)
        if (!$shipTo) {
            $missingFields[] = 'Ship To Address';
        } else {
            if (empty($shipTo->contact_name)) $missingFields[] = 'Ship To Contact Name';
            if (empty($shipTo->company_name)) $missingFields[] = 'Ship To Company Name';
            if (empty($shipTo->address_1)) $missingFields[] = 'Ship To Address 1';
            // Address 2 and 3 are optional in standard cases, but checking requirement...
            // User said: "if any field is missing which is needed to generate the csv file, please inform the user via an alert."
            // In the example: ADD5 and ADD6 are populated. Let's assume Address 1 is strict.
            if (empty($shipTo->zip_code)) $missingFields[] = 'Ship To Zip Code';
            if (empty($shipTo->city)) $missingFields[] = 'Ship To City';
            if (empty($shipTo->country)) $missingFields[] = 'Ship To Country';
            if (empty($shipTo->phone_country_code)) $missingFields[] = 'Ship To Phone Country Code';
            if (empty($shipTo->phone_number)) $missingFields[] = 'Ship To Phone Number';
        }

        // Shipment Validation (Row 3)
        // Most fields are static or present by default (dates), but checking critical ones.
        // if (empty($exportRequest->shipment_reference)) $missingFields[] = 'Shipment Reference'; // Optional now
        // Currency is from item details, assuming at least one item exists and has currency.
        if ($exportRequest->items->isEmpty()) {
            $missingFields[] = 'Items (for Currency and Content)';
        } else {
            // Check if first item has currency, as example uses one currency code for the shipment row.
            if (empty($exportRequest->items->first()->currency)) $missingFields[] = 'Item Currency';
        }
        
        // Packaging Validation (Row 4)
        if ($exportRequest->packages->isEmpty()) {
            $missingFields[] = 'Packages';
        } else {
            foreach ($exportRequest->packages as $index => $package) {
                if (empty($package->package_weight)) $missingFields[] = "Package " . ($index + 1) . " Weight";
                // Dimensions are part of example, so required.
                if (empty($package->length)) $missingFields[] = "Package " . ($index + 1) . " Length";
                if (empty($package->width)) $missingFields[] = "Package " . ($index + 1) . " Width";
                if (empty($package->height)) $missingFields[] = "Package " . ($index + 1) . " Height";
            }
        }
        
        // Invoice Item Validation (Row 8)
        foreach ($exportRequest->items as $index => $item) {
             if (empty($item->item_description)) $missingFields[] = "Item " . ($index + 1) . " Description";
             if (empty($item->quantity)) $missingFields[] = "Item " . ($index + 1) . " Quantity";
             if (empty($item->uom)) $missingFields[] = "Item " . ($index + 1) . " UOM";
             if (empty($item->unit_price)) $missingFields[] = "Item " . ($index + 1) . " Price";
             if (empty($item->weight)) $missingFields[] = "Item " . ($index + 1) . " Weight";
        }

        return $missingFields;
    }

    public function generate(ExportRequest $exportRequest): string
    {
        $lines = [];
        $user = auth()->user(); // Or $exportRequest->creator if that's preferred. Requirement says "USER'S NAME", "LOGGED IN USER'S NAME"
        // Let's use current logged in user as per "LOGGED IN USER'S NAME" in Row 7 instructions.
        
        $shipTo = $exportRequest->shipToAddress;
        
        // Helper to handle pipe separation and quoting
        $formatRow = function (...$args) {
            $pipeString = implode('|', $args);
            // Escape existing double quotes by doubling them
            $escaped = str_replace('"', '""', $pipeString);
            // Wrap in double quotes to ensure it stays in one cell in CSV viewers
            return '"' . $escaped . '"';
        };

        // Helper to extract strictly the currency code (e.g., "United States Dollar (USD)" -> "USD")
        $extractCurrencyCode = function ($currencyString) {
            if (empty($currencyString)) return '';
            if (preg_match('/\(([A-Z]{3})\)$/', $currencyString, $matches)) {
                return $matches[1];
            }
            return $currencyString;
        };

        // Helper to get 2-letter Country Code from Name or Code
        $getCountryCode = function ($countryInput) {
            if (empty($countryInput)) return '';
            
            // If input is already 2 uppercase letters, assume it's the code
            if (preg_match('/^[A-Z]{2}$/', $countryInput)) {
                return $countryInput;
            }

            $countries = config('constants.countries');
            // Search for code by name (case-insensitive)
            $code = array_search(strtolower(trim($countryInput)), array_map('strtolower', $countries));
            
            return $code ?: $countryInput; // Return found code or original input if not found
        };

        // Helper to remove commas
        $escapeCsvField = function ($value) {
            return str_replace(',', '', $value);
        };

        // --- ROW 1: SHIP_FROM ---
        
        $userPhone = $user->phone ? ltrim($user->phone, '0') : '';
        
        $lines[] = $formatRow(
            '1', 'SHIP_FROM', $user->name, 'JF&I PACKAGING (PVT) LTD', '321 KADUWELA ROAD', '', 'THALANGAMA', 'KOSWATTA', '10120', 'KOSWATTA', '', '', 'LK', $user->email, 'O', '94', $userPhone, '', '', '', '', '', '', '', '', '', '', '', ''
        );

        // --- ROW 2: SHIP_TO ---
        $shipToCountryCode = $getCountryCode($shipTo->country);
        
        $lines[] = $formatRow(
            '1',
            'SHIP_TO',
            $shipTo->contact_name,
            $shipTo->company_name,
            $escapeCsvField($shipTo->address_1),
            $escapeCsvField($shipTo->address_2 ?? ''),
            $escapeCsvField($shipTo->address_3 ?? ''),
            '',
            $shipTo->zip_code,
            $shipTo->city,
            '',
            '',
            $shipToCountryCode,
            '',
            'O',
            $shipTo->phone_country_code,
            $shipTo->phone_number,
            '',
            ''
        );

        // --- ROW 3: SHIPMENT ---
        
        // Extract strictly the code 
        $rawCurrency = $exportRequest->items->first()->currency ?? 'USD';
        $currency = $extractCurrencyCode($rawCurrency);
        
        $lines[] = $formatRow(
            '1',
            'SHIPMENT',
            '',
            Carbon::now()->format('Ymd'),
            'P',
            'WPX',
            'P',
            'P',
            $exportRequest->products_summary,
            $exportRequest->shipment_reference,
            '1',
            $currency,
            '',
            '',
            '524045022',
            '524045022',
            '',
            '',
            '',
            '',
            'DAP',
            $exportRequest->shipment_purpose,
            '',
            '',
            'P'
        );

        // --- ROW 4+: PACKAGING ---
        foreach ($exportRequest->packages as $package) {
            $lines[] = $formatRow(
                '1',
                'PACKAGING',
                $package->package_weight,
                'KG',
                $package->length,
                $package->width,
                $package->height,
                'CM'
            );
        }

        // --- ROW 7: INVOICE_HEADER ---
        
        $lines[] = $formatRow(
            '1',
            'INVOICE_HEADER',
            'COMMERCIAL',
            'SAMPLE',
            '',
            '2000',
            '2001',
            '111222333',
            '444555666',
            'LK',
            'KOSWATTA',
            'Invoice',
            'LK',
            'SAMPLE',
            'SAMPLE',
            'SAMPLE',
            $user->name,
            'AUTHORIZED SIGNATURE',
            ''
        );
        
        // --- ROW 8+: INV_ITEM ---
        
        foreach ($exportRequest->items as $item) {
            $lines[] = $formatRow(
                '1',
                'INV_ITEM',
                $item->item_description,
                '',
                $item->quantity,
                $item->uom,
                $item->unit_price,
                $extractCurrencyCode($item->currency),
                $item->weight,
                '',
                'LK'
            );
        }

        // --- ROW 11: EXTRA_SERVICE ---
        
        $lines[] = $formatRow(
            '1', 'EXTRA_SERVICE', '', 'Y', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''
        );

        return implode("\n", $lines);
    }
}
