<?php

namespace Licenzo\Http\Controller\Api\V1;

use Licenzo\Helper\Action;
use Licenzo\Framework\Http\Request;
use Licenzo\Model\Customer;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Customer API controller for managing customers
 */
class CustomerController
{
    /**
     * List customers with pagination and filtering
     */
    public function index(Request $request)
    {
        $accountType = $request->getSafe('account_type', 'sanitize_text_field');

        $customers = Customer::query()
            ->when($accountType === 'wordpress', function ($query) {
                $query->whereNotNull('user_id');
            })
            ->when($accountType === 'external', function ($query) {
                $query->whereNull('user_id');
            })
            ->orderBy('created_at', 'desc')
            ->search($request->getSafe('search', 'sanitize_text_field'))
            ->withCount(['subscriptions'])
            ->paginate();

        \Licenzo\Framework\Support\Helper::tap($customers, function ($customers) {
            $customers->getCollection()->transform(function ($customer) {

                $customer->purchases_count = $customer->subscriptions_count;

                $customer->lifetime_value = $customer->lifetime_value;
                $lastTransaction = $customer->transactions()->latest()->first();
                $customer->last_purchase_date = $lastTransaction ? $lastTransaction->created_at->format('Y-m-d H:i:s') : null;
                $customer->is_user = !empty($customer->user_id);

                unset($customer->subscriptions_count);
                return $customer;
            });
        });


        return [
            'success' => true,
            'customers' => $customers,
        ];
    }

    /**
     * Store a newly created customer
     */
    public function store(Request $request)
    {
        $data = $request->getSafe([
            'first_name' => 'sanitize_text_field',
            'last_name'  => 'sanitize_text_field',
            'email'      => 'sanitize_email',
            'user_id'    => 'sanitize_text_field',
        ]);

        if (empty($data['first_name']) || empty($data['last_name']) || empty($data['email'])) {
            return [
                'success' => false,
                'message' => __('First name, last name, and email are required.', 'licenzo')
            ];
        }

        // Check email uniqueness
        $existingCustomer = Customer::where('email', $data['email'])->first();
        if ($existingCustomer) {
            return [
                'success' => false,
                'message' => __('Email already exists in customers.', 'licenzo')
            ];
        }
        // check if user_id exists in customers
        if (!empty($data['user_id'])) {
            $existingUserCustomer = Customer::where('user_id', $data['user_id'])->first();
            if ($existingUserCustomer) {
                return [
                    'success' => false,
                    'message' => __('This user is already associated with another customer.', 'licenzo')
                ];
            }
        }

        // Manage backend-only fields
        $data['ip'] = $request->ip();
        $data['settings'] = wp_json_encode([]);

        // Create customer
        $customer = Customer::create([
            'first_name' => $data['first_name'],
            'last_name'  => $data['last_name'],
            'email'      => $data['email'],
            'user_id'    => $data['user_id'] ?? null,
            'provider'   => 'manual',
            'provider_id'=> null,
            'ip'         => $data['ip'],
            'settings'   => $data['settings'],
        ]);

        Action::do('notification_customer_welcome', [
            'source' => 'admin_customer_store',
            'customer' => (array) $customer->toArray(),
        ]);

        return [
            'success'  => true,
            'message'  => __('Customer Created Successfully', 'licenzo'),
            'customer' => $customer,
        ];
    }

    /**
     * Display a single customer
     */
    public function show($id)
    {
        $queryLimit = function ($query) {
            return $query->take(5);
        };

        $customer = Customer::with([
            'subscriptions' => $queryLimit,
            'licenses',
            'products',
            'transactions'  => $queryLimit,
            'activities'    => $queryLimit,
        ])->find($id);

        if (!$customer) {
            return [
                'success' => false,
                'message' => __('Customer not found.', 'licenzo'),
                'status' => 404,
            ];
        }

        $customer->purchases_count = $customer->subscriptions->count();
        $customer->lifetime_value = $customer->lifetime_value;
        $customer->last_purchase_date = $customer->last_purchase_date;

        // add a customer WordPress profile link here
        if ($customer->user_id) {
            $customer->profile_link = get_edit_user_link($customer->user_id);
        }

        return [
            'success' => true,
            'customer' => $customer,
        ];
    }


    /**
     * Update a customer
     */
    public function update(Request $request, $id)
    {
        $customer = Customer::find($id);

        if (!$customer) {
            return [
                'success' => false,
                'message' => __('Customer not found.', 'licenzo'),
            ];
        }

        $data = $request->getSafe([
            'first_name' => 'sanitize_text_field',
            'last_name'  => 'sanitize_text_field',
            'email'      => 'sanitize_email',
            'user_id'    => 'sanitize_text_field',
        ]);

        if (empty($data['first_name']) || empty($data['last_name']) || empty($data['email'])) {
            return [
                'success' => false,
                'message' => __('First name, last name, and email are required.', 'licenzo')
            ];
        }


        // Check email uniqueness for other customers
        $existingCustomer = Customer::where('email', $data['email'])
            ->where('id', '!=', $customer->id)
            ->first();

        if ($existingCustomer) {
            return [
                'success' => false,
                'message' => __('Email already exists for another customer.', 'licenzo')
            ];
        }

        // Check user_id uniqueness for other customers
        if (!empty($data['user_id'])) {
            $existingUserCustomer = Customer::where('user_id', $data['user_id'])
                ->where('id', '!=', $customer->id)
                ->first();
            if ($existingUserCustomer) {
                return [
                    'success' => false,
                    'message' => __('This user is already associated with another customer.', 'licenzo')
                ];
            }
        }

        // Backend-managed fields remain unchanged
        $data['ip'] = $customer->ip;
        $data['settings'] = $customer->settings;

        $customer->update($data);

        return [
            'success'  => true,
            'message'  => __('Customer Updated Successfully', 'licenzo'),
            'customer' => $customer,
        ];
    }

    /**
     * Delete a customer
     */
    public function destroy($id)
    {
        $customer = Customer::find($id);

        if (!$customer) {
            return [
                'success' => false,
                'message' => __('Customer not found.', 'licenzo'),
            ];
        }

        $customer->delete();

        return [
            'success' => true,
            'message' => __('Customer deleted successfully.', 'licenzo'),
        ];
    }

    /**
     * Search customers
     */
    public function allCustomers(Request $request)
    {
        $search = $request->getSafe('search', 'sanitize_text_field');

        $customers = \Licenzo\Model\Customer::query()
            ->when($search, function ($query) use ($search) {
                $query->where(function ($q) use ($search) {
                    $q->where('first_name', 'LIKE', "%{$search}%")
                        ->orWhere('last_name', 'LIKE', "%{$search}%")
                        ->orWhere('email', 'LIKE', "%{$search}%");
                });
            })
            ->orderBy('first_name', 'asc')
            ->limit(20)
            ->get();

        // tap
        \Licenzo\Framework\Support\Helper::tap($customers, function ($customers) {
            $customers->transform(function ($customer) {
                return [
                    'id'    => $customer->id,
                    'first_name' => $customer->first_name,
                    'last_name'  => $customer->last_name,
                    'email' => $customer->email,
                    'is_user' => !empty($customer->user_id),
                ];
            });
        });

        return [
            'success' => true,
            'customers' => $customers,
        ];
    }


    public function getCustomerSubscription($id, Request $request)
    {
        $customer = $this->findCustomerOrError($id);
        if (is_array($customer)) {
            return $customer;
        }

        $search = $request->getSafe('search', 'sanitize_text_field');
        $status = $request->getSafe('status', 'sanitize_text_field');

        $subscriptions = $customer->subscriptions()
            ->with(['subscriptionProducts'])
            ->when($search, function ($query) use ($search) {
                $query->search($search);
            })
            ->when($status, function ($query) use ($status) {
                $query->where('status', $status);
            })
            ->orderBy('created_at', 'desc')
            ->paginate();

        return [
            'success' => true,
            'subscriptions' => $subscriptions,
        ];
    }

    public function getCustomerLicense($id, Request $request)
    {
        $customer = $this->findCustomerOrError($id);
        if (is_array($customer)) {
            return $customer;
        }

        $search = $request->getSafe('search', 'sanitize_text_field');
        $status = $request->getSafe('status', 'sanitize_text_field');

        $licenses = $customer->licenses()
            ->with('subscription')
            ->when($search, function ($query) use ($search) {
                $query->search($search);
            })
            ->when($status, function ($query) use ($status) {
                $query->where('status', $status);
            })
            ->orderBy('created_at', 'desc')
            ->paginate();

        $licenses = \Licenzo\Framework\Support\Helper::tap($licenses, function ($licenses) {

            $licenses->transform(function ($license) {
                $billingCycle = $license->subscription ? $license->subscription->billing_cycle : null;
                return [
                    'id'               => $license->id,
                    'license_key'      => $license->license_key,
                    'status'           => $license->status,
                    'activation_count' => $license->activation_count,
                    'activation_limit' => $license->activation_limit,
                    'expiration_date'  => $this->normalizeDateTimeValue($license->expire_date),
                    'billing_cycle'    => $billingCycle,
                ];
            });
        });

        return [
            'success' => true,
            'licenses' => $licenses,
        ];
    }



    public function getCustomerTransactions($id, Request $request)
    {
        $customer = $this->findCustomerOrError($id);
        if (is_array($customer)) {
            return $customer;
        }

        $status     = $request->getSafe('status', 'sanitize_text_field');
        $start_date = $request->getSafe('start_date', 'sanitize_text_field');
        $end_date   = $request->getSafe('end_date', 'sanitize_text_field');

        $transactions = $customer->transactions()
            ->when($status, function ($q) use ($status) {
                $q->where('transaction_type', $status);
            })
            ->when($start_date && $end_date, function ($q) use ($start_date, $end_date) {
                $q->whereBetween('created_at', [$start_date, $end_date]);
            })
            ->orderBy('created_at', 'desc')
            ->paginate();

        \Licenzo\Framework\Support\Helper::tap($transactions, function ($transactions) {
            $transactions->getCollection()->transform(function ($transaction) {
                return [
                    'id'                  => $transaction->id,
                    'transaction_type'    => $transaction->transaction_type,
                    'total'               => $transaction->total ?? 0,
                    'status'              => $transaction->status,
                    'created_at'          => $transaction->created_at ? $transaction->created_at->format('Y-m-d H:i:s') : null,
                    'provider'            => $transaction->provider,
                    'payment_method'      => $transaction->payment_method,
                    'card_brand'          => $transaction->card_brand,
                    'card_last_4'         => $transaction->card_last_4,
                ];
            });
        });

        return [
            'success' => true,
            'transactions' => $transactions,
        ];
    }

    /**
     * Backward-compatible alias for legacy typoed endpoint method.
     */
    public function getCustomerTransection($id, Request $request)
    {
        return $this->getCustomerTransactions($id, $request);
    }

    public function getCustomerProducts($id, Request $request)
    {
        $customer = $this->findCustomerOrError($id);
        if (is_array($customer)) {
            return $customer;
        }

        $search = $request->getSafe('search', 'sanitize_text_field');
        $status = $request->getSafe('status', 'sanitize_text_field');

        $productsQuery = $customer->products()->with('license', 'variation');
        if ($search) {
            $productsQuery->where('product_name', 'LIKE', "%{$search}%");
        }
        if ($status) {
            $productsQuery->whereHas('license', function ($q) use ($status) {
                $q->where('status', $status);
            });
        }

        $products = $productsQuery->orderBy('id', 'asc')->paginate();
        // Transform products for API
        $products = \Licenzo\Framework\Support\Helper::tap($products, function ($products) {
            $products->getCollection()->transform(function ($product) {
                $variation = $product->variation;
                $license = $product->license;

                return [
                    'product_name'     => $product->product_name,
                    'variation_name'   => $product->variation_name,
                    'activation_count' => $product->activation_count,
                    'expiration_date'  => $license && $license->expire_date ? $license->expire_date->format('Y-m-d H:i:s') : null,
                    'status'           => $license ? $license->status : 'inactive',
                    'created_at'       => $product->created_at,
                ];
            });
        });
        return ['success' => true, 'products' => $products];
    }

    /**
     * Normalize mixed date/datetime model values into a stable API string.
     *
     * @param mixed $value
     * @return string|null
     */
    private function normalizeDateTimeValue($value)
    {
        if (empty($value)) {
            return null;
        }

        if ($value instanceof \DateTimeInterface) {
            return $value->format('Y-m-d H:i:s');
        }

        if (is_numeric($value)) {
            $timestamp = (int) $value;
            return $timestamp > 0 ? gmdate('Y-m-d H:i:s', $timestamp) : null;
        }

        if (is_string($value)) {
            $timestamp = strtotime($value);
            return $timestamp ? gmdate('Y-m-d H:i:s', $timestamp) : null;
        }

        return null;
    }

    /**
     * Resolve customer or return a standardized not-found API response payload.
     *
     * @param int|string $id
     * @return \Licenzo\Model\Customer|array
     */
    private function findCustomerOrError($id)
    {
        $customer = Customer::find($id);
        if ($customer) {
            return $customer;
        }

        return [
            'success' => false,
            'message' => __('Customer not found.', 'licenzo'),
            'status' => 404,
        ];
    }
}
