<?php

declare(strict_types=1);

namespace common\services;

use common\models\Customer;
use common\models\Lead;
use yii\db\Exception;

/**
 * LeadService — business logic for lead management.
 */
class LeadService
{
    /**
     * Create a new lead from API or form input.
     *
     * @param array $data Validated input data
     * @throws Exception
     */
    public function createLead(array $data): Lead
    {
        $lead = new Lead();
        $lead->name     = $data['name'];
        $lead->phone    = $data['phone'];
        $lead->email    = $data['email'] ?? null;
        $lead->source   = $data['source'] ?? null;
        $lead->interest = $data['interest'] ?? null;
        $lead->message  = $data['message'] ?? null;
        $lead->status   = Lead::STATUS_NEW;

        if (!$lead->save()) {
            throw new Exception('Failed to save lead: ' . json_encode($lead->errors));
        }

        return $lead;
    }

    /**
     * Convert a lead into a customer record.
     *
     * @throws Exception
     */
    public function convertToCustomer(Lead $lead, array $extraData = []): Customer
    {
        $transaction = \Yii::$app->db->beginTransaction();

        try {
            $customer = new Customer();
            $customer->name          = $lead->name;
            $customer->phone         = $lead->phone;
            $customer->email         = $lead->email;
            $customer->lead_id       = $lead->id;
            $customer->customer_type = $extraData['customer_type'] ?? Customer::TYPE_INDIVIDUAL;
            $customer->address       = $extraData['address'] ?? null;
            $customer->notes         = $extraData['notes'] ?? null;

            if (!$customer->save()) {
                throw new Exception('Failed to create customer: ' . json_encode($customer->errors));
            }

            $lead->status = Lead::STATUS_CONVERTED;
            if (!$lead->save(false)) {
                throw new Exception('Failed to update lead status.');
            }

            $transaction->commit();
            return $customer;
        } catch (\Throwable $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * Update lead status.
     */
    public function updateStatus(Lead $lead, string $status): bool
    {
        $lead->status = $status;
        return $lead->save(true, ['status', 'updated_at']);
    }

    /**
     * Get dashboard counts using single optimized query.
     */
    public function getDashboardCounts(): array
    {
        $rows = (new \yii\db\Query())
            ->select(['status', 'COUNT(*) AS cnt'])
            ->from('{{%leads}}')
            ->groupBy('status')
            ->all();

        $counts = ['total' => 0, 'new' => 0, 'contacted' => 0, 'converted' => 0, 'lost' => 0];
        foreach ($rows as $row) {
            $counts[$row['status']] = (int)$row['cnt'];
            $counts['total'] += (int)$row['cnt'];
        }

        return $counts;
    }
}
