<?php

namespace App\Services\Whatsapp;

use App\Models\WhatsappGroupMembership;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class WhatsappContactService
{
    public function __construct(private WhatsappContextService $context)
    {
    }

    public function listParentContacts(?string $schoolYear, ?string $semester): array
    {
        $schoolYear = trim((string) $schoolYear);
        $semester = trim((string) $semester);

        $builder = DB::table('parents as sp');
        $builder->select("
            sp.id AS parents_row_id,
            sp.firstparent_id AS firstparent_id,
            sp.secondparent_firstname AS sp_firstname,
            sp.secondparent_lastname AS sp_lastname,
            sp.secondparent_email AS sp_email,
            sp.secondparent_phone AS sp_phone,
            sp.school_year AS sp_school_year,
            sp.semester AS sp_semester,
            u.id AS u_id,
            u.firstname AS u_firstname,
            u.lastname AS u_lastname,
            u.email AS u_email,
            u.cellphone AS u_phone,
            u.school_year AS u_school_year,
            u.semester AS u_semester
        ");
        $builder->leftJoin('users as u', 'u.id', '=', 'sp.firstparent_id');

        if ($schoolYear !== '') {
            $builder->where('sp.school_year', $schoolYear);
        }
        if ($semester !== '') {
            $builder->where('sp.semester', $semester);
        }

        $rows = $builder->get()->all();

        $contacts = [];
        foreach ($rows as $row) {
            $r = (array) $row;
            if (!empty($r['u_id'])) {
                $contacts[] = [
                    'firstname' => (string) ($r['u_firstname'] ?? ''),
                    'lastname' => (string) ($r['u_lastname'] ?? ''),
                    'email' => (string) ($r['u_email'] ?? ''),
                    'phone' => (string) ($r['u_phone'] ?? ''),
                    'type' => 'Primary Parent',
                ];
            }

            $hasSecond = !empty($r['sp_firstname']) || !empty($r['sp_lastname']) || !empty($r['sp_email']) || !empty($r['sp_phone']);
            if ($hasSecond) {
                $contacts[] = [
                    'firstname' => (string) ($r['sp_firstname'] ?? ''),
                    'lastname' => (string) ($r['sp_lastname'] ?? ''),
                    'email' => (string) ($r['sp_email'] ?? ''),
                    'phone' => (string) ($r['sp_phone'] ?? ''),
                    'type' => 'Second Parent',
                ];
            }
        }

        $contacts = array_values(array_filter($contacts, function ($c) {
            $name = trim(($c['firstname'] ?? '') . ($c['lastname'] ?? ''));
            $contact = trim(($c['phone'] ?? '') . ($c['email'] ?? ''));
            return $name !== '' || $contact !== '';
        }));

        usort($contacts, function ($a, $b) {
            $la = strtolower($a['lastname'] ?? '');
            $lb = strtolower($b['lastname'] ?? '');
            if ($la !== $lb) {
                return $la <=> $lb;
            }
            $fa = strtolower($a['firstname'] ?? '');
            $fb = strtolower($b['firstname'] ?? '');
            if ($fa !== $fb) {
                return $fa <=> $fb;
            }
            $ta = ($a['type'] ?? '') === 'Primary Parent' ? 0 : 1;
            $tb = ($b['type'] ?? '') === 'Primary Parent' ? 0 : 1;
            return $ta <=> $tb;
        });

        return $contacts;
    }

    public function listParentContactsByClass(?string $schoolYear, ?string $semester): array
    {
        $schoolYear = trim((string) $schoolYear);
        $semester = trim((string) $semester);

        $sections = DB::table('student_class as sc')
            ->select('sc.class_section_id', DB::raw('MAX(sc.school_year) AS school_year'))
            ->when($schoolYear !== '', fn ($q) => $q->where('sc.school_year', $schoolYear))
            ->groupBy('sc.class_section_id')
            ->orderBy('sc.class_section_id', 'ASC')
            ->get()
            ->all();

        $sectionIds = array_values(array_filter(array_unique(array_map(
            fn ($r) => (int) ($r->class_section_id ?? 0),
            $sections
        ))));

        $namesById = [];
        if (!empty($sectionIds)) {
            $nameRows = DB::table('classSection')
                ->select('class_section_id', 'class_section_name')
                ->whereIn('class_section_id', $sectionIds)
                ->get()
                ->all();

            foreach ($nameRows as $row) {
                $namesById[(int) $row->class_section_id] = (string) ($row->class_section_name ?? '');
            }
        }

        $classSections = [];
        foreach ($sections as $s) {
            $sid = (int) ($s->class_section_id ?? 0);
            if (!$sid) {
                continue;
            }

            $classSections[$sid] = [
                'class_section_id' => $sid,
                'class_section_name' => $namesById[$sid] ?? ('Section ' . $sid),
                'semester' => $semester,
                'school_year' => (string) ($s->school_year ?? ''),
                'description' => '',
                'main_teachers' => [],
                'teacher_assistants' => [],
                'parents' => [],
            ];
        }

        $rows = DB::table('student_class as sc')
            ->select([
                'sc.class_section_id',
                'u.id as primary_id',
                'u.firstname as primary_firstname',
                'u.lastname as primary_lastname',
                'u.email as primary_email',
                'u.cellphone as primary_phone',
                'sp.id as second_id',
                'sp.secondparent_firstname as second_firstname',
                'sp.secondparent_lastname as second_lastname',
                'sp.secondparent_email as second_email',
                'sp.secondparent_phone as second_phone',
            ])
            ->join('students as s', 's.id', '=', 'sc.student_id')
            ->join('users as u', 'u.id', '=', 's.parent_id')
            ->leftJoin('parents as sp', function ($join) {
                $join->on('sp.firstparent_id', '=', 'u.id')
                    ->on('sp.school_year', '=', 'sc.school_year');
            })
            ->when($schoolYear !== '', fn ($q) => $q->where('sc.school_year', $schoolYear))
            ->orderBy('sc.class_section_id', 'ASC')
            ->orderBy('u.lastname', 'ASC')
            ->orderBy('u.firstname', 'ASC')
            ->get()
            ->all();

        $seen = [];
        foreach ($rows as $row) {
            $r = (array) $row;
            $sid = (int) ($r['class_section_id'] ?? 0);
            $pid = (int) ($r['primary_id'] ?? 0);
            if (!$sid || !$pid || !isset($classSections[$sid])) {
                continue;
            }

            $key = $sid . ':' . $pid;
            if (isset($seen[$key])) {
                continue;
            }
            $seen[$key] = true;

            $classSections[$sid]['parents'][] = [
                'class_section_id' => $sid,
                'primary_id' => $pid,
                'primary_name' => trim(($r['primary_lastname'] ?? '') . ', ' . ($r['primary_firstname'] ?? '')),
                'primary_phone' => (string) ($r['primary_phone'] ?? ''),
                'primary_email' => (string) ($r['primary_email'] ?? ''),
                'second_id' => (int) ($r['second_id'] ?? 0),
                'second_name' => trim(($r['second_lastname'] ?? '') . ', ' . ($r['second_firstname'] ?? '')),
                'second_phone' => (string) ($r['second_phone'] ?? ''),
                'second_email' => (string) ($r['second_email'] ?? ''),
                'primary_member' => null,
                'second_member' => null,
            ];
        }

        try {
            $sectionIds = array_keys($classSections);
            $membershipMap = WhatsappGroupMembership::getBySectionsAndTerm($sectionIds, $schoolYear, $semester);
            foreach ($classSections as $sid => &$section) {
                foreach ($section['parents'] as &$parent) {
                    $key = sprintf('%d:primary:%d', (int) $parent['class_section_id'], (int) $parent['primary_id']);
                    if (isset($membershipMap[$key])) {
                        $parent['primary_member'] = (int) ($membershipMap[$key]['is_member'] ?? 0);
                    }

                    $secondId = (int) ($parent['second_id'] ?? 0);
                    if ($secondId > 0) {
                        $key2 = sprintf('%d:second:%d', (int) $parent['class_section_id'], $secondId);
                        if (isset($membershipMap[$key2])) {
                            $parent['second_member'] = (int) ($membershipMap[$key2]['is_member'] ?? 0);
                        }
                    }
                }
                unset($parent);
            }
            unset($section);
        } catch (\Throwable $e) {
            Log::warning('WhatsApp membership lookup failed: ' . $e->getMessage());
        }

        try {
            $teachers = DB::table('teacher_class as tc')
                ->select('tc.class_section_id', 'tc.position', 'u.firstname', 'u.lastname')
                ->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
                ->when($schoolYear !== '', fn ($q) => $q->where('tc.school_year', $schoolYear))
                ->get()
                ->all();

            foreach ($teachers as $row) {
                $r = (array) $row;
                $sid = (int) ($r['class_section_id'] ?? 0);
                if (!isset($classSections[$sid])) {
                    continue;
                }
                $name = trim(($r['lastname'] ?? '') . ', ' . ($r['firstname'] ?? ''));
                $pos = strtolower((string) ($r['position'] ?? 'main'));
                if ($pos === 'ta' || $pos === 'assistant') {
                    $classSections[$sid]['teacher_assistants'][] = $name;
                } else {
                    $classSections[$sid]['main_teachers'][] = $name;
                }
            }
        } catch (\Throwable $e) {
            Log::warning('WhatsApp teacher list lookup failed: ' . $e->getMessage());
        }

        foreach ($classSections as &$section) {
            $section['main_teachers'] = array_values(array_filter($section['main_teachers'] ?? []));
            $section['teacher_assistants'] = array_values(array_filter($section['teacher_assistants'] ?? []));
            $section['parents'] = array_values($section['parents'] ?? []);
        }
        unset($section);

        return array_values($classSections);
    }
}
