<?php

namespace App\Services\Character;

use App\Services\Api\API;

class ItemManagementService
{
    protected API $api;

    public function __construct(API $api)
    {
        $this->api = $api;
    }

    /**
     * Process item updates for a section (pocket, equipment, storehouse)
     */
    public function processItemUpdates(int $roleId, array $currentItems, array $newItems, string $section): array
    {
        $messages = [];
        $updatedCount = 0;
        $addedCount = 0;
        $deletedCount = 0;
        
        // Build list of positions in new items
        $newPositions = [];
        foreach ($newItems as $newItem) {
            if (($newItem['id'] ?? 0) > 0) {
                $newPositions[] = $newItem['pos'] ?? -1;
            }
        }
        
        // Check for items to delete (exist in current but not in new)
        foreach ($currentItems as $currentItem) {
            $currentPos = $currentItem['pos'] ?? -1;
            $currentId = $currentItem['id'] ?? 0;
            if ($currentId > 0 && !in_array($currentPos, $newPositions)) {
                $result = $this->api->deleteItem($roleId, $currentPos, $section);
                if ($result['success']) {
                    $deletedCount++;
                }
            }
        }
        
        // Process new/updated items
        foreach ($newItems as $newItem) {
            $itemPos = $newItem['pos'] ?? null;
            if ($itemPos === null) continue;
            
            // Skip if item ID is 0 or not set
            $newItemId = $newItem['id'] ?? 0;
            if ($newItemId <= 0) continue;
            
            // Find current item by pos
            $currentItem = null;
            foreach ($currentItems as $ci) {
                if (($ci['pos'] ?? -1) == $itemPos) {
                    $currentItem = $ci;
                    break;
                }
            }
            
            // If slot is empty, add new item
            if (!$currentItem || ($currentItem['id'] ?? 0) <= 0) {
                $result = $this->api->addItem($roleId, $itemPos, $newItem, $section);
                if ($result['success']) {
                    $addedCount++;
                }
                continue;
            }
            
            // Check if any field changed
            if ($this->hasItemChanges($newItem, $currentItem)) {
                $result = $this->api->updateItem($roleId, $itemPos, $newItem, $section);
                if ($result['success']) {
                    $updatedCount++;
                }
            }
        }
        
        return [
            'updated_count' => $updatedCount,
            'added_count' => $addedCount,
            'deleted_count' => $deletedCount,
            'message' => "$updatedCount modified, $addedCount added, $deletedCount deleted"
        ];
    }

    /**
     * Process money updates for inventory section
     */
    public function processMoneyUpdate(int $roleId, int $newMoney, int $oldMoney, string $section): bool
    {
        if ($newMoney == $oldMoney) {
            return true;
        }

        $result = match($section) {
            'pocket' => $this->api->updatePocketMoney($roleId, $newMoney),
            'storehouse' => $this->api->updateStorehouseMoney($roleId, $newMoney),
            default => ['success' => false, 'message' => 'Invalid section']
        };

        return $result['success'] ?? false;
    }

    /**
     * Check if item data has changed
     */
    private function hasItemChanges(array $newItem, array $currentItem): bool
    {
        $itemFields = ['id', 'count', 'max_count', 'data', 'proctype', 'expire_date', 'guid1', 'guid2', 'mask'];
        foreach ($itemFields as $field) {
            if (array_key_exists($field, $newItem) && ($newItem[$field] ?? null) !== ($currentItem[$field] ?? null)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get inventory data for a section
     */
    public function getSectionData(int $roleId, string $section): ?array
    {
        return match($section) {
            'pocket' => $this->api->getRoleInventory($roleId),
            'equipment' => $this->api->getRoleEquipment($roleId),
            'storehouse' => $this->api->getRoleStorehouse($roleId),
            default => null
        };
    }

    /**
     * Get items array from section data
     */
    public function getItemsFromSection(array $sectionData, string $section): array
    {
        $itemKey = match($section) {
            'pocket' => 'inv',
            'equipment' => 'eqp',
            'storehouse' => 'store',
            default => ''
        };

        return $itemKey ? ($sectionData[$itemKey] ?? []) : [];
    }

    /**
     * Get money from section data
     */
    public function getMoneyFromSection(array $sectionData, string $section): int
    {
        return $sectionData['money'] ?? 0;
    }

    /**
     * Handle section update with money and items
     */
    public function handleSectionUpdate(int $roleId, array $validatedData, string $section): array
    {
        $currentSectionData = $this->getSectionData($roleId, $section);
        if (!$currentSectionData) {
            return ['error' => "Failed to get {$section} data"];
        }

        $messages = [];

        // Handle items update
        if (isset($validatedData[$this->getItemsKey($section)])) {
            $currentItems = $this->getItemsFromSection($currentSectionData, $section);
            $result = $this->processItemUpdates($roleId, $currentItems, $validatedData[$this->getItemsKey($section)], $section);
            $messages[] = $result['message'];
        }

        // Handle money update
        if (isset($validatedData['money'])) {
            $newMoney = (int) $validatedData['money'];
            $oldMoney = $this->getMoneyFromSection($currentSectionData, $section);
            $success = $this->processMoneyUpdate($roleId, $newMoney, $oldMoney, $section);
            if ($success) {
                $messages[] = "money updated";
            }
        }

        return [
            'success' => true,
            'message' => ucfirst($section) . " updated successfully (" . implode(', ', $messages) . ")"
        ];
    }

    /**
     * Get the items key for a section
     */
    private function getItemsKey(string $section): string
    {
        return match($section) {
            'pocket' => 'inv',
            'equipment' => 'eqp',
            'storehouse' => 'store',
            default => ''
        };
    }
}
