<?php

namespace SplitPay\Integrations\FluentCart\Adapters;

use SplitPay\Contracts\OrderAdapterInterface;
use SplitPay\Contracts\TransferableItem;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class FCOrderAdapter implements OrderAdapterInterface {

	private object $order;
	private object $transaction;

	public function __construct( object $order, object $transaction ) {
		$this->order       = $order;
		$this->transaction = $transaction;
	}

	public function getOrderId(): int {
		return (int) $this->order->id;
	}

	private function getOrderItemsFromDb(): array {
		global $wpdb;
		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}fct_order_items WHERE order_id = %d",
				$this->order->id
			)
		) ?: [];
	}

	private function centsToDecimal( $cents ): float {
		return (float) $cents / 100.0;
	}

	private function getProductSplitPaySettings( int $productId ): array {
		global $wpdb;
		$raw = $wpdb->get_var( $wpdb->prepare(
			"SELECT meta_value FROM {$wpdb->prefix}fct_product_meta WHERE object_id = %d AND object_type = 'product_integration' AND meta_key = 'split_pay_connect' LIMIT 1",
			$productId
		) );

		if ( ! empty( $raw ) ) {
			$data = json_decode( $raw, true );
			if ( is_array( $data ) && ! empty( $data['connected_account'] ) ) {
				return [
					'connected_accounts'   => [ 0 => $data['connected_account'] ],
					'transfer_types'       => [ 0 => $data['transfer_type'] ?? 'percentage' ],
					'transfer_percentages' => [ 0 => $data['transfer_percentage'] ?? '' ],
					'transfer_amounts'     => [ 0 => $data['transfer_amount'] ?? '' ],
					'shipping_types'       => [ 0 => $data['shipping_transfer_type'] ?? 'none' ],
					'shipping_percentages' => [ 0 => $data['shipping_transfer_percentage'] ?? '' ],
					'shipping_amounts'     => [ 0 => $data['shipping_transfer_amount'] ?? '' ],
				];
			}
		}

		$accts = get_post_meta( $productId, '_bsd_spscwt_product_connected_account', true );
		if ( ! empty( $accts ) && is_array( $accts ) ) {
			return [
				'connected_accounts'   => $accts,
				'transfer_types'       => get_post_meta( $productId, '_bsd_spscwt_product_type', true ) ?: [],
				'transfer_percentages' => get_post_meta( $productId, '_stripe_connect_split_pay_transfer_percentage', true ) ?: [],
				'transfer_amounts'     => get_post_meta( $productId, '_bsd_spscwt_product_amount', true ) ?: [],
				'shipping_types'       => get_post_meta( $productId, '_bsd_spscwt_shipping_type', true ) ?: [],
				'shipping_percentages' => get_post_meta( $productId, '_bsd_prod_shipping_percentage', true ) ?: [],
				'shipping_amounts'     => get_post_meta( $productId, '_bsd_spscwt_shipping_amount', true ) ?: [],
			];
		}

		return [
			'connected_accounts'   => [],
			'transfer_types'       => [],
			'transfer_percentages' => [],
			'transfer_amounts'     => [],
			'shipping_types'       => [],
			'shipping_percentages' => [],
			'shipping_amounts'     => [],
		];
	}

	/** @return TransferableItem[] */
	public function getItems(): array {
		$items      = [];
		$orderItems = $this->getOrderItemsFromDb();

		if ( empty( $orderItems ) ) {
			return $items;
		}

		foreach ( $orderItems as $orderItem ) {
			$productId = (int) ( $orderItem->post_id ?? 0 );

			if ( $productId === 0 ) {
				continue;
			}

			$settings = $this->getProductSplitPaySettings( $productId );

			$connectedAccounts   = $settings['connected_accounts'];
			$transferTypes       = $settings['transfer_types'];
			$transferPercentages = $settings['transfer_percentages'];
			$transferAmounts     = $settings['transfer_amounts'];

			$shippingTransferSettings = [
				'types'       => is_array( $settings['shipping_types'] ) ? $settings['shipping_types'] : [],
				'percentages' => is_array( $settings['shipping_percentages'] ) ? $settings['shipping_percentages'] : [],
				'amounts'     => is_array( $settings['shipping_amounts'] ) ? $settings['shipping_amounts'] : [],
			];

			$transferLevel = empty( $connectedAccounts ) ? 'global' : 'product';

			$quantity  = (int) ( $orderItem->quantity ?? 1 );
			$lineTotal = $this->centsToDecimal( $orderItem->line_total ?? 0 );
			$unitPrice = $this->centsToDecimal( $orderItem->unit_price ?? 0 );

			$items[] = new TransferableItem(
				$productId,
				'fluent-products',
				$quantity,
				$unitPrice,
				$lineTotal,
				0.0,
				[],
				0.0,
				is_array( $connectedAccounts ) ? $connectedAccounts : [],
				is_array( $transferTypes ) ? $transferTypes : [],
				is_array( $transferPercentages ) ? $transferPercentages : [],
				is_array( $transferAmounts ) ? $transferAmounts : [],
				$shippingTransferSettings,
				$transferLevel
			);
		}

		return apply_filters( 'spp_fc_order_transferable_items', $items, $this->order );
	}

	public function getSubtotal(): float {
		return $this->centsToDecimal( $this->order->subtotal ?? $this->order->total_amount ?? 0 );
	}

	public function getShippingTotal(): float {
		return $this->centsToDecimal( $this->order->shipping_total ?? 0 );
	}

	public function getShippingMethods(): array {
		return [];
	}

	public function getTaxItems(): array {
		return [];
	}

	public function getCoupons(): array {
		global $wpdb;

		$table = $wpdb->prefix . 'fct_applied_coupons';
		$rows  = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT * FROM {$table} WHERE order_id = %d",
				$this->order->id
			),
			ARRAY_A
		);

		return is_array( $rows ) ? $rows : [];
	}

	public function getCurrency(): string {
		if ( ! empty( $this->order->currency ) ) {
			return strtolower( $this->order->currency );
		}

		return 'usd';
	}

	public function getCustomerInfo(): array {
		$customer = $this->order->customer ?? null;

		if ( $customer === null ) {
			return [
				'first_name' => '',
				'last_name'  => '',
				'email'      => '',
			];
		}

		$fullName  = $customer->full_name ?? '';
		$nameParts = explode( ' ', trim( $fullName ), 2 );

		return [
			'first_name' => $nameParts[0] ?? '',
			'last_name'  => $nameParts[1] ?? '',
			'email'      => $customer->email ?? '',
		];
	}

	/** @return mixed */
	public function getOrderMeta( string $key ) {
		global $wpdb;

		$table = $wpdb->prefix . 'fct_order_meta';

		return $wpdb->get_var(
			$wpdb->prepare(
				"SELECT meta_value FROM {$table} WHERE order_id = %d AND meta_key = %s LIMIT 1",
				$this->order->id,
				$key
			)
		);
	}

	public function setOrderMeta( string $key, $value ): void {
		global $wpdb;

		$table    = $wpdb->prefix . 'fct_order_meta';
		$existing = $this->getOrderMeta( $key );

		if ( $existing !== null ) {
			$wpdb->update(
				$table,
				[ 'meta_value' => $value ],
				[
					'order_id' => $this->order->id,
					'meta_key' => $key,
				]
			);
		} else {
			$wpdb->insert(
				$table,
				[
					'order_id'   => $this->order->id,
					'meta_key'   => $key,
					'meta_value' => $value,
				]
			);
		}
	}

	public function addOrderNote( string $note ): void {
		global $wpdb;

		$table = $wpdb->prefix . 'fct_activity';

		$wpdb->insert(
			$table,
			[
				'status'      => 'success',
				'log_type'    => 'activity',
				'module_type' => 'FluentCart\\App\\Models\\Order',
				'module_id'   => $this->order->id,
				'module_name' => 'Split Pay',
				'title'       => 'Split Pay Transfer',
				'content'     => $note,
				'read_status' => 'unread',
				'created_by'  => 'Split Pay Plugin',
				'created_at'  => current_time( 'mysql', true ),
				'updated_at'  => current_time( 'mysql', true ),
			]
		);
	}

	public function isTransferProcessed(): bool {
		return $this->getOrderMeta( 'spp_transfer_processed' ) === '1';
	}

	public function markTransferProcessed(): void {
		$this->setOrderMeta( 'spp_transfer_processed', '1' );
	}
}
