<?php

namespace Database\Seeders;

use App\Models\AttendanceRecord;
use App\Models\ChurchProfile;
use App\Models\ChurchService;
use App\Models\Jumuiya;
use App\Models\Member;
use App\Models\MemberPosition;
use App\Models\Permission;
use App\Models\Role;
use App\Models\SacramentRecord;
use App\Models\SacramentType;
use App\Models\ServiceType;
use App\Models\Setting;
use App\Models\User;
use App\Models\UserPosition;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $permissions = collect([
            ['module' => 'dashboard', 'action' => 'view', 'label' => 'View Dashboard'],
            ['module' => 'members', 'action' => 'manage', 'label' => 'Manage Members'],
            ['module' => 'jumuiyas', 'action' => 'manage', 'label' => 'Manage Jumuiya / Cells'],
            ['module' => 'services', 'action' => 'manage', 'label' => 'Manage Services / Events'],
            ['module' => 'attendance', 'action' => 'manage', 'label' => 'Manage Attendance'],
            ['module' => 'sacrament', 'action' => 'manage', 'label' => 'Manage Sacrament'],
            ['module' => 'reports', 'action' => 'view', 'label' => 'View Reports'],
            ['module' => 'users', 'action' => 'manage', 'label' => 'Manage System Users'],
            ['module' => 'settings', 'action' => 'manage', 'label' => 'Manage Settings'],
        ])->mapWithKeys(fn (array $permission) => [
            $permission['module'].'.'.$permission['action'] => Permission::firstOrCreate(
                ['module' => $permission['module'], 'action' => $permission['action']],
                ['label' => $permission['label']]
            ),
        ]);

        $roles = collect([
            'super-admin' => ['name' => 'Super Admin', 'description' => 'Access ya kila module ya mfumo.'],
            'admin' => ['name' => 'Admin', 'description' => 'Usimamizi wa kila siku wa mfumo.'],
            'priest' => ['name' => 'Priest / Pastor', 'description' => 'Kuona dashboard, sacrament na reports.'],
            'secretary' => ['name' => 'Secretary', 'description' => 'Members, attendance na reports.'],
            'attendance-officer' => ['name' => 'Attendance Officer', 'description' => 'QR attendance na manual entry.'],
            'sacrament-officer' => ['name' => 'Sacrament Officer', 'description' => 'Sacrament module na reports zake.'],
            'cell-leader' => ['name' => 'Cell Leader', 'description' => 'Kuangalia members na attendance za jumuiya.'],
            'viewer' => ['name' => 'Viewer', 'description' => 'View-only access.'],
        ])->map(function (array $role, string $slug) {
            return Role::firstOrCreate(
                ['slug' => $slug],
                ['name' => $role['name'], 'description' => $role['description'], 'status' => 'active']
            );
        });

        $roles->get('super-admin')->permissions()->sync($permissions->pluck('id'));
        $roles->get('attendance-officer')->permissions()->sync($permissions->only(['attendance.manage', 'reports.view', 'dashboard.view'])->pluck('id'));
        $roles->get('sacrament-officer')->permissions()->sync($permissions->only(['sacrament.manage', 'reports.view', 'dashboard.view'])->pluck('id'));
        $roles->get('secretary')->permissions()->sync($permissions->only(['members.manage', 'attendance.manage', 'reports.view', 'dashboard.view'])->pluck('id'));
        $roles->get('viewer')->permissions()->sync($permissions->only(['dashboard.view', 'reports.view'])->pluck('id'));

        $userPositions = collect([
            'Priest',
            'Assistant Priest',
            'Church Secretary',
            'Treasurer',
            'Attendance Officer',
            'Sacrament Officer',
            'Cell Leader',
            'Choir Leader',
            'Youth Leader',
            'Women Leader',
            'Men Leader',
            'Admin',
        ])->mapWithKeys(fn (string $name) => [$name => UserPosition::firstOrCreate(['name' => $name], ['status' => 'active'])]);

        $memberPositions = collect([
            'Normal Member',
            'Cell Leader',
            'Choir Member',
            'Youth Member',
            'Women Fellowship Member',
            'Men Fellowship Member',
            'Church Elder',
            'Treasurer',
            'Secretary',
        ])->mapWithKeys(fn (string $name) => [$name => MemberPosition::firstOrCreate(['name' => $name], ['status' => 'active'])]);

        $serviceTypes = collect([
            'Sunday Service',
            'Morning Prayer',
            'Evening Prayer',
            'Bible Study',
            'Choir Practice',
            'Youth Service',
            'Women Fellowship',
            'Men Fellowship',
            'Special Service',
        ])->mapWithKeys(fn (string $name) => [$name => ServiceType::firstOrCreate(['name' => $name], ['status' => 'active'])]);

        $sacramentTypes = collect(['Holy Communion', 'Baptism', 'Confirmation', 'Marriage'])
            ->mapWithKeys(fn (string $name) => [$name => SacramentType::firstOrCreate(['name' => $name], ['status' => 'active'])]);

        $admin = User::updateOrCreate(
            ['email' => 'admin@stpeterpaul.local'],
            [
                'name' => 'Church Administrator',
                'first_name' => 'Church',
                'middle_name' => null,
                'last_name' => 'Administrator',
                'phone' => '+255700000001',
                'username' => 'admin',
                'password' => 'password',
                'role_id' => $roles->get('super-admin')->id,
                'user_position_id' => $userPositions->get('Admin')->id,
                'status' => 'active',
            ]
        );

        ChurchProfile::updateOrCreate(
            ['id' => 1],
            [
                'church_name' => 'Anglican Church St Peter and Paul',
                'diocese' => 'Diocese of Dar es Salaam',
                'parish' => 'Mwenge Kijitonyama',
                'location' => 'Mwenge Kijitonyama',
                'phone' => '+255700000000',
                'email' => 'info@stpeterpaulmwenge.local',
                'address' => 'Anglican Church St Peter and Paul, Mwenge Kijitonyama, Dar es Salaam',
            ]
        );

        collect([
            ['group' => 'registration', 'key' => 'is_open', 'value' => 'No'],
            ['group' => 'registration', 'key' => 'default_member_status', 'value' => 'inactive'],
            ['group' => 'registration', 'key' => 'intro_text', 'value' => 'Jisajili kama member wa Anglican Church St Peter and Paul Mwenge Kijitonyama.'],
        ])->each(fn (array $setting) => Setting::firstOrCreate(
            ['group' => $setting['group'], 'key' => $setting['key']],
            ['value' => $setting['value']]
        ));

        $jumuiyas = collect([
            ['name' => 'Mt. Petro', 'code' => 'JUM-PETRO', 'leader_name' => 'John Peter', 'assistant_leader' => 'Grace Michael', 'location' => 'Mwenge', 'phone' => '+255711111111'],
            ['name' => 'Mt. Paulo', 'code' => 'JUM-PAULO', 'leader_name' => 'Mary Joseph', 'assistant_leader' => 'Emmanuel Lucas', 'location' => 'Kijitonyama', 'phone' => '+255722222222'],
            ['name' => 'Mt. Andrea', 'code' => 'JUM-ANDREA', 'leader_name' => 'Agnes Gabriel', 'assistant_leader' => 'Daniel Thomas', 'location' => 'Mpakani', 'phone' => '+255733333333'],
        ])->mapWithKeys(fn (array $jumuiya) => [
            $jumuiya['code'] => Jumuiya::updateOrCreate(['code' => $jumuiya['code']], $jumuiya + ['status' => 'active']),
        ]);

        $members = collect([
            ['ACM-00001', 'Mary', 'John', 'Peter', 'Female', '+255744100001', 'JUM-PETRO', 'Choir Member', true, true, true],
            ['ACM-00002', 'John', 'Michael', 'Peter', 'Male', '+255744100002', 'JUM-PETRO', 'Normal Member', true, true, true],
            ['ACM-00003', 'Neema', 'Joseph', 'Komba', 'Female', '+255744100003', 'JUM-PAULO', 'Women Fellowship Member', true, false, false],
            ['ACM-00004', 'Daniel', 'Thomas', 'Lema', 'Male', '+255744100004', 'JUM-ANDREA', 'Youth Member', true, true, true],
            ['ACM-00005', 'Grace', 'Michael', 'Msuya', 'Female', '+255744100005', 'JUM-PETRO', 'Cell Leader', true, true, true],
            ['ACM-00006', 'Emmanuel', 'Lucas', 'Sanga', 'Male', '+255744100006', 'JUM-PAULO', 'Church Elder', true, true, true],
        ])->map(function (array $member) use ($jumuiyas, $memberPositions) {
            return Member::updateOrCreate(
                ['member_code' => $member[0]],
                [
                    'first_name' => $member[1],
                    'middle_name' => $member[2],
                    'last_name' => $member[3],
                    'gender' => $member[4],
                    'phone' => $member[5],
                    'email' => Str::lower($member[1].'.'.$member[3]).'@example.test',
                    'address' => 'Mwenge Kijitonyama',
                    'jumuiya_id' => $jumuiyas->get($member[6])->id,
                    'member_position_id' => $memberPositions->get($member[7])->id,
                    'is_baptized' => $member[8],
                    'is_confirmed' => $member[9],
                    'is_allowed_sacrament' => $member[10],
                    'qr_token' => 'CHURCH-MEMBER-'.Str::upper(Str::random(24)),
                    'status' => 'active',
                    'date_registered' => now()->subDays(random_int(2, 45))->toDateString(),
                ]
            );
        });

        $service = ChurchService::updateOrCreate(
            ['name' => 'Sunday Main Service', 'service_date' => now()->toDateString()],
            [
                'service_type_id' => $serviceTypes->get('Sunday Service')->id,
                'start_time' => '08:00:00',
                'end_time' => '10:30:00',
                'location' => 'Anglican Church St Peter and Paul Mwenge Kijitonyama',
                'status' => 'open',
                'created_by' => $admin->id,
                'description' => 'Ibada kuu ya Jumapili.',
            ]
        );

        $members->take(4)->each(function (Member $member) use ($service, $admin) {
            AttendanceRecord::updateOrCreate(
                ['member_id' => $member->id, 'church_service_id' => $service->id],
                [
                    'attendance_date' => $service->service_date,
                    'time_in' => now()->format('H:i:s'),
                    'method' => $member->id % 2 === 0 ? 'manual' : 'qr',
                    'marked_by' => $admin->id,
                    'status' => 'present',
                ]
            );
        });

        $members->where('is_allowed_sacrament', true)->take(3)->each(function (Member $member) use ($service, $sacramentTypes, $admin) {
            SacramentRecord::updateOrCreate(
                [
                    'member_id' => $member->id,
                    'church_service_id' => $service->id,
                    'sacrament_type_id' => $sacramentTypes->get('Holy Communion')->id,
                ],
                [
                    'sacrament_date' => $service->service_date,
                    'status' => 'participated',
                    'recorded_by' => $admin->id,
                    'remarks' => 'Recorded from initial setup data.',
                ]
            );
        });
    }
}
