import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useAuth } from "../context/AuthContext";
import { useAlert } from "../context/AlertContext";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { formatDate, formatDatetime } from "../utils/attendanceHelpers";
import { czechPlural } from "../utils/formatters";
import {
  leavePendingOptions,
  leaveProcessedOptions,
} from "../lib/queries/leave";
import Forbidden from "../components/Forbidden";
import { useApiMutation } from "../lib/queries/mutations";
import {
  Button,
  Card,
  DataTable,
  ConfirmDialog,
  Modal,
  StatusChip,
  Field,
  TextField,
  PageHeader,
  PageEnter,
  EmptyState,
  LoadingState,
  Tabs,
  TabPanel,
  type DataColumn,
  type TabDef,
} from "../ui";

const API_BASE = "/api/admin";

const leaveTypeLabels: Record<string, string> = {
  vacation: "Dovolená",
  sick: "Nemoc",
  unpaid: "Neplacené volno",
};

const statusLabels: Record<string, string> = {
  pending: "Čeká na schválení",
  approved: "Schváleno",
  rejected: "Zamítnuto",
  cancelled: "Zrušeno",
};

// Leave type → StatusChip color
const leaveTypeColor: Record<
  string,
  "info" | "error" | "default" | "success" | "warning"
> = {
  vacation: "info",
  sick: "error",
  unpaid: "default",
};

// Status → StatusChip color
const statusColor: Record<string, "warning" | "success" | "error" | "default"> =
  {
    pending: "warning",
    approved: "success",
    rejected: "error",
    cancelled: "default",
  };

interface RawLeaveRequest {
  id: number;
  leave_type: string;
  date_from: string;
  date_to: string;
  total_days: number;
  total_hours: number;
  status: string;
  notes?: string;
  reviewer_note?: string;
  created_at: string;
  reviewed_at?: string;
  users_leave_requests_user_idTousers?: {
    first_name: string;
    last_name: string;
  };
  users_leave_requests_reviewer_idTousers?: {
    first_name: string;
    last_name: string;
  } | null;
}

interface LeaveRequest {
  id: number;
  employee_name: string;
  leave_type: string;
  date_from: string;
  date_to: string;
  total_days: number;
  total_hours: number;
  status: string;
  notes?: string;
  reviewer_name?: string;
  reviewer_note?: string;
  created_at: string;
  reviewed_at?: string;
}

function mapLeaveRequest(raw: RawLeaveRequest): LeaveRequest {
  const user = raw.users_leave_requests_user_idTousers;
  const reviewer = raw.users_leave_requests_reviewer_idTousers;
  return {
    id: raw.id,
    employee_name: user ? `${user.first_name} ${user.last_name}` : "Neznámý",
    leave_type: raw.leave_type,
    date_from: raw.date_from,
    date_to: raw.date_to,
    total_days: raw.total_days,
    total_hours: raw.total_hours,
    status: raw.status,
    notes: raw.notes,
    reviewer_name: reviewer
      ? `${reviewer.first_name} ${reviewer.last_name}`
      : undefined,
    reviewer_note: raw.reviewer_note,
    created_at: raw.created_at,
    reviewed_at: raw.reviewed_at,
  };
}

export default function LeaveApproval() {
  const { hasPermission } = useAuth();
  const alert = useAlert();
  const [activeTab, setActiveTab] = useState<"pending" | "processed">(
    "pending",
  );
  const { data: pendingData, isPending: loading } = useQuery(
    leavePendingOptions(),
  );
  const { data: processedData } = useQuery({
    ...leaveProcessedOptions(),
    enabled: activeTab === "processed",
  });
  const pendingRequests =
    (pendingData as RawLeaveRequest[] | undefined)?.map(mapLeaveRequest) ?? [];
  const pendingCount = pendingRequests.length;
  const processedRequests =
    (processedData as RawLeaveRequest[] | undefined)?.map(mapLeaveRequest) ??
    [];

  const [approveModal, setApproveModal] = useState<{
    open: boolean;
    request: LeaveRequest | null;
  }>({ open: false, request: null });
  const [rejectModal, setRejectModal] = useState<{
    open: boolean;
    request: LeaveRequest | null;
  }>({ open: false, request: null });
  const [rejectNote, setRejectNote] = useState("");

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

  const approveMutation = useApiMutation<
    { id: number; status: "approved" },
    unknown
  >({
    url: ({ id }) => `${API_BASE}/leave-requests/${id}`,
    method: () => "PUT",
    invalidate: ["leave-requests", "leave", "attendance", "users"],
    onSuccess: () => {
      setApproveModal({ open: false, request: null });
      alert.success("Žádost byla schválena");
    },
  });

  const rejectMutation = useApiMutation<
    { id: number; status: "rejected"; reviewer_note: string },
    unknown
  >({
    url: ({ id }) => `${API_BASE}/leave-requests/${id}`,
    method: () => "PUT",
    invalidate: ["leave-requests", "leave", "attendance", "users"],
    onSuccess: () => {
      setRejectModal({ open: false, request: null });
      setRejectNote("");
      alert.success("Žádost byla zamítnuta");
    },
  });

  const handleApprove = async () => {
    if (!approveModal.request) return;
    try {
      await approveMutation.mutateAsync({
        id: approveModal.request.id,
        status: "approved",
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleReject = async () => {
    if (!rejectNote.trim()) {
      alert.error("Důvod zamítnutí je povinný");
      return;
    }
    if (!rejectModal.request) return;
    try {
      await rejectMutation.mutateAsync({
        id: rejectModal.request.id,
        status: "rejected",
        reviewer_note: rejectNote,
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  if (loading) {
    return <LoadingState />;
  }

  const tabs: TabDef[] = [
    { value: "pending", label: `Ke schválení (${pendingCount})` },
    { value: "processed", label: "Vyřízené" },
  ];

  const processedColumns: DataColumn<LeaveRequest>[] = [
    {
      key: "employee_name",
      header: "Zaměstnanec",
      width: "16%",
      bold: true,
      render: (req) => req.employee_name,
    },
    {
      key: "leave_type",
      header: "Typ",
      width: "13%",
      render: (req) => (
        <StatusChip
          label={leaveTypeLabels[req.leave_type] || req.leave_type}
          color={leaveTypeColor[req.leave_type] ?? "default"}
        />
      ),
    },
    {
      key: "date_from",
      header: "Od",
      width: "10%",
      mono: true,
      render: (req) => formatDate(req.date_from),
    },
    {
      key: "date_to",
      header: "Do",
      width: "10%",
      mono: true,
      render: (req) => formatDate(req.date_to),
    },
    {
      key: "total_days",
      header: "Dny",
      width: "6%",
      mono: true,
      render: (req) => String(req.total_days),
    },
    {
      key: "status",
      header: "Stav",
      width: "13%",
      render: (req) => (
        <StatusChip
          label={statusLabels[req.status] || req.status}
          color={statusColor[req.status] ?? "default"}
        />
      ),
    },
    {
      key: "reviewer_name",
      header: "Schválil",
      width: "12%",
      render: (req) => req.reviewer_name || "—",
    },
    {
      key: "reviewer_note",
      header: "Poznámka",
      width: "12%",
      render: (req) =>
        req.reviewer_note ? (
          <Box component="span" title={req.reviewer_note}>
            {req.reviewer_note.length > 40
              ? `${req.reviewer_note.substring(0, 40)}...`
              : req.reviewer_note}
          </Box>
        ) : (
          "—"
        ),
    },
    {
      key: "reviewed_at",
      header: "Vyřízeno",
      width: "8%",
      mono: true,
      render: (req) => formatDatetime(req.reviewed_at),
    },
  ];

  return (
    <PageEnter>
      <PageHeader
        title="Schvalování nepřítomnosti"
        subtitle={
          pendingCount > 0
            ? `${pendingCount} ${czechPlural(pendingCount, "žádost čeká", "žádosti čekají", "žádostí čeká")} na schválení`
            : "Žádné čekající žádosti"
        }
      />

      <Tabs
        value={activeTab}
        onChange={(v) => setActiveTab(v as "pending" | "processed")}
        tabs={tabs}
      />

      {/* Pending Tab */}
      <TabPanel value="pending" current={activeTab}>
        {pendingRequests.length === 0 ? (
          <Card>
            <EmptyState title="Žádné čekající žádosti" />
          </Card>
        ) : (
          <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
            {pendingRequests.map((req) => (
              <Card key={req.id}>
                <Box
                  sx={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "flex-start",
                    flexWrap: "wrap",
                    gap: 2,
                  }}
                >
                  <Box sx={{ flex: 1 }}>
                    <Box
                      sx={{
                        display: "flex",
                        alignItems: "center",
                        gap: 1.5,
                        mb: 1,
                      }}
                    >
                      <Typography
                        component="strong"
                        sx={{ fontSize: "1rem", fontWeight: 600 }}
                      >
                        {req.employee_name}
                      </Typography>
                      <StatusChip
                        label={
                          leaveTypeLabels[req.leave_type] || req.leave_type
                        }
                        color={leaveTypeColor[req.leave_type] ?? "default"}
                      />
                    </Box>
                    <Box
                      sx={{
                        display: "flex",
                        gap: 3,
                        flexWrap: "wrap",
                        fontSize: "0.875rem",
                        color: "text.secondary",
                      }}
                    >
                      <Box component="span">
                        <strong>{formatDate(req.date_from)}</strong> —{" "}
                        <strong>{formatDate(req.date_to)}</strong>
                      </Box>
                      <Box component="span">
                        {req.total_days}{" "}
                        {czechPlural(req.total_days, "den", "dny", "dnů")} (
                        {req.total_hours}h)
                      </Box>
                      <Box component="span" sx={{ color: "text.disabled" }}>
                        Podáno: {formatDatetime(req.created_at)}
                      </Box>
                    </Box>
                    {req.notes && (
                      <Box
                        sx={{
                          mt: 1,
                          fontSize: "0.875rem",
                          fontStyle: "italic",
                          color: "text.secondary",
                        }}
                      >
                        {req.notes}
                      </Box>
                    )}
                  </Box>
                  <Box sx={{ display: "flex", gap: 1, flexShrink: 0 }}>
                    <Button
                      size="small"
                      color="success"
                      variant="outlined"
                      onClick={() =>
                        setApproveModal({ open: true, request: req })
                      }
                    >
                      Schválit
                    </Button>
                    <Button
                      size="small"
                      color="error"
                      variant="outlined"
                      onClick={() =>
                        setRejectModal({ open: true, request: req })
                      }
                    >
                      Zamítnout
                    </Button>
                  </Box>
                </Box>
              </Card>
            ))}
          </Box>
        )}
      </TabPanel>

      {/* Processed Tab */}
      <TabPanel value="processed" current={activeTab}>
        <Card>
          <DataTable<LeaveRequest>
            columns={processedColumns}
            rows={processedRequests}
            rowKey={(req) => req.id}
            empty={<EmptyState title="Zatím žádné vyřízené žádosti" />}
          />
        </Card>
      </TabPanel>

      {/* Approve Confirmation */}
      <ConfirmDialog
        isOpen={approveModal.open}
        onClose={() => setApproveModal({ open: false, request: null })}
        onConfirm={handleApprove}
        title="Schválit žádost"
        message={
          approveModal.request
            ? `Schválit ${approveModal.request.total_days} ${czechPlural(approveModal.request.total_days, "den", "dny", "dnů")} ${leaveTypeLabels[approveModal.request.leave_type]?.toLowerCase() || ""} pro ${approveModal.request.employee_name}?`
            : ""
        }
        confirmText="Schválit"
        loading={approveMutation.isPending}
      />

      {/* Reject Modal */}
      <Modal
        isOpen={rejectModal.open && !!rejectModal.request}
        onClose={() => {
          setRejectModal({ open: false, request: null });
          setRejectNote("");
        }}
        onSubmit={handleReject}
        title="Zamítnout žádost"
        submitText="Zamítnout"
        loading={rejectMutation.isPending}
      >
        {rejectModal.request && (
          <>
            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
              {rejectModal.request.employee_name} —{" "}
              {leaveTypeLabels[rejectModal.request.leave_type]},{" "}
              {formatDate(rejectModal.request.date_from)} —{" "}
              {formatDate(rejectModal.request.date_to)} (
              {rejectModal.request.total_days} dnů)
            </Typography>
            <Field label="Důvod zamítnutí" required>
              <TextField
                value={rejectNote}
                onChange={(e) => setRejectNote(e.target.value)}
                placeholder="Uveďte důvod zamítnutí..."
                multiline
                rows={3}
                autoFocus
              />
            </Field>
          </>
        )}
      </Modal>
    </PageEnter>
  );
}
