<?php
/**
 * Consignment Form Model – UPN Delivery Module
 *
 * @category    PortalPeople
 * @package     UPN
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2026 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\upn\models;

use yii\base\Model;

/**
 * ConsignmentForm
 *
 * Validates and builds the payload for a UPN pallet consignment.
 * Maps to the AddConsignment_V4 SOAP API parameters.
 *
 * Main service codes:   1=Priority (P), 2=Standard (S), 3=International (I), 4=Return (R)
 * Additional service:   0=None, 5=Before10, 6=AM/Before12, 7=Timed, 8=SatBefore10,
 *                       9=SatAM, 10=SatTimed, 13=OutOfHours, 25=RestrictedAccess
 * Extra service:        0=None, 11=BookIn, 12=Booked
 * Pallet types:         1=Full, 2=Euro, 3=Half, 4=Quarter, 5=Micro, 6=Quarter+
 * Pallet sizes:         1=Normal, 2=Oversize, 3=OOG2 (up to 2.0m), 4=OOG3 (up to 3.0m)
 */
class ConsignmentForm extends Model
{
    // -------------------------------------------------------------------------
    // Consignment reference
    // -------------------------------------------------------------------------

    /** @var string Customer consignment reference (max 15). */
    public $custRef;

    /** @var string Additional/secondary reference (max 30). */
    public $additionalRef;

    /** @var string Despatch date in YYYY-MM-DD format. Defaults to today if blank. */
    public $despatchDate;

    // -------------------------------------------------------------------------
    // Service selection
    // -------------------------------------------------------------------------

    /**
     * @var int Main delivery service.
     * 1=Priority (next day), 2=Standard (2 days; up to 5 for Scotland),
     * 3=International, 4=Pallet Return.
     */
    public $mainSvc = 1;

    /**
     * @var int Premium/additional service (optional).
     * 0=None, 5=Before 10am, 6=AM/Before 12pm, 7=Timed, 8=Saturday Before 10,
     * 9=Saturday AM, 10=Saturday Timed, 13=Out of Hours, 25=Restricted Access.
     */
    public $additionalSvc = 0;

    /**
     * @var int Extra service (optional).
     * 0=None, 11=Book In (contact delivery point to arrange), 12=Booked (specific day).
     */
    public $extraSvc = 0;

    /** @var int Tail lift required. 1=required, 0=not required. */
    public $tailLift = 0;

    // -------------------------------------------------------------------------
    // Delivery address
    // -------------------------------------------------------------------------

    /** @var string Delivery company/person name (max 100). */
    public $deliveryCoName;

    /** @var string Street / address line 1 (max 100). */
    public $deliveryAdd1;

    /** @var string Address line 2 (max 100). */
    public $deliveryAdd2;

    /** @var string Town (max 100). */
    public $deliveryTown;

    /** @var string County (max 100). */
    public $deliveryCounty;

    /** @var string Full postcode (max 8). */
    public $deliveryPostcode;

    /** @var string Contact name at delivery point (max 100). */
    public $contactName;

    /** @var string Contact phone number (max 15). */
    public $contactPhone;

    /** @var string Contact email address. */
    public $contactEmail;

    // -------------------------------------------------------------------------
    // Pallet / consignment details
    // -------------------------------------------------------------------------

    /**
     * @var int Pallet type.
     * 1=Full, 2=Euro, 3=Half, 4=Quarter, 5=Micro, 6=Quarter+.
     */
    public $palletType = 1;

    /**
     * @var int Pallet size.
     * 1=Normal (up to 1.2m), 2=Oversize (up to 1.5m),
     * 3=OOG2 (up to 2.0m), 4=OOG3 (up to 3.0m).
     */
    public $palletSize = 1;

    /** @var int Number of pallets (all same type and size). */
    public $totalPallets = 1;

    /** @var int Total weight in kilograms. */
    public $totalWeight;

    /** @var string Free text description of pallet contents. */
    public $palletDescription;

    // -------------------------------------------------------------------------
    // Additional options
    // -------------------------------------------------------------------------

    /** @var string Special instructions (max 255). */
    public $specialInstructions;

    /**
     * @var string Scheduled delivery date/time (YYYY-MM-DD HH:MM).
     * Required when Timed (7) or Booked (12) service is selected.
     */
    public $deliveryDateTime;

    /**
     * @var int Paperwork type.
     * 0=None, 1=Electronic paperwork, 2=Hard-copy paperwork.
     */
    public $paperworkType = 0;

    /** @var int Number of pages of customer paperwork. */
    public $custPaperwork = 0;

    /**
     * @var int Local area flag.
     * 0=Network (routed automatically), 1=Local only, or set to a specific depot number.
     */
    public $localArea = 0;

    // -------------------------------------------------------------------------

    /** @inheritdoc */
    public function rules(): array
    {
        return [
            // Required fields
            [['custRef', 'deliveryCoName', 'deliveryAdd1', 'deliveryTown', 'deliveryPostcode', 'totalWeight'], 'required'],

            // String lengths
            [['custRef'], 'string', 'max' => 15],
            [['additionalRef'], 'string', 'max' => 30],
            [['deliveryCoName', 'deliveryAdd1', 'deliveryAdd2', 'deliveryTown', 'deliveryCounty', 'contactName', 'contactEmail'], 'string', 'max' => 100],
            [['deliveryPostcode'], 'string', 'max' => 8],
            [['contactPhone'], 'string', 'max' => 15],
            [['specialInstructions'], 'string', 'max' => 255],
            [['palletDescription'], 'string'],

            // Integer fields
            [['mainSvc'], 'integer', 'min' => 1, 'max' => 4],
            [['additionalSvc'], 'integer', 'min' => 0],
            [['extraSvc'], 'integer', 'min' => 0],
            [['tailLift'], 'boolean'],
            [['palletType'], 'integer', 'min' => 1, 'max' => 6],
            [['palletSize'], 'integer', 'min' => 1, 'max' => 4],
            [['totalPallets'], 'integer', 'min' => 1],
            [['totalWeight'], 'integer', 'min' => 1],
            [['paperworkType'], 'integer', 'min' => 0, 'max' => 2],
            [['custPaperwork'], 'integer', 'min' => 0],
            [['localArea'], 'integer', 'min' => 0],

            // Date fields
            [['despatchDate'], 'date', 'format' => 'php:Y-m-d'],
            [['deliveryDateTime'], 'date', 'format' => 'php:Y-m-d H:i'],

            // Email
            [['contactEmail'], 'email'],

            // Conditional: deliveryDateTime required for Timed or Booked
            [['deliveryDateTime'], 'required', 'when' => function ($model) {
                return in_array((int) $model->additionalSvc, [7, 10]) || (int) $model->extraSvc === 12;
            }, 'whenClient' => "function (attribute, value) {
                var svc = parseInt($('#consignmentform-additionalsvc').val());
                var extra = parseInt($('#consignmentform-extrasvc').val());
                return svc === 7 || svc === 10 || extra === 12;
            }"],

            // Optional nullable
            [['additionalRef', 'deliveryAdd2', 'deliveryCounty', 'contactName', 'contactPhone', 'contactEmail', 'specialInstructions', 'palletDescription', 'deliveryDateTime'], 'default', 'value' => ''],
            [['despatchDate'], 'default', 'value' => date('Y-m-d')],
        ];
    }

    /** @inheritdoc */
    public function attributeLabels(): array
    {
        return [
            'custRef'             => 'Consignment Reference',
            'additionalRef'       => 'Additional Reference',
            'despatchDate'        => 'Despatch Date',
            'mainSvc'             => 'Main Service',
            'additionalSvc'       => 'Additional Service',
            'extraSvc'            => 'Extra Service',
            'tailLift'            => 'Tail Lift Required',
            'deliveryCoName'      => 'Delivery Company / Name',
            'deliveryAdd1'        => 'Address Line 1',
            'deliveryAdd2'        => 'Address Line 2',
            'deliveryTown'        => 'Town',
            'deliveryCounty'      => 'County',
            'deliveryPostcode'    => 'Postcode',
            'contactName'         => 'Contact Name',
            'contactPhone'        => 'Contact Phone',
            'contactEmail'        => 'Contact Email',
            'palletType'          => 'Pallet Type',
            'palletSize'          => 'Pallet Size',
            'totalPallets'        => 'Number of Pallets',
            'totalWeight'         => 'Total Weight (kg)',
            'palletDescription'   => 'Pallet Contents Description',
            'specialInstructions' => 'Special Instructions',
            'deliveryDateTime'    => 'Scheduled Delivery Date/Time',
            'paperworkType'       => 'Paperwork Type',
            'custPaperwork'       => 'Paperwork Pages',
            'localArea'           => 'Local Area',
        ];
    }

    // -------------------------------------------------------------------------
    // Options lists (for views / dropdowns)
    // -------------------------------------------------------------------------

    /** @return array Main service options */
    public static function mainSvcOptions(): array
    {
        return [
            1 => 'Priority (Next Day)',
            2 => 'Standard (2 Day)',
            3 => 'International',
            4 => 'Pallet Return',
        ];
    }

    /** @return array Additional/premium service options */
    public static function additionalSvcOptions(): array
    {
        return [
            0  => 'None',
            5  => 'Before 10am',
            6  => 'AM / Before 12pm',
            7  => 'Timed',
            8  => 'Saturday Before 10am',
            9  => 'Saturday AM',
            10 => 'Saturday Timed',
            13 => 'Out of Hours',
            25 => 'Restricted Access',
        ];
    }

    /** @return array Extra service options */
    public static function extraSvcOptions(): array
    {
        return [
            0  => 'None',
            11 => 'Book In (contact delivery point)',
            12 => 'Booked (specific day)',
        ];
    }

    /** @return array Pallet type options */
    public static function palletTypeOptions(): array
    {
        return [
            1 => 'Full Pallet',
            2 => 'Euro Pallet',
            3 => 'Half Pallet',
            4 => 'Quarter Pallet',
            5 => 'Micro Pallet',
            6 => 'Quarter+ Pallet',
        ];
    }

    /** @return array Pallet size options */
    public static function palletSizeOptions(): array
    {
        return [
            1 => 'Normal (up to 1.2m)',
            2 => 'Oversize (up to 1.5m)',
            3 => 'OOG2 (up to 2.0m)',
            4 => 'OOG3 (up to 3.0m)',
        ];
    }

    /** @return array Paperwork type options */
    public static function paperworkTypeOptions(): array
    {
        return [
            0 => 'No Paperwork',
            1 => 'Electronic Paperwork',
            2 => 'Hard-Copy Paperwork',
        ];
    }

    // -------------------------------------------------------------------------
    // Payload builder
    // -------------------------------------------------------------------------

    /**
     * Build the consignment data array for AddConsignment_V4.
     *
     * @param int $customerId Injected from module config (depot's customer ID)
     * @return array
     */
    public function getConsignmentData(int $customerId = 0): array
    {
        $data = [
            'CustRef'             => $this->custRef,
            'AdditionalRef'       => $this->additionalRef,
            'DespatchDate'        => $this->despatchDate ?: date('Y-m-d'),
            'MainSvc'             => (int) $this->mainSvc,
            'AdditionalSvc'       => (int) $this->additionalSvc,
            'ExtraSvc'            => (int) $this->extraSvc,
            'TailLift'            => (int) $this->tailLift,
            'TotalWeight'         => (int) $this->totalWeight,
            'SpecialInstructions' => $this->specialInstructions,
            'PalletType'          => (int) $this->palletType,
            'PalletSize'          => (int) $this->palletSize,
            'TotalPallets'        => (int) $this->totalPallets,
            'DeliveryCoName'      => $this->deliveryCoName,
            'DeliveryAdd1'        => $this->deliveryAdd1,
            'DeliveryAdd2'        => $this->deliveryAdd2,
            'DeliveryTown'        => $this->deliveryTown,
            'DeliveryCounty'      => $this->deliveryCounty,
            'DeliveryPostcode'    => $this->deliveryPostcode,
            'ContactName'         => $this->contactName,
            'ContactPhone'        => $this->contactPhone,
            'ContactEmail'        => $this->contactEmail,
            'PalletDescription'   => $this->palletDescription,
            'PaperworkType'       => (int) $this->paperworkType,
            'CustPaperwork'       => (int) $this->custPaperwork,
            'LocalArea'           => (int) $this->localArea,
        ];

        if ($customerId > 0) {
            $data['CustomerID'] = $customerId;
        }

        if (!empty($this->deliveryDateTime)) {
            $data['DeliveryDateTime'] = $this->deliveryDateTime;
        }

        return $data;
    }
}
