import React, { useEffect, useMemo, useState } from 'react';
import { PageToolbar, PeriodPicker, Period, SearchInput, StatCard, fmtHKD, filterByPeriod, deriveYears } from './shared/ui';

const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1;
import axios from 'axios';
import { Button } from 'primereact/button';
import { Calendar } from 'primereact/calendar';
import { Column } from 'primereact/column';
import { DataTable } from 'primereact/datatable';
import { Dialog } from 'primereact/dialog';
import { Dropdown } from 'primereact/dropdown';
import { InputNumber } from 'primereact/inputnumber';
import { Message } from 'primereact/message';
import { ProgressSpinner } from 'primereact/progressspinner';

const StaffSalary = () => {
    const [items, setItems] = useState([]);
    const [period, setPeriod] = useState<Period>({ year: currentYear, month: currentMonth });
    const [search, setSearch] = useState('');
    const available_years = useMemo(() => deriveYears(items, 'month'), [items]);
    const filtered_items = useMemo(() => filterByPeriod(items, period, 'month'), [items, period]);
    const summary = useMemo(() => {
        let salary = 0, mpf_employer = 0, mpf_employee = 0, actual_receive = 0;
        for (const it of filtered_items) {
            salary += Number(it.amount) || 0;
            mpf_employer += Number(it.mpf_employer) || 0;
            mpf_employee += Number(it.mpf_employee) || 0;
            actual_receive += Number(it.actual_receive) || 0;
        }
        return { salary, mpf_employer, mpf_employee, mpf_total: mpf_employer + mpf_employee, actual_receive };
    }, [filtered_items]);
    const [staffs, setStaffs] = useState([]);
    const [is_loading, setIsLoading] = useState(true);
    const [is_responding, setIsResponding] = useState(false);
    const [dialog_visible, setDialogVisible] = useState(false);
    const [error_message, setErrorMessage] = useState(null);
    const [item, setItem] = useState({
        id: null,
        staff: null,
        amount: null,
        mpf_employer: null,
        mpf_employee: null,
        actual_receive: null,
        month: null
    });

    const list = async () => {
        setIsLoading(true);
        try {
            let response = await axios.get('/staff/list');
            setStaffs(response.data);
            response = await axios.get('/staff_salary/list');
            setItems(response.data);
        } catch (error) {
            console.log(error.response);
            console.error('Failed to fetch items:', error);
        } finally {
            setIsLoading(false);
        }
    };

    useEffect(() => {
        list();
    }, []);

    const add = () => {
        setItem({
            id: null,
            staff: null,
            amount: null,
            mpf_employer: null,
            mpf_employee: null,
            actual_receive: null,
            month: null
        });
        setDialogVisible(true);
    };

    const save_add = async () => {
        console.log(item);
        setIsResponding(true);
        try {
            await axios.post('/staff_salary/add', 
              {
                staff_id: item.staff != null ? item.staff.id : null,
                amount: item.amount || 0,
                mpf_employer: item.mpf_employer || 0,
                mpf_employee: item.mpf_employee || 0,
                actual_receive: item.actual_receive || 0,
                month: item.month
              }  
            );
            list();
            setDialogVisible(false);
        } catch (error) {
            console.log(error);
            console.log(error.response);
        } finally {
            setIsResponding(false);
        }
    };

    const edit = async (id) => {
        try {
            const response = await axios.get(`/staff_salary/get?id=` + id);
            console.log(response.data);
            setItem({
                id: response.data.id,
                staff: staffs.find((s) => s.id === response.data.staff_id),
                amount: response.data.amount,
                mpf_employer: response.data.mpf_employer,
                mpf_employee: response.data.mpf_employee,
                actual_receive: response.data.actual_receive,
                month: response.data.month? new Date(response.data.month) : null,
            });
        } catch (error) {
            console.log(error);
        } finally {
            setDialogVisible(true);
        }
    };

    const save_edit = async () => {
        setIsResponding(true);
        console.log(item.month);
        try {
            await axios.put(`/staff_salary/edit`, {
                id: item.id,
                staff_id: item.staff != null ? item.staff.id : null,
                amount: item.amount || 0,
                mpf_employer: item.mpf_employer || 0,
                mpf_employee: item.mpf_employee || 0,
                actual_receive: item.actual_receive || 0,
                month: item.month
            });
            list();
            setDialogVisible(false);
        } catch (error) {
            console.log(error.response);
        } finally {
            setIsResponding(false);        
        }
    };


    const manageBodyTemplate = (item) => {
        return <Button onClick={() => edit(item.id)} icon="pi pi-pencil" label="Edit" className="p-button-sm p-button-warning"></Button>;
    };

    return (
        <div>
            <div className="stats3">
                <StatCard label="Salary" value={fmtHKD(summary.salary)} icon="salary" />
                <StatCard label="MPF" value={fmtHKD(summary.mpf_total)} icon="shareholder" />
                <StatCard label="Actual paid" value={fmtHKD(summary.actual_receive)} icon="wallet" accent="var(--green-d)" />
            </div>

            <PageToolbar
                title="Salary"
                filters={
                    <>
                        <SearchInput value={search} onChange={setSearch} placeholder="Search salary…" />
                        <PeriodPicker period={period} years={available_years} onChange={setPeriod} includeAll />
                    </>
                }
                actions={
                    <>
                        <Button icon="pi pi-refresh" onClick={list} className="p-button-text p-button-sm" />
                        <Button icon="pi pi-plus" label="Add" onClick={add} className="p-button-sm" />
                    </>
                }
            />
            <div className='my-3'>
                {is_loading ? (<ProgressSpinner style={{ width: '2rem', height: '2rem' }} className="mr-3"></ProgressSpinner>) : null}
                <DataTable value={filtered_items} tableStyle={{ minWidth: '50rem' }} paginator rows={10}
                    globalFilter={search} globalFilterFields={['name', 'month']}
                    emptyMessage="No salary records found.">
                    <Column field="name" header="Name" footer="Total" sortable filter></Column>
                    <Column field="month" header="Month" sortable></Column>
                    <Column field="amount" header="Amount" footer={fmtHKD(summary.salary)} sortable></Column>
                    <Column field="mpf_employer" header="MPF Employer" footer={fmtHKD(summary.mpf_employer)} sortable></Column>
                    <Column field="mpf_employee" header="MPF Employee" footer={fmtHKD(summary.mpf_employee)} sortable></Column>
                    <Column field="actual_receive" header="Actual Receive" footer={fmtHKD(summary.actual_receive)} sortable></Column>
                    <Column header='Manage' body={manageBodyTemplate}></Column>
                </DataTable>
            </div>
            <Dialog visible={dialog_visible} onHide={() => setDialogVisible(false)} header={item.id ? "Edit Staff Salary" : "Add Staff Salary"} modal className="p-fluid w-1/2">
                <div className="form-body">
                    <div className="row">
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="staff">Staff</label>
                                <Dropdown id="staff" value={item.staff || ""} optionLabel='name' options={staffs} onChange={(e) => setItem({ ...item, staff: e.value })} placeholder="Staff"
                                    filter filterBy="name" filterMatchMode="contains" />
                            </div>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="month">Month</label>
                                <Calendar id="month" view="month" dateFormat='mm/yy' value={item.month || null} onChange={(e) => setItem({ ...item, month: e.value })} placeholder="Month" />
                            </div>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="amount">Amount</label>
                                <InputNumber id="amount" value={item.amount || 0} onValueChange={(e) => setItem({ ...item, amount: e.value })} placeholder="Amount" />
                            </div>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="mpf_employer">MPF (Employer)</label>
                                <InputNumber id="mpf_employer" value={item.mpf_employer || 0} onValueChange={(e) => setItem({ ...item, mpf_employer: e.value })} placeholder="MPF (Employer)" />
                            </div>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="mpf_employee">MPF (Employee)</label>
                                <InputNumber id="mpf_employee" value={item.mpf_employee || 0} onValueChange={(e) => setItem({ ...item, mpf_employee: e.value })} placeholder="MPF (Employee)" />
                            </div>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group mb-3">
                                <label htmlFor="actual_receive">Actual Receive</label>
                                <InputNumber id="actual_receive" value={item.actual_receive || 0} onValueChange={(e) => setItem({ ...item, actual_receive: e.value })} placeholder="Actual Receive" />
                            </div>
                        </div>
                    </div>
                    <div className="flex gap-2 mt-4">
                        {is_responding ? (<ProgressSpinner style={{ width: '2rem', height: '2rem' }} className="mr-3"></ProgressSpinner>) : null}
                        {error_message ? (<Message severity="error" text={error_message} />) : null}   
                        <Button raised label="Save" onClick={item.id ? save_edit : save_add} />
                    </div>
                </div>
            </Dialog>
        </div>
    );
};

export default StaffSalary;
