<?php

namespace Daniv04\HaciendaPackage\Traits;

trait UniqueKeyTrait
{
   

    /**
     * Generates the unique consecutive number for electronic receipts according to Hacienda standards
     *
     * Format: AAABBBBCCDDDDDDDDDD (20 digits)
     * - AAA (digits 1-3): Establishment/branch (001=main office, 002+=branches)
     * - BBBBB (digits 4-8): Terminal/point of sale (00001 if only one)
     * - CC (digits 9-10): Electronic receipt type code
     * - DDDDDDDDDD (digits 11-20): Consecutive numbering (10 digits, starts at 1)
     *
     * @param string $documentType Receipt type (01,02,03..)
     * @param int $consecutive Consecutive number (1-9999999999)
     * @param int $establishment Establishment/branch (1-999, default 001)
     * @param int $terminal Terminal/point of sale (1-99999, default 00001)
     * @return string Formatted consecutive number (20 digits)
     * @throws \InvalidArgumentException If parameters are invalid
     */
    public static function generateConsecutiveKey(
        string $typeCode,
        string $consecutive,
        string $establishment,
        string $terminal
    ): string {


        // Validate establishment range (1-999)
        if ($establishment < 1 || $establishment > 999) {
            throw new \InvalidArgumentException("Establishment must be between 1 and 999, received: {$establishment}");
        }

        // Validate terminal range (1-99999)
        if ($terminal < 1 || $terminal > 99999) {
            throw new \InvalidArgumentException("Terminal must be between 1 and 99999, received: {$terminal}");
        }

        // Validate consecutive range (1-9999999999)
        if ($consecutive < 1 || $consecutive > 9999999999) {
            throw new \InvalidArgumentException("Consecutive must be between 1 and 9999999999, received: {$consecutive}");
        }


        $establishmentPart = str_pad((string)$establishment, 3, '0', STR_PAD_LEFT);
        $terminalPart = str_pad((string)$terminal, 5, '0', STR_PAD_LEFT);
        $consecutivePart = str_pad((string)$consecutive, 10, '0', STR_PAD_LEFT);

        return $establishmentPart . $terminalPart . $typeCode . $consecutivePart;
    }

    /**
     * Formats the identification number according to its type (12 digits)
     *
     * Format rules:
     * - Física: Add 3 leading zeros (000XXXXXXXXX = 12 digits total)
     * - Jurídica: Add 2 leading zeros (00XXXXXXXXXX = 12 digits total)
     * - DIMEX: Add 1 leading zero if 11 digits (0XXXXXXXXXXX = 12 digits)
     * - NITE: Add 2 leading zeros (00XXXXXXXXXX = 12 digits total)
     *
     * @param string $identificationNumber The identification number
     * @param string $type Identification type (fisica, juridica, dimex, nite)
     * @return string Formatted identification number (12 digits)
     * @throws \InvalidArgumentException If type is invalid or number format is incorrect
     */
    public static function formatIdentificationNumber(string $identificationNumber, string $type): string
    {
        


        // Remove any non-numeric characters
        $number = preg_replace('/[^0-9]/', '', $identificationNumber);

        // Validate that we have a number
        if (empty($number)) {
            throw new \InvalidArgumentException("Identification number must contain only numeric characters");
        }

        // Apply formatting based on type
        switch ($type) {
            case '01':
                // Física: Add 3 leading zeros (total 12 digits)
                if (strlen($number) > 9) {
                    throw new \InvalidArgumentException("Física identification number must be up to 9 digits, received: {$number}");
                }
                return str_pad($number, 12, '0', STR_PAD_LEFT);

            case '02':
                // Jurídica: Add 2 leading zeros (total 12 digits)
                if (strlen($number) > 10) {
                    throw new \InvalidArgumentException("Jurídica identification number must be up to 10 digits, received: {$number}");
                }
                return str_pad($number, 12, '0', STR_PAD_LEFT);

            case '03':
                // DIMEX: Add 1 leading zero if 11 digits (total 12 digits)
                if (strlen($number) === 11) {
                    return '0' . $number;
                }
                if (strlen($number) === 12) {
                    return $number;
                }
                throw new \InvalidArgumentException("DIMEX identification number must be 11 or 12 digits, received: {$number}");

            case '04':
                // NITE: Add 2 leading zeros (total 12 digits)
                if (strlen($number) > 10) {
                    throw new \InvalidArgumentException("NITE identification number must be up to 10 digits, received: {$number}");
                }
                return str_pad($number, 12, '0', STR_PAD_LEFT);

            default:
                throw new \InvalidArgumentException("Unknown identification type: {$type}");
        }
    }

    public static function generateUniqueKey(array $dateParsed, string $emisorID, string $idType, string $consecutive, string $situation,string $securityCode): string
    {
        $countryCode = "506";
        $day = $dateParsed['day'];
        $month = $dateParsed['month'];
        $year = $dateParsed['year'];

        // Format identification number (12 digits)
        $formattedId = self::formatIdentificationNumber($emisorID, $idType);

        $dayPart = str_pad((string)$day, 2, '0', STR_PAD_LEFT);
        $monthPart = str_pad((string)$month, 2, '0', STR_PAD_LEFT);
        $yearPart = str_pad((string)$year, 2, '0', STR_PAD_LEFT);

        
        return $countryCode . $dayPart . $monthPart . $yearPart . $formattedId. $consecutive . $situation . $securityCode;
    }




}
