import {modals} from "@mantine/modals";
import React, {useMemo, useState, useEffect} from "react";
import {
    ActionIcon,
    Button, Checkbox,
    type ComboboxItem, CopyButton,
    Group,
    NumberInput,
    type OptionsFilter, Radio,
    Select,
    Stack,
    Text,
    TextInput, Tooltip,
    Table,
    MultiSelect,
    Textarea
} from "@mantine/core";
import {
    apiAdminRegister,
    apiCreateWard,
    apiDeleteWard,
    apiEditDoctorInfo,
    apiEditWard, 
    apiResetPasswordFromRoleID,
    apiSetDoctorResigned,
    apiDeleteTeam,
    apiCreateTeam,
    apiEditTeam,
    apiPatientBooking,
    apiEditPatientBooking,
    apiDeletePatientBooking,
    apiGetTeamList,
    apiProcessAppointment,
    apiPatientAdmission,
    apiGetWardList,
    apiEditPatientInfo,
    apiPatientDischarge
} from "~/utils/hms_api.ts";
import {parseDmyToDate, showErrorMessage, showInfoMessage, timestampToDate} from "~/utils/utils.ts";
import {
    type DoctorDataWithPermission,
    type WardInfo,
    WardTypes,
    type DoctorTeamInfo,
    type PatientBookingInfo,
    type PatientDataWithWardAndAdmission, type PatientData, type DoctorData
} from "~/utils/models.ts";
import {useForm} from "@mantine/form";
import {iconMStyle} from "~/styles.ts";
import RenameIcon from "mdi-react/RenameIcon";
import HumanEditIcon from "mdi-react/HumanEditIcon";
import WardPatients from "~/components/subs/WardPatients.tsx";
import {DoctorGrade, Departments, BookingCategory} from "~/utils/hms_enums.ts";
import {DateInput, DateTimePicker} from "@mantine/dates";
import CalendarIcon from "mdi-react/CalendarIcon";
import PhoneIcon from "mdi-react/PhoneIcon";
import MailIcon from "mdi-react/MailIcon";
import GenderMaleFemaleIcon from "mdi-react/GenderMaleFemaleIcon";
import AlphaGIcon from "mdi-react/AlphaGIcon";
import HomeIcon from "mdi-react/HomeIcon";
import CheckIcon from "mdi-react/CheckIcon";
import ContentCopyIcon from "mdi-react/ContentCopyIcon";


export function confirmDeleteWard(wardId: number, wardName: String, onFinished: () => void = () => {}) {
    const onClickConfirmDeleteWard = (wardId: number) => {
        apiDeleteWard(wardId).then(res => {
            if (res.success) {
                showInfoMessage("", "Ward deleted successfully", 3000)
            } else {
                showErrorMessage(res.message, "Delete Ward Failed")
            }
        }).catch(err => {
            showErrorMessage(err.toString(), "Delete Ward Failed")
        }).finally(() => onFinished())
        modals.closeAll()
    }

    modals.open({
        title: "Delete Ward",
        centered: true,
        children: (
            <Stack>
                <Text>Are you sure you want to delete the ward: <Text span fw={700}>{wardName}</Text>?</Text>
                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" onClick={() => onClickConfirmDeleteWard(wardId)}>Confirm</Button>
                </Group>
            </Stack>
        )
    })
}

export function confirmEditOrCreateWard(origWardInfo: WardInfo | null, onSucceed: () => void = () => {}) {

    function ConfirmEditOrCreateWard({wardInfo}: {wardInfo: WardInfo | null}) {
        const form = useForm({
            initialValues: {
                ward_id: wardInfo ? wardInfo.id : -1,
                ward_name: wardInfo ? wardInfo.name : "",
                total_capacity: wardInfo ? wardInfo.total_capacity : 0,
                type: wardInfo ? wardInfo.type : "GENERAL"
            },

            validate: {
                ward_name: (value) => (value.length == 0 ? "Input ward name." : null),
                total_capacity: (value) => (value < 1 ? "Total capacity must be greater than 0." : null),
            },
        });

        const optionsFilter: OptionsFilter = ({ options, search }) => {
            const filtered = (options as ComboboxItem[]).filter((option) =>
                option.label.toLowerCase().trim().includes(search.toLowerCase().trim())
            );

            filtered.sort((a, b) => a.label.localeCompare(b.label));
            return filtered;
        }

        const wardTypesOptions = useMemo(() => {
            return Object.entries(WardTypes).map(([key, value]) => ({ value: key, label: value }))
        }, [WardTypes])

        const onClickConfirmEditWard = (values: {ward_id: number, ward_name: string, total_capacity: number, type: string}) => {
            if (origWardInfo) {
                apiEditWard(values.ward_id, values.ward_name, values.total_capacity, values.type).then(res => {
                    if (res.success) {
                        modals.closeAll()
                        showInfoMessage("", "Ward edited successfully", 3000)
                        onSucceed()
                    } else {
                        showErrorMessage(res.message, "Edit Ward Failed")
                    }
                }).catch(err => {
                    showErrorMessage(err.toString(), "Edit Ward Failed")
                })
            } else {
                apiCreateWard(values.ward_name, values.total_capacity, values.type).then(res => {
                    if (res.success) {
                        modals.closeAll()
                        showInfoMessage("", "Ward created successfully", 3000)
                        onSucceed()
                    } else {
                        showErrorMessage(res.message, "Create Ward Failed")
                    }
                }).catch(err => {
                    showErrorMessage(err.toString(), "Create Ward Failed")
                })
            }
        }

        return (
            <form onSubmit={form.onSubmit((values) => onClickConfirmEditWard(values))}>
                <Stack>
                    <TextInput
                        withAsterisk
                        label="Ward Name"
                        placeholder="Ward name"
                        leftSection={<RenameIcon style={iconMStyle}/>}
                        {...form.getInputProps('ward_name')}
                    />

                    <NumberInput
                        withAsterisk
                        label="Total Capacity"
                        placeholder="Total capacity"
                        hideControls
                        leftSection={<HumanEditIcon style={iconMStyle}/>}
                        {...form.getInputProps('total_capacity')}
                    />

                    <Select
                        label="Ward Type"
                        placeholder="Select a ward type"
                        data={wardTypesOptions}
                        filter={optionsFilter}
                        searchable
                        {...form.getInputProps("type")}
                        onChange={(e) => {
                            if (!e) e = form.values.type
                            form.getInputProps("type").onChange(e)
                        }}
                    />

                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>Cancel</Button>
                        <Button type="submit">Confirm</Button>
                    </Group>
                </Stack>
            </form>
    )
    }

    modals.open({
        title: origWardInfo ? "Edit Ward" : "Create Ward",
        centered: true,
        children: (
            <ConfirmEditOrCreateWard wardInfo={origWardInfo} />
        )
    })
}

export function confirmCheckWardPatients(origWardId: number, onChanged: () => void = () => {}) {
    modals.open({
        title: "Ward Patients",
        centered: true,
        size: "70%",
        children: (
            <WardPatients ward_id={origWardId} onChanged={onChanged} />
        )
    })
}

export function confirmEditDoctor(
    origDoctorInfo: DoctorDataWithPermission,
    onSucceed: () => void = () => {},
) {
    function ConfirmEditOrCreateDoctor({
                                           doctorInfo,
                                       }: {
        doctorInfo: DoctorDataWithPermission;
    }) {
        const form = useForm({
            initialValues: {
                id: doctorInfo ? doctorInfo.id : -1,
                name: doctorInfo ? doctorInfo.name : '',
                email: doctorInfo ? doctorInfo.email : '',
                phone: doctorInfo ? doctorInfo.phone : '',
                gender: doctorInfo ? doctorInfo.gender : 'M',
                birth_date: doctorInfo ? parseDmyToDate(doctorInfo.birth_date) : new Date(2000, 1, 1),
                title: doctorInfo ? doctorInfo.title : '',
                grade: doctorInfo ? doctorInfo.grade.toString() : DoctorGrade.Unknown.toString(),
                is_admin: doctorInfo ? doctorInfo.is_admin : false
            },

            validate: {
                name: (v) => (v.length === 0 ? 'Input doctor name.' : null),
                email: (v) =>
                    /^\S+@\S+\.\S+$/.test(v) ? null : 'Incorrect email address.',
                phone: (v) =>
                    v.length === 0 || /^\+?\d{6,15}$/.test(v)
                        ? null
                        : 'Invalid phone number.',
                birth_date: (v) => (v > new Date() ? 'Date of birth cannot be in the future' : null),
                gender: (v) => (v.length === 0 ? "Select a gender" : null)
            },
        });

        const genderOptions = useMemo(
            () => [
                { value: 'M', label: 'Male' },
                { value: 'F', label: 'Female' },
                { value: 'Intersex', label: 'Intersex' },
            ],
            [],
        );

        const gradeOptions = useMemo(
            () =>
                Object.entries(DoctorGrade)
                    .filter(([k]) => isNaN(Number(k)))
                    .map(([k, v]) => ({
                        value: v.toString(),
                        label: k,
                    })),
            [],
        );

        const optionsFilter: OptionsFilter = ({ options, search }) => {
            const res = (options as ComboboxItem[]).filter((o) =>
                o.label.toLowerCase().includes(search.toLowerCase().trim()),
            );
            res.sort((a, b) => a.label.localeCompare(b.label));
            return res;
        };

        const onClickConfirmEditDoctor = (values: typeof form.values) => {
            apiEditDoctorInfo(values).then((res) => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage('', 'Doctor edited successfully', 3000);
                    onSucceed();
                } else showErrorMessage(res.message, 'Edit Doctor Failed');
            }).catch((err) =>
                showErrorMessage(err.toString(), 'Edit Doctor Failed'),
            );
        };

        return (
            <form onSubmit={form.onSubmit(onClickConfirmEditDoctor)}>
                <Stack>
                    <Group grow>
                        <TextInput
                            withAsterisk
                            label="Name"
                            placeholder="Doctor name"
                            leftSection={<RenameIcon style={iconMStyle} />}
                            {...form.getInputProps('name')}
                        />

                        <TextInput
                            label="Title"
                            placeholder="e.g. Dr., Prof."
                            leftSection={<RenameIcon style={iconMStyle} />}
                            {...form.getInputProps('title')}
                        />
                    </Group>

                    <Group grow>
                        <Select
                            label="Gender"
                            placeholder="Select gender"
                            data={genderOptions}
                            filter={optionsFilter}
                            leftSection={<GenderMaleFemaleIcon style={iconMStyle} />}
                            searchable
                            withAsterisk
                            {...form.getInputProps('gender')}
                            onChange={(v) => {
                                if (!v) v = form.values.gender;
                                form.getInputProps('gender').onChange(v);
                            }}
                        />

                        <DateInput
                            withAsterisk
                            label="Birth Date"
                            valueFormat="DD/MM/YYYY"
                            leftSection={<CalendarIcon style={iconMStyle} />}
                            {...form.getInputProps('birth_date')}
                        />
                    </Group>

                    <Group grow>
                        <Select
                            label="Grade"
                            placeholder="Select grade"
                            data={gradeOptions}
                            filter={optionsFilter}
                            leftSection={<AlphaGIcon style={iconMStyle} />}
                            {...form.getInputProps('grade')}
                            onChange={(v) => {
                                if (!v) v = form.values.grade.toString();
                                form.getInputProps('grade').onChange(v);
                            }}
                        />

                        <TextInput
                            withAsterisk
                            label="Email"
                            placeholder="doctor@example.com"
                            leftSection={<MailIcon style={iconMStyle} />}
                            {...form.getInputProps('email')}
                        />
                    </Group>

                    <Group grow>
                        <TextInput
                            label="Phone"
                            placeholder="+441234567890"
                            leftSection={<PhoneIcon style={iconMStyle} />}
                            {...form.getInputProps('phone')}
                        />

                        <Checkbox
                            label="Admin"
                            key={form.key("is_admin")}
                            {...form.getInputProps('is_admin', { type: 'checkbox' })}
                        />
                    </Group>

                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button type="submit">Confirm</Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: origDoctorInfo ? 'Edit Doctor' : 'Create Doctor',
        centered: true,
        size: "xl",
        children: <ConfirmEditOrCreateDoctor doctorInfo={origDoctorInfo} />,
    });
}

export function confirmSetResignedDoctor(doctor_id: number, doctor_name: string, is_resigned: boolean, onFinished: () => void = () => {}) {
    const onClickConfirmSetResigned = (doctor: number, resigned: boolean) => {
        apiSetDoctorResigned(doctor, resigned).then(res => {
            if (res.success) {
                showInfoMessage("", "The operation has been completed successfully.", 3000)
            }
            else {
                showErrorMessage(res.message, "The doctor's resignation failed.")
            }
        }).catch(err => {
            showErrorMessage(err.toString(), "The doctor's resignation failed.")
        }).finally(() => onFinished())
        modals.closeAll()
    }

    modals.open({
        title: is_resigned ? "Termination" : "Reinstatement",
        centered: true,
        children: (
            <Stack>
                { is_resigned ?
                    <Text>Are you certain you want to proceed with the termination of <Text span fw={700}>{doctor_name}</Text>?</Text>
                    :
                    <Text>Are you certain you want to proceed with the reinstatement of <Text span fw={700}>{doctor_name}</Text>?</Text>
                }

                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" onClick={() => onClickConfirmSetResigned(doctor_id, is_resigned)}>Confirm</Button>
                </Group>
            </Stack>
        )
    })
}


export function confirmAdminAddUser(
    initRegType: number = 1,  // Patient: 0, Doctor: 1, Receptionist: 99
    onSucceed: () => void = () => {},
) {
    function ConfirmAddUser() {
        const form = useForm({
            initialValues: {
                reg_type: initRegType.toString(),
                username: '',
                name: '',
                email: '',
                phone: '',
                gender: '',
                birth_date: new Date(2000, 1, 1),
                title: '',

                address: '',
                postcode: '',

                grade: DoctorGrade.Unknown.toString(),
                is_admin: false
            },

            validate: {
                name: (v) => (v.length === 0 ? 'Input name.' : null),
                email: (v) =>
                    /^\S+@\S+\.\S+$/.test(v) ? null : 'Incorrect email address.',
                phone: (v) =>
                    v.length === 0 || /^\+?\d{6,15}$/.test(v)
                        ? null
                        : 'Invalid phone number.',
                birth_date: (v) => (v > new Date() ? 'Date of birth cannot be in the future' : null),
                gender: (v) => (v.length === 0 ? "Select a gender" : null)
            },
        });

        const genderOptions = useMemo(
            () => [
                { value: 'M', label: 'Male' },
                { value: 'F', label: 'Female' },
                { value: 'Intersex', label: 'Intersex' },
            ],
            [],
        );

        const gradeOptions = useMemo(
            () =>
                Object.entries(DoctorGrade)
                    .filter(([k]) => isNaN(Number(k)))
                    .map(([k, v]) => ({
                        value: v.toString(),
                        label: k,
                    })),
            [],
        );

        const optionsFilter: OptionsFilter = ({ options, search }) => {
            const res = (options as ComboboxItem[]).filter((o) =>
                o.label.toLowerCase().includes(search.toLowerCase().trim()),
            );
            res.sort((a, b) => a.label.localeCompare(b.label));
            return res;
        };

        const onClickRegSubmit = (values: typeof form.values) => {
            apiAdminRegister(values).then((res) => {
                if (res.success) {
                    // modals.closeAll();
                    showRegAccountPassword("Added User Succeed", res.data?.username, res.data?.password)
                    onSucceed()
                } else showErrorMessage(res.message, 'Add User Failed');
            }).catch((err) =>
                showErrorMessage(err.toString(), 'Add User Failed'),
            );
        };

        return (
            <form onSubmit={form.onSubmit(onClickRegSubmit)}>
                <Stack>
                    <Radio.Group
                        name="User Type"
                        label="Select user type"
                        withAsterisk
                        {...form.getInputProps('reg_type')}
                    >
                        <Group>
                            <Radio value="0" label="Patient" />
                            <Radio value="1" label="Doctor" />
                            <Radio value="99" label="Receptionist" />
                        </Group>
                    </Radio.Group>

                    <TextInput
                        withAsterisk
                        label="Login Name"
                        placeholder="Name used for system login"
                        leftSection={<RenameIcon style={iconMStyle} />}
                        {...form.getInputProps('username')}
                    />

                    <TextInput
                        withAsterisk
                        label="Name"
                        placeholder="Real name"
                        leftSection={<RenameIcon style={iconMStyle} />}
                        {...form.getInputProps('name')}
                    />

                    <TextInput
                        label="Title"
                        placeholder="e.g. Dr., Prof."
                        leftSection={<RenameIcon style={iconMStyle} />}
                        {...form.getInputProps('title')}
                    />

                    <Select
                        label="Gender"
                        placeholder="Select gender"
                        data={genderOptions}
                        filter={optionsFilter}
                        leftSection={<GenderMaleFemaleIcon style={iconMStyle} />}
                        searchable
                        withAsterisk
                        {...form.getInputProps('gender')}
                        onChange={(v) => {
                            if (!v) v = form.values.gender;
                            form.getInputProps('gender').onChange(v);
                        }}
                    />

                    <DateInput
                        withAsterisk
                        label="Birth Date"
                        valueFormat="DD/MM/YYYY"
                        leftSection={<CalendarIcon style={iconMStyle} />}
                        {...form.getInputProps('birth_date')}
                    />

                    <TextInput
                        withAsterisk
                        label="Email"
                        placeholder="doctor@example.com"
                        leftSection={<MailIcon style={iconMStyle} />}
                        {...form.getInputProps('email')}
                    />

                    <TextInput
                        label="Phone"
                        placeholder="+441234567890"
                        leftSection={<PhoneIcon style={iconMStyle} />}
                        {...form.getInputProps('phone')}
                    />

                    {
                        form.values.reg_type == "0" ?
                            <>
                                <TextInput
                                    withAsterisk
                                    label="Address"
                                    placeholder="Your home address"
                                    leftSection={<HomeIcon style={iconMStyle}/>}
                                    {...form.getInputProps('address')}
                                />

                                <TextInput
                                    withAsterisk
                                    label="Postcode"
                                    placeholder="Your postcode. eg. BS16 1QY"
                                    leftSection={<HomeIcon style={iconMStyle}/>}
                                    {...form.getInputProps('postcode')}
                                />
                            </>
                            :
                            <>
                                <Select
                                    label="Grade"
                                    placeholder="Select grade"
                                    data={gradeOptions}
                                    filter={optionsFilter}
                                    leftSection={<AlphaGIcon style={iconMStyle} />}
                                    {...form.getInputProps('grade')}
                                    onChange={(v) => {
                                        if (!v) v = form.values.grade.toString();
                                        form.getInputProps('grade').onChange(v);
                                    }}
                                />

                                <Checkbox
                                    label="Admin"
                                    key={form.key("is_admin")}
                                    {...form.getInputProps('is_admin', { type: 'checkbox' })}
                                />
                            </>
                    }

                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button type="submit">Confirm</Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: "Add User",
        centered: true,
        size: "70%",
        children: <ConfirmAddUser />,
    });
}

export function showRegAccountPassword(title: string, username?: string, password?: string) {
    modals.open({
        title: title,
        centered: true,
        closeOnEscape: false,
        closeOnClickOutside: false,
        withCloseButton: false,
        children: (
            <Stack>
                <Group>
                    <Text>Username: <Text span fw={700}>{username}</Text></Text>
                    { username &&
                        <CopyButton value={username}>
                            {({ copied, copy }) => (
                                <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="right">
                                    <ActionIcon color={copied ? 'teal' : 'gray'} variant="subtle" onClick={copy}>
                                        {copied ? <CheckIcon style={iconMStyle} /> : <ContentCopyIcon style={iconMStyle} />}
                                    </ActionIcon>
                                </Tooltip>
                            )}
                        </CopyButton>
                    }
                </Group>
                <Group>
                    <Text>Password: <Text span fw={700}>{password}</Text></Text>
                    { password &&
                        <CopyButton value={password}>
                            {({ copied, copy }) => (
                                <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="right">
                                    <ActionIcon color={copied ? 'teal' : 'gray'} variant="subtle" onClick={copy}>
                                        {copied ? <CheckIcon style={iconMStyle} /> : <ContentCopyIcon style={iconMStyle} />}
                                    </ActionIcon>
                                </Tooltip>
                            )}
                        </CopyButton>
                    }
                </Group>
                <Group mt="md" justify="flex-end">
                    <CopyButton value={`Username: ${username}\nPassword: ${password}`}>
                        {({ copied, copy }) => (
                            <Button color={copied ? 'teal' : 'blue'} variant="outline" onClick={copy}>
                                {copied ? 'Copied All' : 'Copy All'}
                            </Button>
                        )}
                    </CopyButton>

                    <Button onClick={() => modals.closeAll()}>OK</Button>
                </Group>
            </Stack>
        ),
    });
}

export function confirmResetPassword(user_id: number, user_type: number) {
    function ConfirmResetPWD() {
        const [resetting, setResetting] = useState(false)

        return(
            <Stack>
                <Text>Are you sure you want to reset the password?</Text>
                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" disabled={resetting} onClick={() => {
                        setResetting(true)
                        apiResetPasswordFromRoleID(user_id, user_type).then(res => {
                            if (res.success) {
                                showRegAccountPassword("Reset Password Succeed", res.data?.username, res.data?.password)
                            } else {
                                showErrorMessage(res.message, "Reset Password Failed")
                                modals.closeAll()
                            }
                        }).catch(err => {
                            showErrorMessage(err.toString(), "Reset Password Failed")
                            modals.closeAll()
                        }).finally(() => setResetting(false))
                    }}>Confirm</Button>
                </Group>
            </Stack>
        )
    }

    modals.open({
        title: "Reset Password",
        centered: true,
        children: <ConfirmResetPWD/>
    });
}

export function confirmDeleteTeam(teamId: number, department: String, onFinished: () => void = () => {}) {
    const onClickConfirmDeleteTeam = (teamId: number) => {
        apiDeleteTeam(teamId).then(res => {
            if (res.success) {
                showInfoMessage("", "Medical team deleted successfully", 3000)
            } else {
                showErrorMessage(res.message, "Failed to delete medical team")
            }
        }).catch(err => {
            showErrorMessage(err.toString(), "Failed to delete medical team")
        }).finally(() => onFinished())
        modals.closeAll()
    }

    modals.open({
        title: "Delete Medical Team",
        centered: true,
        children: (
            <Stack>
                <Text>Are you sure you want to delete this medical team: <Text span fw={700}>{department}</Text>?</Text>
                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" onClick={() => onClickConfirmDeleteTeam(teamId)}>Confirm</Button>
                </Group>
            </Stack>
        )
    })
}

export function confirmEditOrCreateTeam(
    origTeamInfo: DoctorTeamInfo | null, 
    doctorsList: DoctorDataWithPermission[] = [],
    onSucceed: () => void = () => {}
) {
    function ConfirmEditOrCreateTeam({
        teamInfo,
        doctorsList
    }: {
        teamInfo: DoctorTeamInfo | null;
        doctorsList: DoctorDataWithPermission[];
    }) {
        const [loading, setLoading] = useState(false);
        const [availableDoctors, setAvailableDoctors] = useState<DoctorDataWithPermission[]>([]);
        
        useEffect(() => {
            // Filter out resigned doctors
            const activeDoctors = doctorsList.filter(d => !d.is_resigned);
            setAvailableDoctors(activeDoctors);
        }, [doctorsList]);
        
        const form = useForm({
            initialValues: {
                team_id: teamInfo ? teamInfo.id : -1,
                department: teamInfo ? teamInfo.department : '',
                consultant_id: teamInfo ? teamInfo.consultant_id.toString() : '-1',
                is_admin_team: teamInfo ? teamInfo.is_admin_team : false,
                team_members: teamInfo 
                    ? teamInfo.members.map(member => member.id) 
                    : []
            },
            validate: {
                department: (value) => (!value ? 'Please select a department' : null),
                consultant_id: (value) => (value === '-1' || !value ? 'Please select a consultant' : null),
            },
        });

        const departmentOptions = useMemo(() => {
            return Object.entries(Departments).map(([key, value]) => ({
                value: value as string,
                label: key.replace(/_/g, ' ')
            }));
        }, []);

        const consultantOptions = useMemo(() => {
            return availableDoctors
                .map(d => ({
                    value: d.id.toString(),
                    label: `${d.title} ${d.name}`
                }));
        }, [availableDoctors]);

        const teamMemberOptions = useMemo(() => {
            return availableDoctors.map(d => ({
                value: d.id.toString(),
                label: `${d.title} ${d.name} (${DoctorGrade[d.grade]})`
            }));
        }, [availableDoctors]);

        const handleFormSubmit = (values: typeof form.values) => {
            setLoading(true);
            
            const teamData = {
                ...values,
                consultant_id: Number(values.consultant_id),
                team_members: values.team_members.map(Number)
            };
            
            const apiCall = teamInfo 
                ? apiEditTeam(teamData) 
                : apiCreateTeam(teamData);
                
            apiCall.then(res => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage("", teamInfo ? "Medical team updated successfully" : "Medical team created successfully", 3000);
                    onSucceed();
                } else {
                    showErrorMessage(res.message, teamInfo ? "Failed to update medical team" : "Failed to create medical team");
                }
            }).catch(err => {
                showErrorMessage(err.toString(), teamInfo ? "Failed to update medical team" : "Failed to create medical team");
            }).finally(() => {
                setLoading(false);
            });
        };

        return (
            <form onSubmit={form.onSubmit(handleFormSubmit)}>
                <Stack>
                    <Select
                        withAsterisk
                        label="Department"
                        placeholder="Select department"
                        data={departmentOptions}
                        searchable
                        nothingFoundMessage="No results found"
                        {...form.getInputProps('department')}
                        onChange={(value) => {
                            if (!value) return;
                            form.setFieldValue('department', value);
                        }}
                    />
                    
                    <Select
                        withAsterisk
                        label="Consultant"
                        placeholder="Select consultant"
                        data={consultantOptions}
                        searchable
                        nothingFoundMessage="No results found"
                        {...form.getInputProps('consultant_id')}
                        onChange={(value) => {
                            if (!value) return;
                            form.setFieldValue('consultant_id', value);
                        }}
                    />
                    
                    <MultiSelect
                        label="Team Members"
                        placeholder="Select team members"
                        data={teamMemberOptions}
                        searchable
                        nothingFoundMessage="No results found"
                        value={form.values.team_members.map(id => id.toString())}
                        onChange={(values) => {
                            form.setFieldValue('team_members', values.map(Number));
                        }}
                    />
                    
                    <Checkbox
                        label="Admin Team"
                        {...form.getInputProps('is_admin_team', { type: 'checkbox' })}
                    />
                    
                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button type="submit" loading={loading}>
                            Confirm
                        </Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: origTeamInfo ? "Edit Medical Team" : "Create Medical Team",
        centered: true,
        size: "lg",
        children: (
            <ConfirmEditOrCreateTeam 
                teamInfo={origTeamInfo} 
                doctorsList={doctorsList}
            />
        )
    });
}

export function confirmViewTeamMembers(teamInfo: DoctorTeamInfo) {
    modals.open({
        title: `Medical Team: ${teamInfo.department.replace(/_/g, ' ')}`,
        centered: true,
        size: "lg",
        children: (
            <Stack>
                <Text fw={700}>Team Information</Text>
                <Text>Department: {teamInfo.department.replace(/_/g, ' ')}</Text>
                <Text>
                    Consultant: {
                        teamInfo.members.find(m => m.id === teamInfo.consultant_id)
                            ? `${teamInfo.members.find(m => m.id === teamInfo.consultant_id)?.title || ''} ${teamInfo.members.find(m => m.id === teamInfo.consultant_id)?.name || ''}`
                            : `ID: ${teamInfo.consultant_id}`
                    }
                </Text>
                <Text>Admin Team: {teamInfo.is_admin_team ? 'Yes' : 'No'}</Text>
                
                <Text fw={700} mt="md">Team Members ({teamInfo.members.length})</Text>
                {teamInfo.members.length > 0 ? (
                    <Table>
                        <Table.Thead>
                            <Table.Tr>
                                <Table.Th>ID</Table.Th>
                                <Table.Th>Name</Table.Th>
                                <Table.Th>Grade</Table.Th>
                                <Table.Th>Gender</Table.Th>
                                <Table.Th>Contact</Table.Th>
                            </Table.Tr>
                        </Table.Thead>
                        <Table.Tbody>
                            {teamInfo.members.map(member => (
                                <Table.Tr key={member.id}>
                                    <Table.Td>{member.id}</Table.Td>
                                    <Table.Td>{`${member.title} ${member.name}`}</Table.Td>
                                    <Table.Td>{DoctorGrade[member.grade]}</Table.Td>
                                    <Table.Td>{member.gender}</Table.Td>
                                    <Table.Td>{member.email}</Table.Td>
                                </Table.Tr>
                            ))}
                        </Table.Tbody>
                    </Table>
                ) : (
                    <Text c="dimmed">No team members</Text>
                )}
                
                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Close</Button>
                </Group>
            </Stack>
        )
    });
}

export function confirmDeleteBooking(appointmentId: number, category: string, onFinished: () => void = () => {}) {
    const onClickConfirmDeleteBooking = (appointmentId: number) => {
        apiDeletePatientBooking(appointmentId).then(res => {
            if (res.success) {
                showInfoMessage("", "Appointment deleted successfully", 3000)
            } else {
                showErrorMessage(res.message, "Failed to delete appointment")
            }
        }).catch(err => {
            showErrorMessage(err.toString(), "Failed to delete appointment")
        }).finally(() => onFinished())
        modals.closeAll()
    }

    modals.open({
        title: "Delete Appointment",
        centered: true,
        children: (
            <Stack>
                <Text>Are you sure you want to delete this appointment: <Text span fw={700}>{category}</Text>?</Text>
                <Group mt="md" justify="flex-end">
                    <Button onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" onClick={() => onClickConfirmDeleteBooking(appointmentId)}>Confirm</Button>
                </Group>
            </Stack>
        )
    })
}

export function confirmEditOrCreateBooking(
    origBookingInfo: PatientBookingInfo | null,
    onSucceed: () => void = () => {}
) {
    function ConfirmEditOrCreateBooking({
        bookingInfo
    }: {
        bookingInfo: PatientBookingInfo | null;
    }) {
        const [loading, setLoading] = useState(false);
        
        const form = useForm({
            initialValues: {
                appointment_id: bookingInfo ? bookingInfo.id : -1,
                appointment_time: bookingInfo ? new Date(bookingInfo.appointment_time * 1000) : new Date(),
                category: bookingInfo ? bookingInfo.category : BookingCategory.Consultation,
                description: bookingInfo ? bookingInfo.description : '',
            },
            validate: {
                appointment_time: (value) => (!value ? 'Please select appointment time' : null),
                category: (value) => (!value ? 'Please select category' : null),
                description: (value) => (!value || value.length < 5 ? 'Description must be at least 5 characters' : null),
            },
        });

        const categoryOptions = useMemo(() => {
            return Object.entries(BookingCategory).map(([key, value]) => ({
                value: value,
                label: key.replace(/_/g, ' ')
            }));
        }, []);

        const handleFormSubmit = (values: typeof form.values) => {
            setLoading(true);
            
            const appointmentTime = Math.floor(values.appointment_time.getTime() / 1000);
            
            const bookingData = {
                ...values,
                appointment_time: appointmentTime,
            };
            
            const apiCall = bookingInfo 
                ? apiEditPatientBooking(bookingData) 
                : apiPatientBooking(bookingData);
                
            apiCall.then(res => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage("", bookingInfo ? "Appointment updated successfully" : "Appointment created successfully", 3000);
                    onSucceed();
                } else {
                    showErrorMessage(res.message, bookingInfo ? "Failed to update appointment" : "Failed to create appointment");
                }
            }).catch(err => {
                showErrorMessage(err.toString(), bookingInfo ? "Failed to update appointment" : "Failed to create appointment");
            }).finally(() => {
                setLoading(false);
            });
        };

        return (
            <form onSubmit={form.onSubmit(handleFormSubmit)}>
                <Stack>
                    <Select
                        withAsterisk
                        label="Category"
                        placeholder="Select appointment category"
                        data={categoryOptions}
                        searchable
                        nothingFoundMessage="No results found"
                        {...form.getInputProps('category')}
                        onChange={(value) => {
                            if (!value) return;
                            form.setFieldValue('category', value);
                        }}
                    />
                    
                    <DateTimePicker
                        withAsterisk
                        label="Appointment Time"
                        placeholder="Select date and time"
                        valueFormat="DD/MM/YYYY HH:mm"
                        leftSection={<CalendarIcon style={iconMStyle} />}
                        {...form.getInputProps('appointment_time')}
                    />
                    
                    <Textarea
                        withAsterisk
                        label="Description"
                        placeholder="Describe your appointment request"
                        minRows={3}
                        {...form.getInputProps('description')}
                    />
                    
                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button type="submit" loading={loading}>
                            Confirm
                        </Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: origBookingInfo ? "Edit Appointment" : "Create Appointment",
        centered: true,
        size: "lg",
        children: (
            <ConfirmEditOrCreateBooking bookingInfo={origBookingInfo} />
        )
    });
}

export function confirmApproveAppointment(
    appointmentId: number, 
    onSucceed: () => void = () => {}
) {
    function ConfirmApproveAppointment() {
        const [loading, setLoading] = useState(false);
        const [teams, setTeams] = useState<DoctorTeamInfo[]>([]);
        const [loadingTeams, setLoadingTeams] = useState(true);
        
        const form = useForm({
            initialValues: {
                appointment_id: appointmentId,
                approved: true,
                feedback: '',
                assigned_team: '',
            },
            validate: {
                feedback: (value) => (!value ? 'Please provide feedback' : null),
                assigned_team: (value) => (!value ? 'Please select a medical team' : null),
            },
        });

        useEffect(() => {
            // Load teams for selection
            apiGetTeamList(1).then(res => {
                if (res.success) {
                    setTeams(res.data.teams);
                } else {
                    showErrorMessage(res.message, "Failed to load medical teams");
                }
            })
            .catch(err => {
                showErrorMessage("Failed to load medical teams", "Error");
            })
            .finally(() => {
                setLoadingTeams(false);
            });
        }, []);

        const teamOptions = useMemo(() => {
            return teams.map(team => ({
                value: team.id.toString(),
                label: `${team.department.replace(/_/g, ' ')} (ID: ${team.id})`
            }));
        }, [teams]);

        const handleFormSubmit = (values: typeof form.values) => {
            setLoading(true);
            
            apiProcessAppointment(
                values.appointment_id,
                values.approved,
                values.feedback,
                parseInt(values.assigned_team)
            ).then(res => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage("", "Appointment approved successfully", 3000);
                    onSucceed();
                } else {
                    showErrorMessage(res.message, "Failed to approve appointment");
                }
            }).catch(err => {
                showErrorMessage("Failed to approve appointment", "Error");
            }).finally(() => {
                setLoading(false);
            });
        };

        return (
            <form onSubmit={form.onSubmit(handleFormSubmit)}>
                <Stack>
                    <Textarea
                        withAsterisk
                        label="Feedback"
                        placeholder="Provide feedback for the patient"
                        minRows={3}
                        {...form.getInputProps('feedback')}
                    />
                    
                    <Select
                        withAsterisk
                        label="Assign Medical Team"
                        placeholder="Select a medical team"
                        data={teamOptions}
                        searchable
                        nothingFoundMessage="No medical teams found"
                        disabled={loadingTeams}
                        {...form.getInputProps('assigned_team')}
                        onChange={(value) => {
                            if (!value) return;
                            form.setFieldValue('assigned_team', value);
                        }}
                    />
                    
                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button 
                            type="submit" 
                            loading={loading || loadingTeams}
                            color="green"
                        >
                            Approve
                        </Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: "Approve Appointment",
        centered: true,
        size: "md",
        children: <ConfirmApproveAppointment />
    });
}

export function confirmRejectAppointment(
    appointmentId: number, 
    onSucceed: () => void = () => {}
) {
    function ConfirmRejectAppointment() {
        const [loading, setLoading] = useState(false);
        
        const form = useForm({
            initialValues: {
                appointment_id: appointmentId,
                approved: true,
                feedback: '',
                assigned_team: null,
            },
            validate: {
                feedback: (value) => (!value ? 'Please provide rejection reason' : null),
            },
        });

        const handleFormSubmit = (values: typeof form.values) => {
            setLoading(true);
            
            apiProcessAppointment(
                values.appointment_id,
                values.approved,
                values.feedback,
                values.assigned_team
            ).then(res => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage("", "Appointment rejected successfully", 3000);
                    onSucceed();
                } else {
                    showErrorMessage(res.message, "Failed to reject appointment");
                }
            }).catch(err => {
                showErrorMessage("Failed to reject appointment", "Error");
            }).finally(() => {
                setLoading(false);
            });
        };

        return (
            <form onSubmit={form.onSubmit(handleFormSubmit)}>
                <Stack>
                    <Textarea
                        withAsterisk
                        label="Rejection Reason"
                        placeholder="Provide reason for rejection"
                        minRows={3}
                        {...form.getInputProps('feedback')}
                    />
                    
                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button 
                            type="submit" 
                            loading={loading}
                            color="red"
                        >
                            Reject
                        </Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: "Reject Appointment",
        centered: true,
        size: "md",
        children: <ConfirmRejectAppointment />
    });
}

export function confirmPatientAdmission(
    appointmentId: number, 
    onSucceed: () => void = () => {}
) {
    function ConfirmPatientAdmission() {
        const [loading, setLoading] = useState(false);
        const [wards, setWards] = useState<WardInfo[]>([]);
        const [loadingWards, setLoadingWards] = useState(true);
        
        const form = useForm({
            initialValues: {
                appointment_id: appointmentId,
                ward_id: '',
            },
            validate: {
                ward_id: (value) => (!value ? 'Please select a ward' : null),
            },
        });

        useEffect(() => {
            // Load wards for selection
            apiGetWardList(1, true).then(res => {
                if (res.success) {
                    setWards(res.data.wards);
                } else {
                    showErrorMessage(res.message, "Failed to load wards");
                }
            })
            .catch(err => {
                showErrorMessage("Failed to load wards", "Error");
            })
            .finally(() => {
                setLoadingWards(false);
            });
        }, []);

        const wardOptions = useMemo(() => {
            return wards
                .filter(ward => ward.current_occupancy < ward.total_capacity) // Only show wards with available capacity
                .map(ward => ({
                    value: ward.id.toString(),
                    label: `${ward.name} (${ward.current_occupancy}/${ward.total_capacity}) - ${WardTypes[ward.type]}`
                }));
        }, [wards]);

        const handleFormSubmit = (values: typeof form.values) => {
            setLoading(true);
            
            apiPatientAdmission(
                values.appointment_id,
                parseInt(values.ward_id)
            ).then(res => {
                if (res.success) {
                    modals.closeAll();
                    showInfoMessage("", "Patient admitted successfully", 3000);
                    onSucceed();
                } else {
                    showErrorMessage(res.message, "Failed to admit patient");
                }
            }).catch(err => {
                showErrorMessage("Failed to admit patient", "Error");
            }).finally(() => {
                setLoading(false);
            });
        };

        return (
            <form onSubmit={form.onSubmit(handleFormSubmit)}>
                <Stack>
                    <Select
                        withAsterisk
                        label="Select Ward"
                        placeholder="Choose a ward for patient"
                        data={wardOptions}
                        searchable
                        nothingFoundMessage={wardOptions.length === 0 ? "No wards with available capacity" : "No matching wards found"}
                        disabled={loadingWards || wardOptions.length === 0}
                        {...form.getInputProps('ward_id')}
                        onChange={(value) => {
                            if (!value) return;
                            form.setFieldValue('ward_id', value);
                        }}
                    />
                    
                    {wardOptions.length === 0 && !loadingWards && (
                        <Text c="red" size="sm">
                            No wards with available capacity. Please free up space in a ward first.
                        </Text>
                    )}
                    
                    <Group mt="md" justify="flex-end">
                        <Button variant="outline" onClick={() => modals.closeAll()}>
                            Cancel
                        </Button>
                        <Button 
                            type="submit" 
                            loading={loading || loadingWards}
                            disabled={wardOptions.length === 0}
                            color="blue"
                        >
                            Admit Patient
                        </Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: "Patient Admission",
        centered: true,
        size: "md",
        children: <ConfirmPatientAdmission />
    });
}

export function confirmEditPatient(
    origPatientInfo: PatientData,
    onSucceed: () => void = () => {},
) {
    function ConfirmEditPatient({
        patientInfo,
    }: {
        patientInfo: PatientData;
    }) {
        const form = useForm({
            initialValues: {
                patient_id: patientInfo.id,
                title: patientInfo.title,
                name: patientInfo.name,
                gender: patientInfo.gender,
                birth_date: parseDmyToDate(patientInfo.birth_date),
                email: patientInfo.email,
                phone: patientInfo.phone,
                address: patientInfo.address,
                postcode: patientInfo.postcode,
            },
            validate: {
                name: (value) => (!value || value.trim() === "" ? "Name cannot be empty" : null),
                title: (value) => (!value || value.trim() === "" ? "Title cannot be empty" : null),
                email: (value) => (!/^\S+@\S+$/.test(value) ? "Please enter a valid email" : null),
                phone: (value) => (!value || value.length < 6 ? "Please enter a valid phone number" : null),
                address: (value) => (!value || value.trim() === "" ? "Address cannot be empty" : null),
                postcode: (value) => (!value || value.trim() === "" ? "Postcode cannot be empty" : null),
            },
        });

        const onClickConfirmEditPatient = (values: typeof form.values) => {
            apiEditPatientInfo(values).then(res => {
                if (res.success) {
                    modals.closeAll()
                    showInfoMessage("", "Patient information updated successfully", 3000)
                    onSucceed()
                } else {
                    showErrorMessage(res.message, "Failed to update patient information")
                }
            }).catch(err => {
                showErrorMessage(err.toString(), "Failed to update patient information")
            })
        }

        return (
            <form onSubmit={form.onSubmit(onClickConfirmEditPatient)}>
                <Stack>
                    <Group grow>
                        <TextInput
                            withAsterisk
                            label="Title"
                            placeholder="Mr, Mrs, Dr, etc."
                            {...form.getInputProps("title")}
                        />
                        <TextInput
                            withAsterisk
                            label="Name"
                            placeholder="Full name"
                            leftSection={<HumanEditIcon style={iconMStyle}/>}
                            {...form.getInputProps("name")}
                        />
                    </Group>
                    <Group grow>
                        <Select
                            withAsterisk
                            label="Gender"
                            placeholder="Select gender"
                            data={[
                                { value: "M", label: "Male" },
                                { value: "F", label: "Female" },
                                { value: "Intersex", label: "Intersex" },
                            ]}
                            leftSection={<GenderMaleFemaleIcon style={iconMStyle}/>}
                            {...form.getInputProps("gender")}
                        />
                        <DateInput
                            withAsterisk
                            label="Birth Date"
                            placeholder="Select birth date"
                            value={form.values.birth_date || null}
                            onChange={(value) => {
                                form.setFieldValue("birth_date", value || new Date());
                            }}
                            leftSection={<CalendarIcon style={iconMStyle}/>}
                            error={form.errors.birth_date}
                        />
                    </Group>
                    <Group grow>
                        <TextInput
                            withAsterisk
                            label="Email"
                            placeholder="example@example.com"
                            leftSection={<MailIcon style={iconMStyle}/>}
                            {...form.getInputProps("email")}
                        />
                        <TextInput
                            withAsterisk
                            label="Phone"
                            placeholder="Phone number"
                            leftSection={<PhoneIcon style={iconMStyle}/>}
                            {...form.getInputProps("phone")}
                        />
                    </Group>
                    <Group grow>
                        <TextInput
                            withAsterisk
                            label="Address"
                            placeholder="Full address"
                            leftSection={<HomeIcon style={iconMStyle}/>}
                            {...form.getInputProps("address")}
                        />
                        <TextInput
                            withAsterisk
                            label="Postcode"
                            placeholder="Postal code"
                            {...form.getInputProps("postcode")}
                        />
                    </Group>
                    <Group justify="flex-end" mt="md">
                        <Button variant="outline" onClick={() => modals.closeAll()}>Cancel</Button>
                        <Button type="submit">Save Changes</Button>
                    </Group>
                </Stack>
            </form>
        );
    }

    modals.open({
        title: "Edit Patient Information",
        centered: true,
        size: "xl",
        children: <ConfirmEditPatient patientInfo={origPatientInfo} />,
    });
}

export function confirmPatientDischarge(admissionId: number, patientName: string, onFinished: () => void = () => {}) {
    const onClickConfirmDischarge = (admissionId: number) => {
        apiPatientDischarge(admissionId).then(res => {
            if (res.success) {
                modals.closeAll()
                showInfoMessage("", "Patient discharged successfully", 3000)
                onFinished()
            } else {
                showErrorMessage(res.message, "Failed to discharge patient")
            }
        }).catch(err => {
            showErrorMessage(err.toString(), "Failed to discharge patient")
        })
    }

    modals.open({
        title: "Confirm Patient Discharge",
        centered: true,
        children: (
            <Stack>
                <Text>Are you sure you want to discharge {patientName}?</Text>
                <Group justify="flex-end" mt="md">
                    <Button variant="outline" onClick={() => modals.closeAll()}>Cancel</Button>
                    <Button color="red" onClick={() => onClickConfirmDischarge(admissionId)}>Confirm Discharge</Button>
                </Group>
            </Stack>
        ),
    })
}
