import { create } from 'zustand';
import { api, ApiError } from '../api/client';
import type { Payroll, PayrollOverviewRow } from '../api/types';
import { currentMonthKey, shiftMonthKey } from '../lib/month';

export interface Adjustments {
  tips_amount: number;
  bonus_amount: number;
  other_amount: number;
}

interface AdminPayrollState {
  period: string;
  rows: PayrollOverviewRow[] | null;
  busy: boolean;
  error: string | null;

  load: () => Promise<void>;
  setPeriod: (period: string) => Promise<void>;
  prevPeriod: () => Promise<void>;
  nextPeriod: () => Promise<void>;
  saveAdjustments: (employeeId: number, data: Adjustments) => Promise<void>;
  lock: (employeeId: number) => Promise<void>;
  reopen: (employeeId: number) => Promise<void>;
  markPaid: (employeeId: number) => Promise<void>;
}

const useAdminPayrollStore = create<AdminPayrollState>((set, get) => ({
  period: currentMonthKey(),
  rows: null,
  busy: false,
  error: null,

  load: async () => {
    try {
      const res = await api.get<{ rows: PayrollOverviewRow[] }>(`/admin/payroll?period=${get().period}`);
      set({ rows: res.rows, error: null });
    } catch {
      set({ error: 'Nepodařilo se načíst mzdy' });
    }
  },

  setPeriod: async (period) => {
    set({ period });
    await get().load();
  },

  prevPeriod: async () => {
    await get().setPeriod(shiftMonthKey(get().period, -1));
  },

  nextPeriod: async () => {
    await get().setPeriod(shiftMonthKey(get().period, 1));
  },

  saveAdjustments: async (employeeId, data) => {
    set({ busy: true, error: null });
    try {
      await api.post<{ payroll: Payroll }>(`/admin/payroll/${employeeId}/adjustments`, {
        period: get().period,
        ...data,
      });
      await get().load();
    } catch (err) {
      set({ error: err instanceof ApiError ? err.message : 'Uložení se nezdařilo' });
    } finally {
      set({ busy: false });
    }
  },

  lock: async (employeeId) => {
    set({ busy: true, error: null });
    try {
      await api.post(`/admin/payroll/${employeeId}/lock`, { period: get().period });
      await get().load();
    } catch (err) {
      set({ error: err instanceof ApiError ? err.message : 'Uzamčení se nezdařilo' });
    } finally {
      set({ busy: false });
    }
  },

  reopen: async (employeeId) => {
    set({ busy: true, error: null });
    try {
      await api.post(`/admin/payroll/${employeeId}/reopen`, { period: get().period });
      await get().load();
    } catch (err) {
      set({ error: err instanceof ApiError ? err.message : 'Odemknutí se nezdařilo' });
    } finally {
      set({ busy: false });
    }
  },

  markPaid: async (employeeId) => {
    set({ busy: true, error: null });
    try {
      await api.post(`/admin/payroll/${employeeId}/paid`, { period: get().period });
      await get().load();
    } catch (err) {
      set({ error: err instanceof ApiError ? err.message : 'Označení se nezdařilo' });
    } finally {
      set({ busy: false });
    }
  },
}));

export default useAdminPayrollStore;
