import { useState } from "react";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import { useQuery } from "@tanstack/react-query";
import {
  attendanceBalancesOptions,
  attendanceWorkFundOptions,
  attendanceProjectReportOptions,
  type BalanceEntry,
  type FundUserData,
} from "../lib/queries/attendance";

import { useApiMutation } from "../lib/queries/mutations";
import {
  Card,
  DataTable,
  Modal,
  ConfirmDialog,
  Field,
  TextField,
  Select,
  StatusChip,
  PageHeader,
  PageEnter,
  EmptyState,
  LoadingState,
  ProgressBar,
  type DataColumn,
  type ProgressColor,
} from "../ui";

const API_BASE = "/api/admin";

const EditIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
    <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
  </svg>
);
const ResetIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <polyline points="3 6 5 6 21 6" />
    <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
  </svg>
);

/** Maps the remaining-vacation value to a kit color token (mirrors legacy
 *  getVacationClass: <=0 danger, <20 warning, otherwise default text color). */
const getVacationColor = (remaining: number): string | undefined => {
  if (remaining <= 0) return "error.main";
  if (remaining < 20) return "warning.main";
  return undefined;
};

const renderFundDiff = (data: { overtime: number; missing: number }) => {
  if (data.overtime > 0) {
    return (
      <Typography
        component="span"
        sx={{ fontWeight: 600, color: "warning.main", fontSize: "0.8rem" }}
      >
        +{data.overtime}h
      </Typography>
    );
  }
  if (data.missing > 0) {
    return (
      <Typography
        component="span"
        sx={{ color: "error.main", fontSize: "0.8rem" }}
      >
        -{data.missing}h
      </Typography>
    );
  }
  return (
    <Typography
      component="span"
      sx={{ color: "success.main", fontSize: "0.8rem" }}
    >
      0h
    </Typography>
  );
};

const renderMonthlyStatus = (
  us: FundUserData,
  isFulfilled: boolean,
  isCurrentMonth: boolean,
) => {
  if (us.overtime > 0) {
    return <StatusChip color="warning" label={`+${us.overtime}h`} />;
  }
  if (us.missing > 0) {
    return <StatusChip color="error" label={`-${us.missing}h`} />;
  }
  if (isFulfilled && !isCurrentMonth) {
    return <StatusChip color="success" label="OK" />;
  }
  return null;
};

/** Maps a user's monthly fund state to a ProgressBar color token. Mirrors the
 *  legacy getProgressBackground gradient conditional: overtime→warning,
 *  fulfilled→success, current month→primary (was the accent gradient),
 *  otherwise→error (deficit). */
const getProgressColor = (
  us: FundUserData,
  isFulfilled: boolean,
  isCurrentMonth: boolean,
): ProgressColor => {
  if (us.overtime > 0) return "warning";
  if (isFulfilled) return "success";
  if (isCurrentMonth) return "primary";
  return "error";
};

export default function AttendanceBalances() {
  const alert = useAlert();
  const { hasPermission } = useAuth();
  const [year, setYear] = useState(new Date().getFullYear());
  const { data: balancesData, isPending: balancesPending } = useQuery(
    attendanceBalancesOptions(year),
  );
  const { data: fundData, isPending: fundPending } = useQuery(
    attendanceWorkFundOptions(year),
  );
  const { data: projectData, isPending: projectPending } = useQuery(
    attendanceProjectReportOptions(year),
  );

  const [showEditModal, setShowEditModal] = useState(false);
  const [editingUser, setEditingUser] = useState<{
    id: string;
    name: string;
  } | null>(null);
  const [editForm, setEditForm] = useState({
    vacation_total: 160,
    vacation_used: 0,
    sick_used: 0,
  });

  const [resetConfirm, setResetConfirm] = useState<{
    show: boolean;
    userId: string | null;
    userName: string;
  }>({ show: false, userId: null, userName: "" });

  const editMutation = useApiMutation<
    {
      user_id: string;
      year: number;
      action_type: "edit";
      vacation_total: number;
      vacation_used: number;
      sick_used: number;
    },
    { message?: string; error?: string }
  >({
    url: () => `${API_BASE}/attendance?action=balances`,
    method: () => "POST",
    invalidate: ["attendance", "users"],
  });

  const resetMutation = useApiMutation<
    { user_id: string; year: number; action_type: "reset" },
    { message?: string; error?: string }
  >({
    url: () => `${API_BASE}/attendance?action=balances`,
    method: () => "POST",
    invalidate: ["attendance", "users"],
    onSuccess: (data) => {
      setResetConfirm({ show: false, userId: null, userName: "" });
      alert.success(data?.message || "Operace dokončena");
    },
  });

  if (!hasPermission("attendance.balances")) return <Forbidden />;

  const openEditModal = (userId: string, balance: BalanceEntry) => {
    setEditingUser({ id: userId, name: balance.name });
    setEditForm({
      vacation_total: balance.vacation_total,
      vacation_used: balance.vacation_used,
      sick_used: balance.sick_used,
    });
    setShowEditModal(true);
  };

  const handleEditSubmit = async () => {
    if (!editingUser) return;
    try {
      const result = await editMutation.mutateAsync({
        user_id: editingUser.id,
        year,
        action_type: "edit",
        ...editForm,
      });
      setShowEditModal(false);
      alert.success(result?.message || "Upraveno");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleReset = async () => {
    if (!resetConfirm.userId) return;
    try {
      await resetMutation.mutateAsync({
        user_id: resetConfirm.userId,
        year,
        action_type: "reset",
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const years: number[] = [];
  const currentYear = new Date().getFullYear();
  const currentMonth = new Date().getMonth() + 1;
  for (let y = currentYear - 5; y <= currentYear + 5; y++) {
    years.push(y);
  }

  const getYearFundTotals = (userId: string) => {
    if (!fundData?.months || Object.keys(fundData.months).length === 0)
      return null;
    let totalFund = 0;
    let totalWorked = 0;
    let totalCovered = 0;
    for (const monthData of Object.values(fundData.months)) {
      // Use prorated fund (fund_to_date) for current month, full fund for past
      totalFund += monthData.fund_to_date ?? monthData.fund;
      const us = monthData.users?.[userId];
      if (us) {
        totalWorked += us.worked;
        totalCovered += us.covered;
      }
    }
    const missing = Math.max(
      0,
      Math.round((totalFund - totalCovered) * 10) / 10,
    );
    const overtime = Math.max(
      0,
      Math.round((totalCovered - totalFund) * 10) / 10,
    );
    return {
      fund: totalFund,
      worked: Math.round(totalWorked * 10) / 10,
      covered: Math.round(totalCovered * 10) / 10,
      missing,
      overtime,
    };
  };

  const balanceRows = balancesData
    ? Object.entries(balancesData.balances).map(([userId, balance]) => ({
        userId,
        balance,
      }))
    : [];

  const columns: DataColumn<{ userId: string; balance: BalanceEntry }>[] = [
    {
      key: "name",
      header: "Zaměstnanec",
      width: "20%",
      bold: true,
      render: ({ balance }) => balance.name,
    },
    {
      key: "vacation_total",
      header: "Nárok (h)",
      width: "10%",
      mono: true,
      render: ({ balance }) => balance.vacation_total,
    },
    {
      key: "vacation_used",
      header: "Čerpáno (h)",
      width: "10%",
      mono: true,
      render: ({ balance }) => balance.vacation_used.toFixed(1),
    },
    {
      key: "vacation_remaining",
      header: "Zbývá (h)",
      width: "10%",
      mono: true,
      render: ({ balance }) => (
        <Box
          component="span"
          sx={{ color: getVacationColor(balance.vacation_remaining) }}
        >
          {balance.vacation_remaining.toFixed(1)}
        </Box>
      ),
    },
    {
      key: "sick_used",
      header: "Nemoc (h)",
      width: "9%",
      mono: true,
      render: ({ balance }) => balance.sick_used.toFixed(1),
    },
    {
      key: "fund",
      header: "Fond roku",
      width: "9%",
      mono: true,
      render: ({ userId }) => {
        const yf = getYearFundTotals(userId);
        return yf ? `${yf.fund}h` : "—";
      },
    },
    {
      key: "covered",
      header: "Pokryto",
      width: "9%",
      mono: true,
      render: ({ userId }) => {
        const yf = getYearFundTotals(userId);
        return yf ? `${yf.covered}h` : "—";
      },
    },
    {
      key: "diff",
      header: "+/−",
      width: "8%",
      mono: true,
      render: ({ userId }) => {
        const yf = getYearFundTotals(userId);
        return yf ? renderFundDiff(yf) : "—";
      },
    },
    {
      key: "actions",
      header: "Akce",
      width: "10%",
      align: "right",
      render: ({ userId, balance }) => (
        <Box sx={{ display: "flex", gap: 0.5, justifyContent: "flex-end" }}>
          <IconButton
            size="small"
            onClick={() => openEditModal(userId, balance)}
            aria-label="Upravit"
            title="Upravit"
          >
            {EditIcon}
          </IconButton>
          <IconButton
            size="small"
            color="error"
            onClick={() =>
              setResetConfirm({
                show: true,
                userId,
                userName: balance.name,
              })
            }
            aria-label="Resetovat"
            title="Resetovat"
          >
            {ResetIcon}
          </IconButton>
        </Box>
      ),
    },
  ];

  return (
    <PageEnter>
      <PageHeader
        title="Správa bilancí"
        actions={
          <Box sx={{ minWidth: 120 }}>
            <Select
              value={String(year)}
              onChange={(val) => setYear(parseInt(val))}
              options={years.map((y) => ({
                value: String(y),
                label: String(y),
              }))}
            />
          </Box>
        }
      />

      <Card>
        {balancesPending ? (
          <LoadingState />
        ) : balanceRows.length === 0 ? (
          <EmptyState title="Žádní uživatelé k zobrazení." />
        ) : (
          <DataTable<{ userId: string; balance: BalanceEntry }>
            columns={columns}
            rows={balanceRows}
            rowKey={(row) => row.userId}
          />
        )}
      </Card>

      {/* Monthly Fund Overview */}
      {!fundPending &&
        fundData?.months &&
        Object.keys(fundData.months).length > 0 && (
          <Box sx={{ mt: 4 }}>
            <Typography variant="h6" sx={{ mb: 2 }}>
              Měsíční přehled fondu {year}
            </Typography>
            <Box
              sx={{
                display: "grid",
                gridTemplateColumns: { xs: "1fr", md: "repeat(3, 1fr)" },
                gap: 2,
              }}
            >
              {Object.entries(fundData.months).map(([monthKey, monthData]) => {
                const isCurrentMonth =
                  year === currentYear && parseInt(monthKey) === currentMonth;
                return (
                  <Card
                    key={monthKey}
                    sx={
                      isCurrentMonth
                        ? {
                            borderColor: "primary.main",
                            boxShadow: (theme) =>
                              `0 0 0 1px ${theme.palette.primary.main}`,
                          }
                        : undefined
                    }
                  >
                    <Box
                      sx={{
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                        mb: 1.5,
                      }}
                    >
                      <Typography
                        component="h3"
                        sx={{
                          fontWeight: 600,
                          fontSize: "1rem",
                          display: "flex",
                          alignItems: "center",
                          gap: 0.75,
                        }}
                      >
                        {monthData.month_name}
                        {isCurrentMonth && (
                          <StatusChip color="info" label="aktuální" />
                        )}
                      </Typography>
                      <Typography
                        variant="caption"
                        color="text.secondary"
                        sx={{ fontSize: "12px" }}
                      >
                        {monthData.fund_to_date ?? monthData.fund}h (
                        {Math.round(
                          (monthData.fund_to_date ?? monthData.fund) / 8,
                        )}{" "}
                        dnů)
                      </Typography>
                    </Box>
                    <Box
                      sx={{
                        display: "flex",
                        flexDirection: "column",
                        gap: 1,
                      }}
                    >
                      {fundData?.users &&
                        fundData.users.map((user) => {
                          const us = monthData.users?.[String(user.id)];
                          if (!us) return null;
                          const effectiveFund =
                            monthData.fund_to_date ?? monthData.fund;
                          const pct =
                            effectiveFund > 0
                              ? Math.min(
                                  100,
                                  (us.covered / effectiveFund) * 100,
                                )
                              : 0;
                          const isFulfilled = us.covered >= effectiveFund;
                          return (
                            <Box key={user.id}>
                              <Box
                                sx={{
                                  display: "flex",
                                  justifyContent: "space-between",
                                  alignItems: "center",
                                  fontSize: "12px",
                                  mb: 0.5,
                                }}
                              >
                                <Typography
                                  variant="caption"
                                  sx={{ color: "text.primary" }}
                                >
                                  {us.name}
                                </Typography>
                                <Box
                                  sx={{
                                    display: "flex",
                                    gap: 1,
                                    alignItems: "center",
                                  }}
                                >
                                  <Typography
                                    variant="caption"
                                    color="text.secondary"
                                  >
                                    {us.worked}h
                                  </Typography>
                                  {renderMonthlyStatus(
                                    us,
                                    isFulfilled,
                                    isCurrentMonth,
                                  )}
                                </Box>
                              </Box>
                              <ProgressBar
                                value={pct}
                                color={getProgressColor(
                                  us,
                                  isFulfilled,
                                  isCurrentMonth,
                                )}
                                height={4}
                              />
                            </Box>
                          );
                        })}
                    </Box>
                  </Card>
                );
              })}
            </Box>
          </Box>
        )}

      {fundPending && <LoadingState />}

      {/* Monthly Project Overview */}
      {!projectPending &&
        projectData?.months &&
        Object.keys(projectData.months).length > 0 && (
          <Box sx={{ mt: 4 }}>
            <Typography variant="h6" sx={{ mb: 2 }}>
              Měsíční přehled projektů {year}
            </Typography>
            <Box
              sx={{
                display: "grid",
                gridTemplateColumns: { xs: "1fr", md: "repeat(3, 1fr)" },
                gap: 2,
              }}
            >
              {Object.entries(projectData.months).map(
                ([monthKey, monthInfo]) => {
                  const isCurrentMonth =
                    year === currentYear && parseInt(monthKey) === currentMonth;
                  const totalHours = monthInfo.projects.reduce(
                    (sum, p) => sum + p.hours,
                    0,
                  );
                  if (monthInfo.projects.length === 0) return null;
                  return (
                    <Card
                      key={monthKey}
                      sx={
                        isCurrentMonth
                          ? {
                              borderColor: "primary.main",
                              boxShadow: (theme) =>
                                `0 0 0 1px ${theme.palette.primary.main}`,
                            }
                          : undefined
                      }
                    >
                      <Box
                        sx={{
                          display: "flex",
                          justifyContent: "space-between",
                          alignItems: "center",
                          mb: 1.5,
                        }}
                      >
                        <Typography
                          component="h3"
                          sx={{
                            fontWeight: 600,
                            fontSize: "1rem",
                            display: "flex",
                            alignItems: "center",
                            gap: 0.75,
                          }}
                        >
                          {monthInfo.month_name}
                          {isCurrentMonth && (
                            <StatusChip color="info" label="aktuální" />
                          )}
                        </Typography>
                        <Typography
                          variant="caption"
                          color="text.secondary"
                          sx={{ fontSize: "12px", fontWeight: 600 }}
                        >
                          {totalHours.toFixed(1)}h
                        </Typography>
                      </Box>
                      <Box
                        sx={{
                          display: "flex",
                          flexDirection: "column",
                          gap: 1.5,
                        }}
                      >
                        {monthInfo.projects.map((proj) => (
                          <Box key={proj.project_id || "no-project"}>
                            <Box
                              sx={{
                                display: "flex",
                                justifyContent: "space-between",
                                alignItems: "center",
                                mb: 0.5,
                              }}
                            >
                              <Typography
                                variant="caption"
                                sx={{
                                  fontWeight: 600,
                                  color: "text.primary",
                                }}
                              >
                                {proj.project_id
                                  ? proj.project_number
                                  : "Bez projektu"}
                              </Typography>
                              <Typography
                                variant="caption"
                                color="text.secondary"
                                sx={{ fontWeight: 600 }}
                              >
                                {proj.hours.toFixed(1)}h
                              </Typography>
                            </Box>
                            {proj.project_id && proj.project_name && (
                              <Typography
                                variant="caption"
                                color="text.disabled"
                                sx={{
                                  display: "block",
                                  fontSize: "0.7rem",
                                  mb: 0.5,
                                }}
                              >
                                {proj.project_name}
                              </Typography>
                            )}
                            <Box
                              sx={{
                                display: "flex",
                                flexDirection: "column",
                                gap: 0.75,
                              }}
                            >
                              {proj.users.map((u) => {
                                const pct =
                                  proj.hours > 0
                                    ? Math.min(
                                        100,
                                        (u.hours / proj.hours) * 100,
                                      )
                                    : 0;
                                return (
                                  <Box key={u.user_id}>
                                    <Box
                                      sx={{
                                        display: "flex",
                                        justifyContent: "space-between",
                                        alignItems: "center",
                                        mb: 0.25,
                                      }}
                                    >
                                      <Typography
                                        variant="caption"
                                        color="text.secondary"
                                        sx={{ fontSize: "11px" }}
                                      >
                                        {u.user_name}
                                      </Typography>
                                      <Typography
                                        variant="caption"
                                        color="text.secondary"
                                        sx={{ fontSize: "11px" }}
                                      >
                                        {u.hours.toFixed(1)}h
                                      </Typography>
                                    </Box>
                                    <ProgressBar
                                      value={pct}
                                      color={
                                        proj.project_id ? "primary" : "info"
                                      }
                                      height={4}
                                    />
                                  </Box>
                                );
                              })}
                            </Box>
                          </Box>
                        ))}
                      </Box>
                    </Card>
                  );
                },
              )}
            </Box>
          </Box>
        )}

      {projectPending && <LoadingState />}

      {/* Edit Modal */}
      <Modal
        isOpen={showEditModal && !!editingUser}
        onClose={() => setShowEditModal(false)}
        onSubmit={handleEditSubmit}
        title="Upravit dovolenou"
        subtitle={editingUser?.name}
        loading={editMutation.isPending}
      >
        <Field label="Nárok na dovolenou (hodiny)">
          <TextField
            type="number"
            value={editForm.vacation_total}
            onChange={(e) =>
              setEditForm({
                ...editForm,
                vacation_total: parseFloat(e.target.value) || 0,
              })
            }
            slotProps={{ htmlInput: { min: 0, max: 500, step: 1 } }}
          />
        </Field>

        <Field label="Čerpáno dovolené (hodiny)">
          <TextField
            type="number"
            value={editForm.vacation_used}
            onChange={(e) =>
              setEditForm({
                ...editForm,
                vacation_used: parseFloat(e.target.value) || 0,
              })
            }
            slotProps={{ htmlInput: { min: 0, max: 500, step: 0.5 } }}
          />
        </Field>

        <Field label="Čerpáno nemocenské (hodiny)">
          <TextField
            type="number"
            value={editForm.sick_used}
            onChange={(e) =>
              setEditForm({
                ...editForm,
                sick_used: parseFloat(e.target.value) || 0,
              })
            }
            slotProps={{ htmlInput: { min: 0, max: 500, step: 0.5 } }}
          />
        </Field>
      </Modal>

      {/* Reset Confirmation */}
      <ConfirmDialog
        isOpen={resetConfirm.show}
        onClose={() =>
          setResetConfirm({ show: false, userId: null, userName: "" })
        }
        onConfirm={handleReset}
        title="Resetovat bilanci"
        message={`Opravdu chcete vynulovat čerpání dovolené a nemocenské pro ${resetConfirm.userName} za rok ${year}?`}
        confirmText="Resetovat"
        confirmVariant="danger"
        loading={resetMutation.isPending}
      />
    </PageEnter>
  );
}
