<?php

namespace App\Http\Controllers\Accounts;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Account;
use App\Models\AccountAddress;
use App\Models\AccountBank;
use App\Models\AccountLicense;
use App\Models\MasterType;
use App\Models\MasterCategory;
use App\Models\AccountingGroup;
use App\Models\TaxRegisterCategory;
use App\Models\AccountPayment;
use App\Models\AccountAttachment;
use App\Models\AccountImage;
use App\Models\Country;
use App\Models\CompanyAddress;
use App\Models\AccountContact;
use App\Models\Gender;
use App\Models\MaritalStatus;
use App\Models\BloodGroup;
use App\Models\User;
use App\Models\AccountTitle;
use App\Models\AccountRelativesDetail;
use App\Models\LicenseType;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Carbon\Carbon;
use App\Models\RelationType;
use App\Models\StudentHouse;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\AccountsExport;
use App\Models\AccountSettlementType;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class AccountsController extends Controller
{
    function __construct()
    {
        $this->middleware(function ($request, $next){
            $authRolePermissions = \Session::get('rolePermissions');

            if (!in_array('account-contacts-list', $authRolePermissions)) {
                return redirect('dashboard')->with('info', 'You don\'t have enough permission to access this page.');
            } else {
                return $next($request);
            }
        });
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if (!$this->modulePermissionCheck('ACCOUNTS')) {
            abort(404);
        }
        $status = $request->status ?? 1;
        $data = Account::select([
                'accounts.id',
                'accounts.name',
                'accounts.code',
                'accounts.unique_register_no',
                'accounts.status',
                'accounts.primary_account',
                'accounting_groups.name as group_name',
                'account_addresses.address_line1 as address',
                'countries.name as country',
                'states.name as state',
                'cities.name as city',
                'account_contacts.phone_no',
                'account_contacts.whatsapp_no',
                'account_contacts.email',
                'account_types.type_name as account_type_name',
                'account_titles.name as account_title_name',
                'users.prepared_by'
            ])
            ->leftjoin('account_contacts','account_contacts.account_id','accounts.id')
            ->leftjoin('accounting_groups','accounting_groups.id','accounts.accounting_group_id')
            ->leftjoin('account_types','account_types.id','accounts.account_type_id')
            ->leftjoin('account_addresses','account_addresses.account_id','accounts.id')
            ->leftjoin('account_titles','account_titles.id','accounts.account_title_id')
            ->leftjoin('countries', 'countries.id', 'account_addresses.country_id')
            ->leftjoin('states', 'states.id', 'account_addresses.state_id')
            ->leftjoin('users', 'users.id', 'accounts.created_by')
            ->leftjoin('cities', 'cities.id', 'account_addresses.city_id')
            ->where('accounts.status',$status);

        if ($request->ajax()) {
            $sort_by           = $request->get('sortby') ?? 10;
            $sort_type         = $request->get('sorttype');
            $search_query      = $request->get('query');
            $search_type       = $request->get('search_type');
            $accounting_groups = $request->get('accounting_groups');
            $account_type      = $request->get('account_type');

            $data = $data->when(!empty($search_query) && !empty($search_type),
                function ($query) use ($search_query, $search_type) {
                    if ($search_type == 'code') {
                        $query->where('accounts.code', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'name') {
                        $query->where('accounts.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'address') {
                        $query->where('account_addresses.address_line1', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'city') {
                        $query->where('cities.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'state') {
                        $query->where('states.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'country') {
                        $query->where('countries.name', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'phone') {
                        $query->where('account_contacts.phone_no', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'abha') {
                        $query->where('accounts.abha_no', 'like', '%'.$search_query.'%');
                    } else if ($search_type == 'abha_address') {
                        $query->where('accounts.abha_address', 'like', '%'.$search_query.'%');
                    }
                })
                ->when(!empty($account_type), function($query) use ($account_type) {
                    return $query->where('accounts.account_type_id', $account_type);
                })
                ->when(!empty($accounting_groups), function($query) use ($accounting_groups) {
                    return $query->where('accounts.accounting_group_id', $accounting_groups);
                })
                ->orderBy('accounts.name')
                ->paginate($sort_by);

            return view('accounts.table', compact('data'));
        }
        else
        {
            $accounting_groups = AccountingGroup::select('name', 'id')->get();
            $account_type      = MasterType::select('type_name', 'id')->get();
            $data              = $data->orderBy('accounts.name')->paginate(10);

            return view('accounts.index',compact('data','accounting_groups','account_type'));
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $genders                 = Gender::select(['id','name'])->get();
        $maritalStatus           = MaritalStatus::select(['id','name'])->get();
        $bloodGroup              = BloodGroup::select(['id','group'])->get();
        $account_types           = MasterType::select(['id', 'type_name'])->orderByRaw('is_default DESC, type_name ASC')->get();
        $account_categories      = MasterCategory::select(['id','category_name'])->get();
        $accounting_groups       = AccountingGroup::select(['id','name'])->orderBy('name','asc')->whereNull('deleted_at')->get();
        $account_title           = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $country                 = Country::select(['id','name'])->where('status', '1')->get();
        $company_address           = \Session::get('company_data')['companies_addresses'];
        // dd( $company_address['city_id']  );
        $tax_register_categories = TaxRegisterCategory::select(['id','name'])->whereNull('deleted_at')->get();
        $countryCode             = $company_address->country_code ?? 'us';
        $houses                  = StudentHouse::all();
        // $license_type   = LicenseType::where('is_mandatory', '1')->first();
        // dd(\Session::get('company_data')['companies_addresses']->country_id);

        $license_types = LicenseType::select('id','name','code')->where('is_mandatory', '1')->where('status',1)->get();

        return view('accounts.create', compact([
            'houses',
            'country',
            'company_address',
            'countryCode',
            'account_types',
            'account_categories',
            'tax_register_categories',
            'genders',
            'maritalStatus',
            'bloodGroup',
            'account_title',
            'accounting_groups',
            'license_types',
        ]));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'tax_register_category_id' => 'required',
            'account_type_id'          => 'required',
            'account_category_id'      => 'required',
            'phone_no'                 => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('name', $request->name)
                        ->where('phone_no', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
            'name'                     => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('phone_no', $request->phone_no)
                        ->where('name', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
        ], [
            'required' => 'The :attribute field is required.',
            'unique'   => 'This Name and Phone No are already taken.',
        ]);

        // Check if validation fails
        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->errors()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->errors()->first());
        }

        $type = MasterType::findOrFail($request->account_type_id);

        if (isset($type) && strtolower($type->type_name) != 'student') {
            $rules['accounting_group_id'] = 'required';
        } else {
                    $rules['unique_register_no'] = 'required|unique:accounts,unique_register_no';
        }

        $validator = \Validator::make($request->all(), $rules, [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }
        $company_id         = \Auth::user()->company_id ?? '';
        $data = $request->except([
            '_token',
            '_method',
            'country_id',
            'state_id',
            'cityid',
            'city_id',
            'phone_no',
            'whatsapp_no',
            'address_line1',
            'email',
            'contact',
            'date_of_birth',
            'account_gender_id',
            'blood_group_id',
            'marital_status',
            'any_known_allergies',
            'license_type_id',
            'license_number',
            'valid_from',
            'valid_upto',
            'pin',
            'qualifications'
        ]);
        $data['company_id'] = $company_id;
        $account = Account::create($data);

        if (isset($type) && strtolower($type->type_code) == 'general') {
            $accounting_groups = AccountingGroup::find($request->accounting_group_id);
            $count  = 1;
            $prefix = "AC";
            if($accounting_groups) {
                $count  = $accounting_groups->count != '' ? $accounting_groups->count + 1 : 1;
                $prefix = $accounting_groups->prefix != '' ? $accounting_groups->prefix : "AC";

                $accounting_groups->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }else {
            $count  = 1;
            $prefix = "AC";

            if($type) {
                $count  = $type->count != '' ? $type->count + 1 : 1;
                $prefix = $type->prefix != '' ? $type->prefix : "AC";

                $type->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }

        $account_gender_id = $request->account_gender_id ?? '';

        if (isset($request->account_title_id) && $request->account_title_id != '') {
            $account_title     = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);
            $account_gender_id = $account_title->gender_id ?? '';
        }

        $data = $request->input('license_number');

        if (!is_null($data) && is_array($data)) {
            foreach ($data as $type => $licenseInfo) {
                if (!empty($licenseInfo['license_number'])) {
                    AccountLicense::create([
                        'account_id'      => $account->id,
                        'license_number'  => $licenseInfo['license_number'],
                        'license_type_id' => $licenseInfo['license_type_id'],
                        'valid_from'      => '',
                        'valid_upto'      => '',
                    ]);
                }
            }
        }


        $address = AccountAddress::insert([
            'account_id'    => $account->id,
            'country_id'    => $request->country_id,
            'state_id'      => $request->state_id,
            'city_id'       => $request->city_id,
            'address_line1' => $request->address_line1,
            'post_code'     => $request->pin,
            'is_default'    => '1'
        ]);

        $contact = AccountContact::insert([
            'account_id'          => $account->id,
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no,
            'email'               => $request->email ?? '',
            'name'                => $request->contact ?? '',
            'date_of_birth'       => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : null,
            'account_gender_id'   => $account_gender_id ?? '',
            'blood_group_id'      => $request->blood_group_id ?? '',
            'marital_status'      => $request->marital_status ?? '',
            'any_known_allergies' => $request->any_known_allergies ?? '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,
            'pin'                 => $request->pin,
            'postal_code'         => $request->pin,
            'qualifications'      => $request->qualifications??''
        ]);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been created successfully',
            ]);
        }
        return redirect()->back()
            ->with('success','Account has been created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $company_id      = \Auth::user()->company_id ?? '';
        $company_address = \Session::get('company_data');
        $countryCode     = $company_address['country_code'] ?? 'us';
        $account = Account::select([
                'accounts.*',
                'account_types.type_name',
                'account_categories.category_name',
                'accounting_groups.name as group_name',
                'account_images.image',
                'countries.name as country',
                'states.name as state',
                'cities.name as city',
                'account_contacts.date_of_birth',
                'marital_statuses.name as marital_status',
                'genders.name as gender',
                'blood_groups.group as blood_group',
                'account_contacts.guardian_name',
                'account_contacts.anniversary_date',
                'account_contacts.any_known_allergies',
            ])
            ->leftjoin('account_types','account_types.id','accounts.account_type_id')
            ->leftjoin('account_categories','account_categories.id','accounts.account_category_id')
            ->leftjoin('accounting_groups','accounting_groups.id','accounts.accounting_group_id')
            ->leftjoin('account_images','account_images.account_id','accounts.id')
            ->leftjoin('account_contacts','account_contacts.account_id','accounts.id')
            ->leftjoin('marital_statuses', 'marital_statuses.id', 'account_contacts.marital_status')
            ->leftjoin('countries', 'countries.id', 'account_contacts.country_id')
            ->leftjoin('states', 'states.id', 'account_contacts.state_id')
            ->leftjoin('cities', 'cities.id', 'account_contacts.city_id')
            ->leftjoin('genders', 'genders.id', 'account_contacts.account_gender_id')
            ->leftjoin('blood_groups', 'blood_groups.id', 'account_contacts.blood_group_id')
            ->where('accounts.id', $id)->first();

        if (!$account) {
            return redirect()->back()->with('error', 'Account id is invalid!');
        }

        $relative = AccountRelativesDetail::orderBy('priority', 'ASC')
            ->where('account_id', $id)
            ->first();

        return view('accounts.show', compact('account','countryCode','relative'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $account                 = Account::where('id',$id)->with('first_account_address','account_contact')->first();
        $maritalStatus           = MaritalStatus::select(['id','name'])->get();
        $bloodGroup              = BloodGroup::select(['id','group'])->get();
        $account_types           = MasterType::select(['id','type_name'])->get();
        $account_categories      = MasterCategory::select(['id','category_name'])->get();
        $accounting_groups       = AccountingGroup::select(['id','name'])->where('accounting_type_id',$account->accounting_type_id)->whereNull('deleted_at')->get();
        $account_title           = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $country                 = Country::select(['id','name'])->where('status', '1')->get();
        $tax_register_categories = TaxRegisterCategory::select(['id','name'])->whereNull('deleted_at')->get();
        $houses                  = StudentHouse::all();
        // $types = [
        //     'AADHAAR',
        //     'GST',
        //     'PAN',
        //     'TRANSPORTERID',
        //     'RCMCNO',
        //     'IECODE',
        // ];

        // $account_license = AccountLicense::bykey('license_type_id');
        // dd($account_license);
        // $license_types = LicenseType::select('id','name','code')->whereIn('code', $types)->where('is_mandatory', '1')->get();

        $account_license = AccountLicense::select('id','license_type_id','account_id','license_number')->where('account_id', $id)->get();
        $account_license = $account_license->keyBy('license_type_id');
        // dd($account_license);
        $license_types = LicenseType::select('id', 'name', 'code')->where('status',1)->where('is_mandatory','1')->get();

        return view('accounts.edit', compact([
            'houses',
            'account',
            'country',
            'bloodGroup',
            'account_types',
            'account_title',
            'maritalStatus',
            'accounting_groups',
            'account_categories',
            'tax_register_categories',
            'license_types',
            'account_license'
        ]));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $rules = [
            // 'accounting_group_id' => 'required',
            'name' => 'required',
        ];

        $acc  = Account::find($id);

        if (!$acc) {
            return redirect()->back()->with('error', 'Account not found');
        }

        $type = MasterType::find($acc->account_type_id);

        if (isset($type) && strtolower($type->type_name) != 'student') {
            $rules['accounting_group_id'] = 'required';
        } else {
            $rules['unique_register_no'] = 'required|unique:accounts,unique_register_no,'.$id;
        }

        $validator = \Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method',
            'country_id',
            'state_id',
            'cityid',
            'city_id',
            'phone_no',
            'whatsapp_no',
            'address_line1',
            'email',
            'contact',
            'date_of_birth',
            'account_gender_id',
            'blood_group_id',
            'marital_status',
            'any_known_allergies',
            'license_type_id',
            'license_number',
            'valid_from',
            'valid_upto',
            'qualifications'
        ]);

        $account = Account::find($id);

        if (!$account) {
            return redirect()->route('accounting-groups.index')
                ->with('error','Account not found!');
        }

        $account->update($data);

        $account_gender_id = $request->account_gender_id ?? '';

        if (isset($request->account_title_id) && $request->account_title_id != '') {
            $account_title     = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);
            $account_gender_id = $account_title->gender_id ?? '';
        }

        $data = $request->input('license_number');

        if (!is_null($data) && is_array($data)) {
            foreach ($data as $type => $licenseInfo) {
                if (empty($licenseInfo['license_number'])) {
                    AccountLicense::where([
                        'account_id'      => $account->id,
                        'license_type_id' => $licenseInfo['license_type_id'],
                    ])->delete();
                } else {
                    AccountLicense::updateOrCreate(
                        [
                            'account_id'      => $account->id,
                            'license_type_id' => $licenseInfo['license_type_id'],
                        ],
                        [
                            'license_number'  => $licenseInfo['license_number'],
                            'valid_from'      => '',
                            'valid_upto'      => '',
                        ]
                    );
                }
            }
        }


        $address = AccountAddress::updateOrCreate([
            'account_id'    => $account->id,
            'is_default'    => '1'
        ],[
            'address_line1' => $request->address,
            'country_id'    => $request->country_id,
            'state_id'      => $request->state_id,
            'city_id'       => $request->city_id,
        ]);

        $contact = AccountContact::updateOrCreate([
            'account_id'          => $account->id
        ],[
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no,
            'email'               => $request->email ?? '',
            'name'                => $request->contact ?? '',
            'date_of_birth'       => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : null,
            'account_gender_id'   => $account_gender_id ?? '',
            'blood_group_id'      => $request->blood_group_id ?? '',
            'marital_status'      => $request->marital_status ?? '',
            'any_known_allergies' => $request->any_known_allergies ?? '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,
            'qualifications'      => $request->qualifications??''
        ]);

        return redirect()->route('accounts.index')
            ->with('success','Account has been updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request)
    {
        $account = Account::find($request->id);

        // Find and delete all images of this account
        $account_images = AccountImage::select('image','id')->where('account_id', $request->id)->get();

        foreach($account_images as $value) {
            deleteImage($value->image);

            AccountImage::where('id', $value->id)->delete();
        }

        // Find and delete all attachments of this account
        $account_attachment = AccountAttachment::select('file_name','id')->where('account_id', $request->id)->get();

        foreach($account_attachment as $value) {
            deleteImage($value->file_name);

            AccountAttachment::where('id', $value->id)->delete();
        }

        // Find and delete all Licenses
        AccountLicense::where('account_id', $request->id)->delete();

        // Find and delete all Banks
        AccountBank::where('account_id', $request->id)->delete();

        // Find and delete all Contacts
        AccountContact::where('account_id', $request->id)->delete();

        // Find and delete all Addresses
        AccountAddress::where('account_id', $request->id)->delete();

        // Find and delete all Payments
        AccountPayment::where('account_id', $request->id)->delete();

        $account = $account->delete();

        $Redirect = 'accounts';

        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data'    => [
                'redirect' => $Redirect,
            ]
        ]);
    }

    /**
     * Fetch the specified resource addresses from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function addresses($id)
    {
        $data = AccountAddress::select([
                'account_addresses.*',
                'countries.name as country',
                'address_types.name as address_types',
                'states.name as state',
                'cities.name as city',
            ])
            ->leftjoin('address_types', 'address_types.id', 'account_addresses.address_type_id')
            ->leftjoin('countries', 'countries.id', 'account_addresses.country_id')
            ->leftjoin('states', 'states.id', 'account_addresses.state_id')
            ->leftjoin('cities', 'cities.id', 'account_addresses.city_id')
            ->where('account_id', $id)
            ->whereNull('deleted_at')
            ->orderBy('priority','ASC')
            ->get();

        return view('account-addresses.table', compact('data'));
    }

    public function relatives($id)
    {
        $data = AccountRelativesDetail::orderBy('priority', 'ASC')
            ->where('account_id', $id)
            ->get();

        return view('account-relatives.table', compact('data'));
    }

    public function accountBanks($id)
    {
        $data = AccountBank::where('account_id', $id)->whereNull('deleted_at')->get();

        return view('account-banks.table', compact('data'));
    }

    public function accountLicenses($id)
    {
        $data = AccountLicense::select([
                'account_licenses.*',
                'license_types.name as license_type',
            ])
            ->leftjoin('license_types', 'license_types.id', 'account_licenses.license_type_id')
            ->where('account_id', $id)
            ->whereNull('deleted_at')->get();

        return view('account-licenses.table', compact('data'));
    }

    public function accountPayments($id)
    {
        $data = AccountPayment::select([
                'account_payments.*',
                'payment_modes.mode as mode',
            ])
            ->leftjoin('payment_modes', 'payment_modes.id', 'account_payments.payment_mode_id')
            ->where('account_id', $id)
            ->whereNull('deleted_at')->get();

        return view('account-payments.table', compact('data'));
    }

    public function accountAttachments($id)
    {
        $data = AccountAttachment::where('account_id', $id)->whereNull('deleted_at')->get();

        return view('account-attachments.table', compact('data'));
    }

    public function accountImages($id)
    {
        $data = AccountImage::where('account_id', $id)->whereNull('deleted_at')->get();

        return view('account-images.table', compact('data'));
    }

    public function assignAdminRoles()
    {
        $user = User::find(1);

        $role = Role::find(1);

        $permissions = Permission::pluck('id','id')->all();

        $role->syncPermissions($permissions);

        $user->assignRole([$role->id]);
    }

    public function createPatient(Request $request)
    {
        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('name', '<>', 'M/s.')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id    = $company_address['country_id'] ?? '';
        $state_id      = $company_address['state_id'] ?? '';
        $city_id       = $company_address['city_id'] ?? '';
        $redirect_back = $request->redirect_back ?? '';
        $types         = RelationType::all();
        $maritalStatus           = MaritalStatus::select(['id','name'])->get();
        $bloodGroup              = BloodGroup::select(['id','group'])->get();

        return view('accounts.create-patient', compact(
            'types',
            'country',
            'account_title',
            'country_id',
            'state_id',
            'redirect_back',
            'maritalStatus',
            'bloodGroup',
            'city_id'
        ));
    }

    public function storePatient(Request $request)
    {
        if (!isset($request->date_of_birth) || $request->date_of_birth == '') {
            $ageInYears = $request->year ?? 0;
            $months     = $request->month ?? 0;
            $days       = $request->day ?? 0;
            $hours      = $request->hour ?? 0;

            $currentDate = Carbon::now();
            $dateOfBirth = $currentDate->subYears($ageInYears)->subMonths($months)->subDays($days)->subHours($hours);
            $DOB         = $dateOfBirth->format('Y-m-d H:i:s');
        } else {
            $DOB        = date('Y-m-d H:i:s', strtotime($request->date_of_birth));

            $ageInYears = Carbon::parse($DOB)->age;
        }

        $unique_register_no = $request->unique_register_no;
        $validator = Validator::make($request->all(), [
            // 'date_of_birth' => [
            //     'required',
            //     function ($attribute, $value, $fail) use ($request, $DOB) {
            //         $existingContact = AccountContact::where('date_of_birth', $DOB)
            //             ->where('name', $request->name)
            //             ->first();
            //         if ($existingContact) {
            //             $fail('This Name and Date of birth combination already exists.');
            //         }
            //     }
            // ],
            'name'       => [
                'required',
                function ($attribute, $value, $fail) use ($request, $DOB) {
                    $existingContact = AccountContact::where('date_of_birth', $DOB)
                        ->where('name', $value)
                        ->first();
                    if ($existingContact) {
                        $fail('This Name and Date of birth combination already exists.');
                    }
                }
            ],
            'country_id' => 'required',
        ], [
            'required' => 'The :attribute field is required.',
        ]);
        if($unique_register_no!=''){
            $validator = Validator::make($request->all(), [
                'unique_register_no'=>[
                function ($attribute, $value, $fail) use ($request) {
                    $existingAbhaNo = Account::where('unique_register_no', $request->unique_register_no)
                        ->first();
                    if ($existingAbhaNo) {
                        $fail('This Ayushman Bharat Health Account No already exists.');
                    }
                }],]);
        }


        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->errors()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->errors()->first());
        }

        if (!isset($request->date_of_birth) || $request->date_of_birth == '') {
            $ageInYears = $request->year ?? 0;
            $months     = $request->month ?? 0;
            $days       = $request->day ?? 0;
            $hours      = $request->hour ?? 0;

            $currentDate = Carbon::now();
            $dateOfBirth = $currentDate->subYears($ageInYears)->subMonths($months)->subDays($days)->subHours($hours);
            $DOB         = $dateOfBirth->format('Y-m-d H:i:s');
        } else {
            $DOB        = date('Y-m-d H:i:s', strtotime($request->date_of_birth));

            $ageInYears = Carbon::parse($DOB)->age;
        }

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $type = MasterType::where('type_code', 'PATIENT')->first();
        $accounting_group = AccountingGroup::where('code','SUNDRY_DEBTORS')->first();
        $company_id             = Auth::user()->company_id ?? '';
        $accounting_category    = MasterCategory::select('id','category_name')->where('is_default',1)->first();
        $tax_register_cagtegory = TaxRegisterCategory::select('id','name')->where('is_default',1)->first();
        $sattlement_type        = AccountSettlementType::select('id','name')->where('is_default',1)->first();


        $account = Account::create([
            'name'                     => $request->name,
            'account_title_id'         => $request->account_title_id,
            'account_type_id'          => $type->id ?? '',
            'created_by'               => \Auth::user()->id ?? '',
            'accounting_group_id'      => $accounting_group->id,
            'company_id'               => $company_id,
            'account_category_id'      => $accounting_category->id,
            'tax_register_category_id' => $tax_register_cagtegory->id,
            'settlement_type'          => $sattlement_type->id,
            'unique_register_no'       => $request->unique_register_no,
        ]);

        $account_type = MasterType::find(1);
        $count  = 1;
        $prefix = "PAT";

        if($account_type) {
            $count  = $account_type->count != '' ? $account_type->count + 1 : 1;
            $prefix = $account_type->prefix != '' ? $account_type->prefix : "PAT";

            $account_type->update(['count' => $count]);
        }

        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::create([
            'account_id'    => $account->id,
            'country_id'    => $request->country_id,
            'state_id'      => $request->state_id,
            'city_id'       => $request->city_id,
            'address_line1' => $request->address,
            'post_code'     => $request->postal_code,
            'is_default'    => '1'
        ]);

        $contact = AccountContact::create([
            'account_id'        => $account->id,
            'phone_no'          => str_replace(' ','',$request->phone_no),
            'whatsapp_no'       => $request->whatsapp_no ?? '',
            'email'             => $request->email ?? '',
            'name'              => $request->name ?? '',
            'date_of_birth'     => $DOB,
            'country_id'        => $request->country_id,
            'state_id'          => $request->state_id,
            'city_id'           => $request->city_id,
            'postal_code'       => $request->postal_code,
            'account_gender_id' => $account_title->gender_id ?? '',
            'address'           => $request->address,
            'marital_status'    => $request->marital_status ?? '',
            'blood_group_id'    => $request->blood_group_id ?? ''
        ]);

        if (!empty($request->relation_name) && !empty($request->relation_type) && !empty($request->relation_phone) ) {
            $relative = AccountRelativesDetail::create([
                'account_id'     => $account->id,
                'relation_name'  => $request->relation_name,
                'relation_type'  => $request->relation_type ?? '',
                'relation_phone' => $request->relation_phone ?? ''
            ]);
        }

        $gender = [];

        if ($account_title && isset($account_title->gender_id)) {
            $gender = Gender::find($account_title->gender_id);
        }

        $response = [
            'id'   => $account->id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - (' . $account->code . '), ' . ($gender->name ?? '') . ', ' . ($ageInYears != '' ? $ageInYears . ' Years' : '' ) . ', ' . $contact->phone_no
        ];

        $data = \Session::get('billing_products_cart') ?? [];
        $data['patient_id'] = $account->id;

        \Session::put('billing_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been created successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been created successfully.');
    }

    public function createDoctor()
    {
        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('code', 'like', '%Dr%')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address['country_id'] ?? '';
        $state_id   = $company_address['state_id'] ?? '';
        $city_id    = $company_address['city_id'] ?? '';

        return view('accounts.create-doctor', compact('country','account_title','country_id','state_id','city_id'));
    }

    public function storeDoctor(Request $request)
    {
        $phone_no = (string) $request->phone_no;

        $validator = Validator::make($request->all(), [
            // 'phone_no'   => [
            //     'required',
            //     function ($attribute, $value, $fail) use ($request) {
            //         $existingContact = AccountContact::where('name', $request->name)
            //             ->where('phone_no', $value)
            //             ->first();
            //         if ($existingContact) {
            //             $fail('This Name and Phone No combination already exists.');
            //         }
            //     }
            // ],
            'name'       => [
                'required',
                function ($attribute, $value, $fail) use ($phone_no) {
                    $existingContact = AccountContact::where('phone_no',$phone_no)
                        ->where('name', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
        ], [
            'required' => 'The :attribute field is required.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->errors()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->errors()->first());
        }

        $type                = MasterType::where('type_code', 'DOCTOR')->first();
        $accounting_group    = AccountingGroup::where('name','Sundry Creditors')->first();
        $accounting_category = MasterCategory::select('id','category_name')->where('is_default',1)->first();
        $taxRegisterCategory = TaxRegisterCategory::select('id','name')->where('is_default',1)->first();
        $sattlement          = AccountSettlementType::select('id','name')->where('is_default',1)->first();

        $account = Account::create([
            'name'                     => $request->name,
            'account_title_id'         => $request->account_title_id,
            'account_type_id'          => $type->id ?? '',
            'created_by'               => Auth::user()->id ?? '',
            'accounting_group_id'      => $accounting_group->id,
            'account_category_id'      => $accounting_category->id,
            'tax_register_category_id' => $taxRegisterCategory->id,
            'settlement_type'          => $sattlement->id,
        ]);

        $account_type = MasterType::where('type_code','DOCTOR')->first();
        $count  = 1;
        $prefix = "DRS";

        if($account_type) {
            $count  = $account_type->count != '' ? $account_type->count + 1 : 1;
            $prefix = $account_type->prefix != '' ? $account_type->prefix : "DOC";

            $account_type->update(['count' => $count]);
        }

        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::create([
            'account_id' => $account->id,
            'country_id' => $request->country_id,
            'state_id'   => $request->state_id,
            'city_id'    => $request->city_id,
            'is_default' => '1'
        ]);

        $contact = AccountContact::create([
            'account_id'     => $account->id,
            'phone_no'       => str_replace(' ','',$request->phone_no) ?? '',
            'name'           => $request->name ?? '',
            'country_id'     => $request->country_id,
            'organization'   => $request->organization,
            'qualifications' => $request->qualifications,
        ]);

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $response = [
            'id' => $account->id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - ' . $account->code . ', ' . $request->phone_no
        ];

        $data = \Session::get('billing_products_cart') ?? [];
        $data['doctor_id'] = $account->id;

        \Session::put('billing_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been created successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been created successfully.');
    }

    public function createReferral()
    {
        $country       = Country::select(['id','name'])->get();
        $account_title = AccountTitle::select(['id','name','value'])->where('status', '1')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address->country_id ?? '';
        $state_id   = $company_address->state_id ?? '';
        $city_id    = $company_address->city_id ?? '';

        return view('accounts.create-referral', compact('country','account_title','country_id'));
    }

    public function storeReferral(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'phone_no'   => 'required|unique:account_contacts,phone_no,'.$request->name.',name',
            'name'       => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no',
            'organization' => 'required',
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $type = MasterType::where('type_code', 'REFERRAL_PARTNER')->first();

        $account = Account::create([
            'name'             => $request->name,
            'account_title_id' => $request->account_title_id,
            'account_type_id'  => $type->id ?? '',
            'created_by'       => \Auth::user()->id ?? ''
        ]);

        $account_type = MasterType::find(3);
        $count  = 1;
        $prefix = "REF";

        if($account_type) {
            $count  = $account_type->count != '' ? $account_type->count + 1 : 1;
            $prefix = $account_type->prefix != '' ? $account_type->prefix : "REF";

            $account_type->update(['count' => $count]);
        }

        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::create([
            'account_id'    => $account->id,
            'country_id'    => $request->country_id,
            'state_id'      => $request->state_id,
            'city_id'       => $request->city_id,
            'address_line1' => $request->address,
            'is_default'    => '1'
        ]);

        $contact = AccountContact::create([
            'account_id'          => $account->id,
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no ?? '',
            'email'               => $request->email ?? '',
            'name'                => $request->name ?? '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,
            'organization'   => $request->organization,
        ]);

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $response      = [
            'id'   => $account->id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ', ' . ($account->code ?? '') . ', ' . $request->phone_no
        ];

        $data = \Session::get('billing_products_cart') ?? [];
        $data['refferal_id'] = $account->id;

        \Session::put('billing_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been created successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been created successfully.');
    }

    public function createCollectionAgent()
    {
        $country       = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address->country_id ?? '';
        $state_id   = $company_address->state_id ?? '';
        $city_id    = $company_address->city_id ?? '';

        return view('accounts.create-collection-agent', compact('country','account_title','country_id'));
    }

    public function storeCollectionAgent(Request $request)
    {
        $validator = \Validator::make($request->all(), [
            'phone_no'         => 'required|unique:account_contacts,phone_no,'.$request->name.',name',
            'name'             => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no',
            'account_title_id' => 'required' ,
        ], [
            'unique' => 'This Name and Phone No are already taken.',
            'account_title_id' => 'Account Title is required' ,
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }


        $type = MasterType::where('type_code', 'COLLECTION_AGENT')->first();

        $account = Account::create([
            'name'             => $request->name,
            'account_title_id' => $request->account_title_id,
            'account_type_id'  => $type->id ?? '',
            'created_by'       => \Auth::user()->id ?? ''
        ]);

        $account_type = MasterType::find(4);
        $count  = 1;
        $prefix = "COL";

        if($account_type) {
            $count  = $account_type->count != '' ? $account_type->count + 1 : 1;
            $prefix = $account_type->prefix != '' ? $account_type->prefix : "COL";

            $account_type->update(['count' => $count]);
        }

        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::create([
            'account_id'    => $account->id,
            'country_id'    => $request->country_id,
            'state_id'      => $request->state_id,
            'city_id'       => $request->city_id,
            'address_line1' => $request->address,
            'is_default'    => '1'
        ]);

        $contact = AccountContact::create([
            'account_id'          => $account->id,
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no ?? '',
            'email'               => $request->email ?? '',
            'name'                => $request->name ?? '',
            'date_of_birth'       => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,
        ]);

        $age = '';

        if ($request->date_of_birth != '') {
            $dateOfBirth = \Carbon\Carbon::createFromFormat('Y-m-d', $request->date_of_birth);
            $currentDate = \Carbon\Carbon::now();
            $age         = $dateOfBirth->diffInYears($currentDate);
        }

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $response      = [
            'id'   => $account->id,
            'name' => $account_title->name . ' ' . $request->name . ', ' . $account->code . ($age != '' ? ', ' . $age . ' Years' : '' ) . ', ' . $request->phone_no
        ];

        $data = \Session::get('billing_products_cart') ?? [];
        $data['collection_id'] = $account->id;

        \Session::put('billing_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been created successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been created successfully.');
    }

    public function createRelative($id)
    {
        $types = RelationType::all();
        $priority = AccountRelativesDetail::max('priority');
        $priority = $priority != '' ? $priority : 0;

        return view('account-relatives.create', compact('types','priority'));
    }

    public function editRelative($id)
    {
        $types = RelationType::all();
        $data = AccountRelativesDetail::find($id);

        return view('account-relatives.edit', compact('types', 'data'));
    }

    public function storeRelative(Request $request)
    {
       $validator = \Validator::make($request->all(), [
            'relation_type'       => 'required',
            'relation_name'       => 'required',
            'relation_phone'      => 'required',
            'relation_occupation' => 'required',
            'priority'            => 'required'
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method'
        ]);

        $account = AccountRelativesDetail::create($data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account relative has been created successfully',
            ]);
        }
        return redirect()->back()
            ->with('success','Account relative has been created successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function relativeDestroy(Request $request)
    {
        $data = AccountRelativesDetail::find($request->id);

        $data->delete();

        $Redirect = 'accounts';

        return response()->json([
            'success' => true,
            'message' => ['Deleted successfully'],
            'data'    => [
                'reload' => true,
            ]
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function updateRelative(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'relation_type'       => 'required',
            'relation_name'       => 'required',
            'relation_phone'      => 'required',
            'relation_occupation' => 'required',
            'priority'            => 'required'
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $data = $request->except([
            '_token',
            '_method'
        ]);

        $account = AccountRelativesDetail::whereId($id)->update($data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account relative has been updated successfully',
            ]);
        }
        return redirect()->back()
            ->with('success','Account relative has been updated successfully.');
    }

    public function relativeChangestatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('status' => $request->status );
            $Update = AccountRelativesDetail::where(['id' => $request->id])->update($data);

            if($Update){
                return response()->json([
                    'success'=>true,
                    'message'=>['Account relative status successfully change.'],
                    'data'=>[
                       'reload'=>true,
                    ]
                ]);
            } else {
                return response()->json([
                   'success'=>false,
                   'message'=>['Error for change status'],
                   'data'=>[
                       'redirect'=>'',
                   ]
                ]);
            }
        }
    }

    public function exportAccountsForm()
    {
        $accounting_groups = AccountingGroup::select('name', 'id')->get();
        $account_type      = MasterType::select('type_name', 'id')->get();

        return view('accounts.export-form', compact('accounting_groups', 'account_type'));
    }

    public function exportAccounts(Request $request)
    {
        $filename = "accounts_" . date("Y_m_d_i_H") . ".xlsx";

        return Excel::download(new AccountsExport, $filename);
    }

    public function createParty()
    {
        $country            = Country::select(['id','name'])->get();
        $account_title      = AccountTitle::where('status', '1')->with('gender')->get();
        $company_address    = \Session::get('company_data')['companies_addresses'];
        $account_types      = MasterType::select(['id', 'type_name'])->orderByRaw('is_default DESC, type_name ASC')->get();
        $accounting_groups       = AccountingGroup::select(['id','name'])->orderBy('name','asc')->whereNull('deleted_at')->get();
        $country_id         = $company_address->country_id ?? '';
        $state_id           = $company_address->state_id ?? '';
        $city_id            = $company_address->city_id ?? '';
        $countryCode        = $company_address->country_code ?? 'us';
        $license_types      = LicenseType::select('id','name','code')->where('is_mandatory', '1')->where('status',1)->get();

        return view('accounts.create-party', compact(
            'country',
            'account_title',
            'license_types',
            'country_id',
            'state_id',
            'city_id',
            'account_types',
            'accounting_groups'
        ));
    }

    public function storeParty(Request $request)
    {
        $validator = \Validator::make($request->all(),
        [
            'phone_no'                 => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('name', $request->name)
                        ->where('phone_no', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
            'name'                     => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('phone_no', $request->phone_no)
                        ->where('name', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $type = MasterType::findOrFail($request->account_type_id);
        $company_id             = Auth::user()->company_id ?? '';
        $accounting_category    = MasterCategory::select('id','category_name')->where('is_default',1)->first();
        $tax_register_cagtegory = TaxRegisterCategory::select('id','name')->where('is_default',1)->first();
        $sattlement_type        = AccountSettlementType::select('id','name')->where('is_default',1)->first();

        $account = Account::create([
            'name'                     => $request->name,
            'account_title_id'         => $request->account_title_id,
            'accounting_group_id'      => $request->accounting_group_id,
            'account_type_id'          => $type->id ?? '',
            'created_by'               => \Auth::user()->id ?? '',
            'company_id'               => $company_id,
            'account_category_id'      => $accounting_category->id,
            'tax_register_category_id' => $tax_register_cagtegory->id,
            'settlement_type'          => $sattlement_type->id,
        ]);

        if (isset($type) && strtolower($type->type_code) == 'general') {
            $accounting_groups = AccountingGroup::find($request->accounting_group_id);
            $count  = 1;
            $prefix = "AC";
            if($accounting_groups) {
                $count  = $accounting_groups->count != '' ? $accounting_groups->count + 1 : 1;
                $prefix = $accounting_groups->prefix != '' ? $accounting_groups->prefix : "AC";

                $accounting_groups->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }else {
            $count  = 1;
            $prefix = "AC";

            if($type) {
                $count  = $type->count != '' ? $type->count + 1 : 1;
                $prefix = $type->prefix != '' ? $type->prefix : "AC";

                $type->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }

        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::create([
            'account_id' => $account->id,
            'country_id' => $request->country_id,
            'is_default' => '1'
        ]);

        $data = $request->input('license_number');

        if (!is_null($data) && is_array($data)) {
            foreach ($data as $type => $licenseInfo) {
                if (!empty($licenseInfo['license_number'])) {
                    AccountLicense::create([
                        'account_id'      => $account->id,
                        'license_number'  => $licenseInfo['license_number'],
                        'license_type_id' => $licenseInfo['license_type_id'],
                        'valid_from'      => '',
                        'valid_upto'      => '',
                    ]);
                }
            }
        }

        $contact = AccountContact::create([
            'account_id'    => $account->id,
            'name'          => $request->name ?? '',
            'phone_no'      => str_replace(' ','',$request->phone_no) ?? '',
            'whatsapp_no'   => $request->whatsapp_no,
            'email'         => $request->email ?? '',
            'country_id'    => $request->country_id,
            'address'       => $request->address,
            'postal_code'   => $request->postal_code,
        ]);

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $response = [
            'id' => $account->id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name
        ];

        $data = \Session::get('sales_products_cart') ?? [];
        $data['customer_id'] = $account->id;

        \Session::put('sales_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Customer has been created successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Customer has been created successfully.');
    }
    public function partyEdit($id)
    {
        $account_license   = AccountLicense::select('id','license_type_id','account_id','license_number')->where('account_id', $id)->get();
        $account_license   = $account_license->keyBy('license_type_id');
        $license_types     = LicenseType::select('id', 'name', 'code')->where('status',1)->where('is_mandatory','1')->get();
        $account_types     = MasterType::select(['id', 'type_name'])->orderByRaw('is_default DESC, type_name ASC')->get();
        $accounting_groups = AccountingGroup::select(['id','name'])->orderBy('name','asc')->whereNull('deleted_at')->get();
        $account           = Account::where('id',$id)->with('first_account_address','account_contact')->first();
        $country           = Country::select(['id','name'])->get();
        $account_title     = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $company_address   = \Session::get('company_data')['companies_addresses'];

        $country_id        = $company_address->country_id ?? '';
        $state_id          = $company_address->state_id ?? '';
        $city_id           = $company_address->city_id ?? '';

        return view('accounts.edit-party', compact(
            'country',
            'account_title',
            'country_id',
            'state_id',
            'city_id',
            'account',
            'account_license',
            'license_types',
            'account_types',
            'accounting_groups'
        ));
    }

    public function updateParty(Request $request, $id)
    {
        $contact   = AccountContact::where(['account_id'  => $id])->first();
        $validator = \Validator::make($request->all(), [
            'phone_no'                 => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('name', $request->name)
                        ->where('phone_no', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
            'name'                     => [
                'required',
                function ($attribute, $value, $fail) use ($request) {
                    $existingContact = AccountContact::where('phone_no', $request->phone_no)
                        ->where('name', $value)
                        ->exists();
                    if ($existingContact) {
                        $fail('This Name and Phone No combination already exists.');
                    }
                }
            ],
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        $type = MasterType::where('type_code', 'Customer')->first();

        $account = Account::updateOrCreate([
            'name'                => $request->name,
            'account_title_id'    => $request->account_title_id,
            'account_type_id'     => $type->id ?? '',
            'created_by'          => \Auth::user()->id ?? '',
            'accounting_group_id' => $request->accounting_group_id,

        ]);

        if (isset($type) && strtolower($type->type_code) == 'general') {
            $accounting_groups = AccountingGroup::find($request->accounting_group_id);
            $count  = 1;
            $prefix = "AC";
            if($accounting_groups) {
                $count  = $accounting_groups->count != '' ? $accounting_groups->count + 1 : 1;
                $prefix = $accounting_groups->prefix != '' ? $accounting_groups->prefix : "AC";

                $accounting_groups->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }else {
            $count  = 1;
            $prefix = "AC";

            if($type) {
                $count  = $type->count != '' ? $type->count + 1 : 1;
                $prefix = $type->prefix != '' ? $type->prefix : "AC";

                $type->update(['count' => $count]);
            }

            $enquiry_id = $this->generateCode($count, $prefix);

            $account->update(['code' => $enquiry_id]);
        }


        $code = $this->generateCode($count, $prefix);

        $account->update(['code' => $code]);

        $address = AccountAddress::updateOrCreate([
            'account_id' => $account->id,
            'country_id' => $request->country_id,
            'is_default' => '1'
        ]);

        $data = $request->input('license_number');

        if (!is_null($data) && is_array($data)) {
            foreach ($data as $type => $licenseInfo) {
                if (empty($licenseInfo['license_number'])) {
                    // If license_number is empty, delete the record
                    AccountLicense::where([
                        'account_id'      => $account->id,
                        'license_type_id' => $licenseInfo['license_type_id'],
                    ])->delete();
                } else {
                    // If license_number is not empty, update or create the record
                    AccountLicense::updateOrCreate(
                        [
                            'account_id'      => $account->id,
                            'license_type_id' => $licenseInfo['license_type_id'],
                        ],
                        [
                            'license_number'  => $licenseInfo['license_number'],
                            'valid_from'      => '',
                            'valid_upto'      => '',
                        ]
                    );
                }
            }
        }


        $contact = AccountContact::updateOrCreate([
            'account_id'  => $account->id,
        ],[
            'name'          => $request->name ?? '',
            'phone_no'      => str_replace(' ','',$request->phone_no) ?? '',
            'whatsapp_no'   => $request->whatsapp_no,
            'email'         => $request->email ?? '',
            'country_id'    => $request->country_id,
            'address'       => $request->address,
            'postal_code'   => $request->postal_code,
            'date_of_birth' => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : '',
        ]);

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $response = [
            'id' => $account->id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name
        ];

        $data = \Session::get('sales_products_cart') ?? [];
        $data['customer_id'] = $account->id;

        \Session::put('sales_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been Updated successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been Updated successfully.');
    }

    public function checkPerson()
    {
        $person = MasterType::where('is_person',1)->get();

    }
    public function accountTypePerson(Request $request)
    {
        $accountTypeId = $request->input('accountTypeId');

        $masterType = MasterType::find($accountTypeId);
        // dd($masterType);
        $isPerson = $masterType->is_person ?? '';
        return response()->json(['isPerson' => $isPerson]);
    }


    public function EditDoctorDetails($id)
    {
        $doctor = Account::with('first_account_address', 'account_contact')->where([
                    'id' => $id
                ])->first();

        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address['country_id'] ?? '';
        $state_id   = $company_address['state_id'] ?? '';
        $city_id    = $company_address['city_id'] ?? '';
        return view('accounts.edit-doctor',compact(
            'doctor',
            'country',
            'account_title',
            'country_id',
            'state_id',
            'city_id'
        ));
    }

    public function updateDoctorDetails(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'name'       => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no,id,'.$id,
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }


        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $account = Account::where('id', $id)->first();
        $account->update([
            'name'             => $request->name,
            'account_title_id' => $request->account_title_id,
        ]);

        $address = AccountAddress::where(['account_id' => $id, 'is_default' => '1'])
            ->update([
                'country_id'    => $request->country_id,
            ]);

        $contact = AccountContact::where(['account_id' => $id])->first();
        $contact->update([
                'phone_no'          => str_replace(' ','',$request->phone_no),
                'email'             => $request->email ?? '',
                'name'              => $request->name ?? '',
                'country_id'        => $request->country_id,
                'account_gender_id' => $account_title->gender_id ?? '',
                'organization'      => $request->organization,
                'qualifications'    => $request->qualifications,
            ]);

        $gender = [];

        if ($account_title && isset($account_title->gender_id)) {
            $gender = Gender::find($account_title->gender_id);
        }

        $response = [
            'id'   => $id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - (' . $account->code . '), ' . ($gender->name ?? '') . ', ' . $contact->phone_no
        ];


        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Doctor Account has been updates successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been updates successfully.');
    }


    public function EdiCollectionAgentDetails($id)
    {
        $collectionAgent = Account::with('first_account_address', 'account_contact')->where([
                    'id' => $id
                ])->first();

        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address->country_id ?? '';
        $state_id   = $company_address->state_id ?? '';
        $city_id    = $company_address->city_id ?? '';
        return view('accounts.edit-collection-agent',compact(
            'collectionAgent',
            'country',
            'account_title',
            'country_id',
            'state_id',
            'city_id'
        ));
    }


    public function updateCollectionAgentDetails(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'phone_no'   => 'required|unique:account_contacts,phone_no,'.$request->name.',name,id,'.$id,
            'name'       => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no,id,'.$id,
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }


        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $account = Account::where('id', $id)->first();
        $account->update([
            'name'             => $request->name,
            'account_title_id' => $request->account_title_id,
        ]);

        $address = AccountAddress::where(['account_id' => $id])
            ->update([
                'country_id'    => $request->country_id,
                'state_id'      => $request->state_id,
                'city_id'       => $request->city_id,
                'address_line1' => $request->address,
                'post_code'     => $request->postal_code??'',
            ]);

        $contact = AccountContact::where(['account_id' => $id])->first();
        $contact->update([
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no ?? '',
            'email'               => $request->email ?? '',
            'name'                => $request->name ?? '',
            'date_of_birth'       => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,

            ]);

        $gender = [];

        if ($account_title && isset($account_title->gender_id)) {
            $gender = Gender::find($account_title->gender_id);
        }

        $response = [
            'id'   => $id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - (' . $account->code . '), ' . ($gender->name ?? '') . ', ' . $contact->phone_no
        ];


        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Collection Agent Account has been updates successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been updates successfully.');
    }


    public function EdiReferralAgentDetails($id)
    {
        $referralAgent = Account::with('first_account_address', 'account_contact')->where([
                    'id' => $id
                ])->first();

        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address->country_id ?? '';
        $state_id   = $company_address->state_id ?? '';
        $city_id    = $company_address->city_id ?? '';
        return view('accounts.edit-referral-agent',compact(
            'referralAgent',
            'country',
            'account_title',
            'country_id',
            'state_id',
            'city_id'
        ));
    }

    public function updateReferralAgentDetails(Request $request, $id)
    {
        $validator = \Validator::make($request->all(), [
            'phone_no'   => 'required|unique:account_contacts,phone_no,'.$request->name.',name,id,'.$id,
            'name'       => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no,id,'.$id,
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);

        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }


        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $account = Account::where('id', $id)->first();
        $account->update([
            'name'             => $request->name,
            'account_title_id' => $request->account_title_id,
        ]);

        $address = AccountAddress::where(['account_id' => $id])
            ->update([
                'country_id'    => $request->country_id,
                'state_id'      => $request->state_id,
                'city_id'       => $request->city_id,
                'address_line1' => $request->address,
                'post_code'     => $request->postal_code??'',
            ]);

        $contact = AccountContact::where(['account_id' => $id])->first();
        $contact->update([
            'phone_no'            => str_replace(' ','',$request->phone_no),
            'whatsapp_no'         => $request->whatsapp_no ?? '',
            'email'               => $request->email ?? '',
            'name'                => $request->name ?? '',
            'date_of_birth'       => $request->date_of_birth != '' ? date('Y-m-d', strtotime($request->date_of_birth)) : '',
            'country_id'          => $request->country_id,
            'state_id'            => $request->state_id,
            'city_id'             => $request->city_id,
            'organization'        => $request->organization,

            ]);

        $gender = [];

        if ($account_title && isset($account_title->gender_id)) {
            $gender = Gender::find($account_title->gender_id);
        }

        $response = [
            'id'   => $id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - (' . $account->code . '), ' . ($gender->name ?? '') . ', ' . $contact->phone_no
        ];


        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Referral Agent Account has been updates successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been updates successfully.');
    }


    public function EditPatient(Request $request,$id)
    {
        $patient = Account::with('first_account_address', 'account_contact')->where([
            'id' => $id
        ])->first();

        $country         = Country::select(['id','name'])->get();
        $account_title   = AccountTitle::where('status', '1')->where('code', '<>', 'M/s.')->with('gender')->get();
        $company_address = \Session::get('company_data')['companies_addresses'];

        $country_id = $company_address['country_id'] ?? '';
        $state_id   = $company_address['state_id'] ?? '';
        $city_id    = $company_address['city_id'] ?? '';
        $redirect_back = $request->redirect_back ?? '';
        $types         = RelationType::all();
        $maritalStatus           = MaritalStatus::select(['id','name'])->get();
        $bloodGroup              = BloodGroup::select(['id','group'])->get();

        return view('accounts.edit-patient',compact(
            'patient',
            'country',
            'account_title',
            'country_id',
            'state_id',
            'city_id',
            'redirect_back',
            'types',
            'maritalStatus',
            'bloodGroup'

        ));
    }
    public function UpdatePatient(Request $request, $id)
    {
        //  dd($request);
        $validator = \Validator::make($request->all(), [
            'phone_no'   => 'required|unique:account_contacts,phone_no,'.$request->name.',name,id,'.$id,
            'name'       => 'required|unique:account_contacts,name,'.$request->phone_no.',phone_no,id,'.$id,
            'country_id' => 'required',
        ], [
            'unique' => 'This Name and Phone No are already taken.',
        ]);


        if ($validator->fails()) {
            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->getMessageBag()->first(),
                    'data'    => []
                ]);
            }
            return redirect()->back()->with('error', $validator->getMessageBag()->first());
        }

        if (!isset($request->date_of_birth) || $request->date_of_birth == '') {
            $ageInYears = $request->year ?? 0;
            $months     = $request->month ?? 0;
            $days       = $request->day ?? 0;
            $hours      = $request->hour ?? 0;

            $currentDate = Carbon::now();
            $dateOfBirth = $currentDate->subYears($ageInYears)->subMonths($months)->subDays($days)->subHours($hours);
            $DOB         = $dateOfBirth->format('Y-m-d H:i:s');
        } else {
            $DOB = date('Y-m-d H:i:s', strtotime($request->date_of_birth));

            $ageInYears = Carbon::parse($DOB)->age;
        }

        $account_title = AccountTitle::select(['name','gender_id','id'])->find($request->account_title_id);

        $account = Account::where('id', $id)->first();
        $account->update([
            'name'                      => $request->name,
            'account_title_id'          => $request->account_title_id,
            'unique_register_no'        => $request->unique_register_no,
        ]);

        $address = AccountAddress::where(['account_id' => $id, 'is_default' => '1'])
            ->update([
                'country_id'    => $request->country_id,
                'state_id'      => $request->state_id,
                'city_id'       => $request->city_id,
                'address_line1' => $request->address,
                'post_code'     => $request->postal_code,
            ]);

        $contact = AccountContact::where(['account_id' => $id])->first();
        $contact->update([
                'phone_no'          => str_replace(' ','',$request->phone_no),
                'whatsapp_no'       => $request->whatsapp_no ?? '',
                'email'             => $request->email ?? '',
                'name'              => $request->name ?? '',
                'date_of_birth'     => $DOB,
                'country_id'        => $request->country_id,
                'state_id'          => $request->state_id,
                'city_id'           => $request->city_id,
                'postal_code'       => $request->postal_code,
                'account_gender_id' => $account_title->gender_id ?? '',
                'marital_status'    => $request->marital_status ?? '',
                'blood_group_id'    => $request->blood_group_id ?? ''
            ]);

        if (!empty($request->relation_name) && !empty($request->relation_type) && !empty($request->relation_phone) ) {
            $relative = AccountRelativesDetail::where('account_id',$id)->first();
            if(isset($relative))
            {
                $relative->update([
                    'relation_name'  => $request->relation_name,
                    'relation_type'  => $request->relation_type ?? '',
                    'relation_phone' => $request->relation_phone ?? ''
                ]);
            }
            else
            {
                AccountRelativesDetail::create([
                    'account_id'     => $account->id,
                    'relation_name'  => $request->relation_name,
                    'relation_type'  => $request->relation_type ?? '',
                    'relation_phone' => $request->relation_phone ?? ''
                ]);
            }
            
        }

        $gender = [];

        if ($account_title && isset($account_title->gender_id)) {
            $gender = Gender::find($account_title->gender_id);
        }

        $response = [
            'id'   => $id,
            'name' => ($account_title->name ?? '') . ' ' . $request->name . ' - (' . $account->code . '), ' . ($gender->name ?? '') . ', ' . ($ageInYears != '' ? $ageInYears . ' Years' : '' ) . ', ' . $contact->phone_no
        ];

        $data = \Session::get('billing_products_cart') ?? [];
        $data['patient_id'] = $id;

        \Session::put('billing_products_cart', $data);

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Account has been updates successfully',
                'data'    => $response
            ]);
        }
        return redirect()->route('accounts.index')
            ->with('success','Account has been updates successfully.');
    }

    public function changeStatus(Request $request)
    {
        if ($request->ajax()) {
            $data   = array('status' => $request->status );
            $Update = Account::where('id', '=', $request->id)->update($data);

            if($Update){
                return response()->json([
                    'success'=>true,
                    'message'=>['Account status successfully change'],
                    'data'=>[
                    ]
                ]);
            } else {
                return response()->json([
                   'success'=>false,
                   'message'=>['Error for change status'],
                   'data'=>[
                       'redirect'=>'',
                   ]
                ]);
            }
        }
    }
}
