import { Form, Head, Link, router } from '@inertiajs/react';
import { ArrowLeft } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import { ConfirmDialog } from '@/components/dialogs';
import { DataTable } from '@/components/data-display';
import { InputError } from '@/components/ui';
import { RupiahInput } from '@/components/inputs';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { useCan } from '@/hooks/use-can';
import { MONTH_NAMES } from '@/lib/constants';
import { formatCurrency } from '@/lib/utils';
import { destroy as adjustmentDestroy } from '@/routes/admin/finance/payroll-adjustments';
import { index as payrollPeriodsIndex } from '@/routes/admin/finance/payroll-periods';
import {
    cancel as payrollCancel,
    pay as payrollPay,
} from '@/routes/admin/finance/payrolls';
import { store as adjustmentStore } from '@/routes/admin/finance/payrolls/adjustments';
import type { Payroll, PayrollAdjustment } from './show-columns';
import { createPayrollColumns } from './show-columns';

type Props = {
    payrollPeriod: {
        id: number;
        year: number;
        month: number;
        status: string;
        payrolls: Payroll[];
    };
    auth: {
        user: {
            id: number;
        };
    };
};

export default function PayrollPeriodShow({ payrollPeriod, auth }: Props) {
    const { can, hasAnyRole } = useCan();
    const canViewAll = hasAnyRole(['developer', 'owner', 'direktur', 'admin-toko']);
    const [paying, setPaying] = useState<Payroll | null>(null);
    const [cancelling, setCancelling] = useState<Payroll | null>(null);
    const [addingAdjustment, setAddingAdjustment] = useState<Payroll | null>(
        null,
    );
    const [deletingAdjustment, setDeletingAdjustment] = useState<{
        adjustment: PayrollAdjustment;
        payrollId: number;
    } | null>(null);
    const [adjustmentType, setAdjustmentType] = useState<string>('bonus');

    function handlePay() {
        if (!paying) {
            return;
        }

        router.post(
            payrollPay(paying.id),
            {},
            {
                onSuccess: () => setPaying(null),
            },
        );
    }

    function handleCancel() {
        if (!cancelling) {
            return;
        }

        router.post(
            payrollCancel(cancelling.id),
            {},
            {
                onSuccess: () => setCancelling(null),
            },
        );
    }

    function handleDeleteAdjustment() {
        if (!deletingAdjustment) {
            return;
        }

        router.delete(adjustmentDestroy(deletingAdjustment.adjustment.id), {
            onSuccess: () => setDeletingAdjustment(null),
        });
    }

    const columns = createPayrollColumns({
        handlePay: (payroll) => setPaying(payroll),
        handleCancel: (payroll) => setCancelling(payroll),
        handleAddAdjustment: (payroll) => {
            setAddingAdjustment(payroll);
            setAdjustmentType('bonus');
        },
        handleDeleteAdjustment: (adjustment, payrollId) => {
            setDeletingAdjustment({ adjustment, payrollId });
        },
        can,
        hasAnyRole,
        userId: auth.user.id,
    });

    const activePayrolls = payrollPeriod.payrolls.filter(
        (p) => p.status !== 'cancelled',
    );

    const totalBaseSalary = activePayrolls.reduce(
        (sum, p) => sum + p.base_salary,
        0,
    );
    const totalBonus = activePayrolls.reduce(
        (sum, p) => sum + p.bonus_amount,
        0,
    );
    const totalDeduction = activePayrolls.reduce(
        (sum, p) => sum + p.deduction_amount,
        0,
    );
    const totalAmount = activePayrolls.reduce(
        (sum, p) => sum + p.total_amount,
        0,
    );

    return (
        <>
            <Head
                title={`Gaji - ${MONTH_NAMES[payrollPeriod.month]} ${payrollPeriod.year}`}
            />

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <div className="flex items-center justify-between">
                    <div>
                        <h2 className="text-2xl font-semibold tracking-tight">
                            Gaji {MONTH_NAMES[payrollPeriod.month]}{' '}
                            {payrollPeriod.year}
                        </h2>
                        {canViewAll && (
                            <p className="text-sm text-muted-foreground">
                                {payrollPeriod.payrolls.length} karyawan &middot;
                                Status:{' '}
                                {payrollPeriod.status === 'open'
                                    ? 'Terbuka'
                                    : 'Ditutup'}
                            </p>
                        )}
                    </div>
                    <Button asChild variant="outline">
                        <Link href={payrollPeriodsIndex.url()}>
                            <ArrowLeft className="h-4 w-4" />
                            Kembali
                        </Link>
                    </Button>
                </div>

                <div className="grid grid-cols-2 gap-4 md:grid-cols-4">
                    <div className="rounded-lg border p-4">
                        <p className="text-sm text-muted-foreground">
                            Total Gaji Pokok
                        </p>
                        <p className="text-lg font-semibold">
                            {formatCurrency(totalBaseSalary)}
                        </p>
                    </div>
                    <div className="rounded-lg border p-4">
                        <p className="text-sm text-muted-foreground">
                            Total Bonus
                        </p>
                        <p className="text-lg font-semibold text-green-600">
                            {formatCurrency(totalBonus)}
                        </p>
                    </div>
                    <div className="rounded-lg border p-4">
                        <p className="text-sm text-muted-foreground">
                            Total Potongan
                        </p>
                        <p className="text-lg font-semibold text-red-600">
                            {formatCurrency(totalDeduction)}
                        </p>
                    </div>
                    <div className="rounded-lg border p-4">
                        <p className="text-sm text-muted-foreground">
                            Total Gaji
                        </p>
                        <p className="text-lg font-semibold">
                            {formatCurrency(totalAmount)}
                        </p>
                    </div>
                </div>

                <DataTable
                    columns={columns}
                    data={payrollPeriod.payrolls}
                    searchKey="employee_name"

                    emptyText="Belum ada data gaji."
                />

                {/* Dialog Tambah Penyesuaian */}
                <Dialog
                    open={addingAdjustment !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setAddingAdjustment(null);
                            setAdjustmentType('bonus');
                        }
                    }}
                >
                    <DialogContent>
                        {addingAdjustment && (
                            <Form
                                action={adjustmentStore(addingAdjustment.id)}
                                resetOnSuccess
                                onSuccess={() => {
                                    setAddingAdjustment(null);
                                    setAdjustmentType('bonus');
                                }}
                                onError={() => {
                                    toast.error('Ada data yang belum sesuai, silakan periksa kembali input Anda.');
                                }}
                            >
                                {({ errors, processing }) => (
                                    <>
                                        <DialogHeader>
                                            <DialogTitle>
                                                Tambah Penyesuaian
                                            </DialogTitle>
                                        </DialogHeader>
                                        <div className="grid gap-4 py-4">
                                            <div className="grid gap-2">
                                                <Label>
                                                    Jenis{' '}
                                                    <span className="text-destructive">
                                                        *
                                                    </span>
                                                </Label>
                                                <input
                                                    type="hidden"
                                                    name="type"
                                                    value={adjustmentType}
                                                />
                                                <RadioGroup
                                                    value={adjustmentType}
                                                    onValueChange={
                                                        setAdjustmentType
                                                    }
                                                    className="flex gap-4"
                                                >
                                                    <div className="flex items-center gap-2">
                                                        <RadioGroupItem
                                                            value="bonus"
                                                            id="bonus"
                                                        />
                                                        <Label
                                                            htmlFor="bonus"
                                                            className="font-normal"
                                                        >
                                                            Bonus
                                                        </Label>
                                                    </div>
                                                    <div className="flex items-center gap-2">
                                                        <RadioGroupItem
                                                            value="deduction"
                                                            id="deduction"
                                                        />
                                                        <Label
                                                            htmlFor="deduction"
                                                            className="font-normal"
                                                        >
                                                            Potongan
                                                        </Label>
                                                    </div>
                                                </RadioGroup>
                                                <InputError
                                                    message={errors.type}
                                                />
                                            </div>
                                            <div className="grid gap-2">
                                                <Label>
                                                    Jumlah{' '}
                                                    <span className="text-destructive">
                                                        *
                                                    </span>
                                                </Label>
                                                <RupiahInput
                                                    name="amount"
                                                />
                                                <InputError
                                                    message={errors.amount}
                                                />
                                            </div>
                                            <div className="grid gap-2">
                                                <Label htmlFor="adjustment-description">
                                                    Keterangan{' '}
                                                    <span className="text-destructive">
                                                        *
                                                    </span>
                                                </Label>
                                                <Input
                                                    id="adjustment-description"
                                                    name="description"
                                                    placeholder="Masukkan keterangan"
                                                />
                                                <InputError
                                                    message={errors.description}
                                                />
                                            </div>
                                        </div>
                                        <DialogFooter>
                                            <Button
                                                type="button"
                                                variant="outline"
                                                onClick={() =>
                                                    setAddingAdjustment(null)
                                                }
                                            >
                                                Batal
                                            </Button>
                                            <Button
                                                type="submit"
                                                disabled={processing}
                                            >
                                                {processing
                                                    ? 'Menyimpan...'
                                                    : 'Simpan'}
                                            </Button>
                                        </DialogFooter>
                                    </>
                                )}
                            </Form>
                        )}
                    </DialogContent>
                </Dialog>

                {/* Dialog Konfirmasi Bayar */}
                <ConfirmDialog
                    open={paying !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setPaying(null);
                        }
                    }}
                    title="Tandai Dibayar"
                    description={`Apakah Anda yakin ingin menandai gaji "${paying?.employee?.user?.user_profile?.full_name}" sebesar ${formatCurrency(paying?.total_amount ?? 0)} sebagai sudah dibayar? Penyesuaian tidak dapat ditambahkan setelah dibayar.`}
                    confirmLabel="Bayar"
                    onConfirm={handlePay}
                />

                {/* Dialog Konfirmasi Batalkan */}
                <ConfirmDialog
                    open={cancelling !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setCancelling(null);
                        }
                    }}
                    title="Batalkan Gaji"
                    description={`Apakah Anda yakin ingin membatalkan gaji "${cancelling?.employee?.user?.user_profile?.full_name}"?`}
                    confirmLabel="Batalkan"
                    onConfirm={handleCancel}
                />

                {/* Dialog Konfirmasi Hapus Penyesuaian */}
                <ConfirmDialog
                    open={deletingAdjustment !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setDeletingAdjustment(null);
                        }
                    }}
                    title="Hapus Penyesuaian"
                    description={`Apakah Anda yakin ingin menghapus penyesuaian "${deletingAdjustment?.adjustment.description}" sebesar ${formatCurrency(deletingAdjustment?.adjustment.amount ?? 0)}?`}
                    confirmLabel="Hapus"
                    onConfirm={handleDeleteAdjustment}
                />
            </div>
        </>
    );
}
