<?php

namespace Rtc\PlantShopWC\Frontend\Models;

use Rtc\PlantShopWC\Admin\Models\GeneralSettingsModel;
use Rtc\PlantShopWC\Admin\Modules\BotanicalName;
use Rtc\PlantShopWC\Admin\Modules\Neighbors;

class CartModel {


	public function get_neighbors( array $contents, $checked, bool $filterExcluded = false ): array {
		$neighbors      = new Neighbors();
		$botanical_name = new BotanicalName();

		$get_product = function ( $item ) {
			if ( isset( $item['data'] ) && is_object( $item['data'] ) && method_exists( $item['data'], 'get_id' ) ) {
				return $item['data'];
			}
			if ( is_object( $item ) && method_exists( $item, 'get_product' ) ) {
				return $item->get_product();
			}
			if ( is_object( $item ) && method_exists( $item, 'get_id' ) && method_exists( $item, 'get_name' ) ) {
				return $item;
			}
			return null;
		};

		// Only filter when explicitly requested (email/PDF case)
		if ( $filterExcluded ) {
			$contents = array_values(
				array_filter(
					$contents,
					function ( $item ) use ( $get_product ) {
						$product = $get_product( $item );
						return $product && GeneralSettingsModel::is_product_included( $product );
					}
				)
			);
		}

		if ( empty( $contents ) ) {
			return array(
				'good_neighbors' => array(),
				'bad_neighbors'  => array(),
			);
		}

		$cartById = array();
		foreach ( $contents as $item ) {
			$product = $get_product( $item );
			if ( ! $product ) {
				continue;
			}
			$pid = (int) $product->get_id();
			if ( $pid <= 0 ) {
				continue;
			}
			$title = (string) $product->get_name();
			$name  = $title;
			if ( $checked ) {
				$maybe = $botanical_name->build( $product, $title, true );
				if ( ! empty( $maybe ) ) {
					$name = $maybe;
				}
			}
			$cartById[ $pid ] = $name;
		}

		$edges = array(
			'good_neighbors' => array(),
			'bad_neighbors'  => array(),
		);
		foreach ( $contents as $item ) {
			$product = $get_product( $item );
			if ( ! $product ) {
				continue;
			}
			$fromId = (int) $product->get_id();
			if ( $fromId <= 0 || ! isset( $cartById[ $fromId ] ) ) {
				continue;
			}
			$fromDisplay = $cartById[ $fromId ];
			$data        = (array) $neighbors->get( $fromId );

			foreach ( array( 'good_neighbors', 'bad_neighbors' ) as $type ) {
				foreach ( ( $data[ $type ] ?? array() ) as $row ) {
					$toId = (int) ( $row['id'] ?? 0 );
					$note = trim( (string) ( $row['note'] ?? '' ) );
					if ( $toId <= 0 || $toId === $fromId || ! isset( $cartById[ $toId ] ) ) {
						continue;
					}
					$directKey = $fromId . '||' . $toId;
					if ( ! isset( $edges[ $type ][ $directKey ] ) || ( $note !== '' && $edges[ $type ][ $directKey ]['note'] === '' ) ) {
						$edges[ $type ][ $directKey ] = array(
							'from' => $fromDisplay,
							'to'   => $cartById[ $toId ],
							'note' => $note,
						);
					}
				}
			}
		}

		$result = array(
			'good_neighbors' => array(),
			'bad_neighbors'  => array(),
		);
		foreach ( array( 'good_neighbors', 'bad_neighbors' ) as $type ) {
			$groups = array();
			foreach ( $edges[ $type ] as $dk => $edge ) {
				[$a, $b]                = array_map( 'intval', explode( '||', $dk, 2 ) );
				$ukey                   = ( $a < $b ? "$a||$b" : "$b||$a" );
				$groups[ $ukey ][ $dk ] = $edge;
			}
			foreach ( $groups as $ukey => $dirEdges ) {
				[$a, $b] = array_map( 'intval', explode( '||', $ukey, 2 ) );
				$abKey   = "$a||$b";
				$baKey   = "$b||$a";
				$AtoB    = $dirEdges[ $abKey ] ?? null;
				$BtoA    = $dirEdges[ $baKey ] ?? null;
				if ( $AtoB && $BtoA ) {
					$noteA = trim( (string) $AtoB['note'] );
					$noteB = trim( (string) $BtoA['note'] );
					if ( $noteA !== '' && $noteB !== '' ) {
						$result[ $type ][] = $AtoB;
						$result[ $type ][] = $BtoA;
					} elseif ( $noteA !== '' ) {
							$result[ $type ][] = $AtoB;
					} elseif ( $noteB !== '' ) {
						$result[ $type ][] = $BtoA;
					} else {
						$result[ $type ][] = $AtoB;
					}
				} else {
					if ( $AtoB ) {
						$result[ $type ][] = $AtoB;
					}
					if ( $BtoA ) {
						$result[ $type ][] = $BtoA;
					}
				}
			}
		}
		return $result;
	}
}
