<?php
require_once __DIR__ . '/../Core.php';
require_once __DIR__ . '/Contact.php';

class ContactList extends Model
{
    public function all(): array
    {
        $sql = "SELECT cl.*, COUNT(clm.id) AS member_count
                FROM contact_lists cl
                LEFT JOIN contact_list_members clm ON clm.list_id = cl.id
                GROUP BY cl.id
                ORDER BY cl.created_at DESC, cl.name ASC";
        return $this->db->query($sql)->fetchAll();
    }

    public function find(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM contact_lists WHERE id = ? LIMIT 1');
        $stmt->execute([$id]);
        return $stmt->fetch() ?: null;
    }

    public function create(array $data): int
    {
        $stmt = $this->db->prepare('INSERT INTO contact_lists (name, channel, description, created_by) VALUES (?, ?, ?, ?)');
        $stmt->execute([
            trim((string)($data['name'] ?? 'Untitled List')),
            in_array(($data['channel'] ?? 'both'), ['sms','email','both'], true) ? $data['channel'] : 'both',
            trim((string)($data['description'] ?? '')) ?: null,
            $data['created_by'] ?? null,
        ]);
        return (int)$this->db->lastInsertId();
    }

    public function delete(int $id): bool
    {
        $this->db->prepare('DELETE FROM contact_list_members WHERE list_id = ?')->execute([$id]);
        return $this->db->prepare('DELETE FROM contact_lists WHERE id = ?')->execute([$id]);
    }

    public function addMember(int $listId, int $contactId): void
    {
        $stmt = $this->db->prepare('INSERT IGNORE INTO contact_list_members (list_id, contact_id) VALUES (?, ?)');
        $stmt->execute([$listId, $contactId]);
    }

    public function contactsForChannel(int $listId, string $channel): array
    {
        $where = $channel === 'sms'
            ? 'c.phone IS NOT NULL AND c.phone != "" AND c.unsubscribed_sms = 0'
            : 'c.email IS NOT NULL AND c.email != "" AND c.unsubscribed_email = 0';
        $stmt = $this->db->prepare("SELECT c.* FROM contact_list_members clm INNER JOIN contacts c ON c.id = clm.contact_id WHERE clm.list_id = ? AND {$where} ORDER BY c.created_at DESC");
        $stmt->execute([$listId]);
        return $stmt->fetchAll();
    }

    private function normalizedHeaders(array $headers): array
    {
        return array_map(function ($header) {
            $value = strtolower(trim((string)$header));
            $value = preg_replace('/[^a-z0-9]+/', '_', $value) ?: '';
            return trim($value, '_');
        }, $headers);
    }

    private function canonicalRecord(array $record): array
    {
        $aliases = [
            'firstname' => 'first_name',
            'first' => 'first_name',
            'given_name' => 'first_name',
            'lastname' => 'last_name',
            'last' => 'last_name',
            'surname' => 'last_name',
            'mobile' => 'phone',
            'phone_number' => 'phone',
            'email_address' => 'email',
            'e_mail' => 'email',
            'organization' => 'company',
            'tag' => 'tags',
            'tz' => 'timezone',
            'stage' => 'lifecycle_stage',
        ];
        foreach ($aliases as $from => $to) {
            if (!array_key_exists($to, $record) && array_key_exists($from, $record)) {
                $record[$to] = $record[$from];
            }
        }
        return $record;
    }

    public function importCsv(int $listId, string $path): array
    {
        if ($listId <= 0 || !$this->find($listId)) {
            throw new RuntimeException('Please choose a valid saved list.');
        }
        $handle = fopen($path, 'r');
        if (!$handle) {
            throw new RuntimeException('Unable to open CSV file.');
        }
        $headers = $this->normalizedHeaders(fgetcsv($handle) ?: []);
        if (!$headers) {
            fclose($handle);
            throw new RuntimeException('The CSV file is empty or missing headers.');
        }
        $contactModel = new Contact();
        $stats = ['processed' => 0, 'new' => 0, 'existing' => 0, 'skipped' => 0];
        while (($row = fgetcsv($handle)) !== false) {
            $record = array_combine($headers, array_pad($row, count($headers), '')) ?: [];
            $record = $this->canonicalRecord($record);
            if (empty($record['first_name']) && empty($record['email']) && empty($record['phone'])) {
                $stats['skipped']++;
                continue;
            }
            $result = $contactModel->createOrReuse([
                'first_name' => $record['first_name'] ?? 'Contact',
                'last_name' => $record['last_name'] ?? '',
                'phone' => $record['phone'] ?? null,
                'email' => $record['email'] ?? null,
                'company' => $record['company'] ?? null,
                'tags' => $record['tags'] ?? null,
                'timezone' => $record['timezone'] ?? config('app.timezone', 'America/Chicago'),
                'lifecycle_stage' => $record['lifecycle_stage'] ?? 'lead',
                'score' => (int)($record['score'] ?? 0),
            ]);
            $this->addMember($listId, (int)$result['id']);
            $stats['processed']++;
            $stats[$result['created'] ? 'new' : 'existing']++;
        }
        fclose($handle);
        return $stats;
    }
}
