import { useMemo, useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Building2, CheckCircle2, RefreshCw, Save, XCircle } from "lucide-react";
import {
  Button,
  Card,
  Group,
  SimpleGrid,
  Text,
  Title,
} from "@mantine/core";
import { api } from "@/services/api";
import type { CompanyProfileResponse } from "@/services/companies.service";
import type { ProfileResponse } from "@/types/profile";
import RoleCard from "./RoleCard";
import { rolesForCompanyType } from "./companyRoles";

interface CompanyRolesCardProps {
  profile: ProfileResponse;
}

/**
 * How an existing role reads on the card. Only an `active` role is "approved" —
 * anything else is locked (a profile already exists, so it cannot be re-added)
 * but must never be presented as granted.
 */
function roleStatusView(p: CompanyProfileResponse): {
  note: string;
  color: string;
  approved: boolean;
} {
  switch (p.status) {
    case "active":
      return { note: `Active · ${p.reference}`, color: "edr-green", approved: true };
    case "pending":
      return { note: "Pending review", color: "yellow.7", approved: false };
    case "rejected":
      return { note: "Rejected", color: "red.7", approved: false };
    case "suspended":
      return { note: "Suspended", color: "orange.7", approved: false };
    case "blacklisted":
      return { note: "Blacklisted", color: "red.7", approved: false };
    default:
      return { note: p.status, color: "edr-muted", approved: false };
  }
}

export default function CompanyRolesCard({ profile }: CompanyRolesCardProps) {
  const queryClient = useQueryClient();

  const options = useMemo(
    () => rolesForCompanyType(profile.companyType),
    [profile.companyType],
  );

  // Roles already persisted, keyed by type. Existence locks the card; the
  // profile's own status decides how it is labelled.
  const profileByType = useMemo(() => {
    const map = new Map<string, CompanyProfileResponse>();
    for (const p of profile.companyProfiles) map.set(p.type, p);
    return map;
  }, [profile.companyProfiles]);

  const [selected, setSelected] = useState<Set<string>>(new Set());

  const toggle = (type: string) => {
    if (profileByType.has(type)) return; // add-only: existing roles are locked
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(type)) next.delete(type);
      else next.add(type);
      return next;
    });
  };

  const mutation = useMutation({
    mutationFn: (types: string[]) =>
      api.companies.addCompanyProfiles.call({ types }),
    onSuccess: () => {
      setSelected(new Set());
      queryClient.invalidateQueries({
        queryKey: api.companies.getProfile.queryKey(),
      });
      queryClient.invalidateQueries({
        queryKey: api.companies.getInfo.queryKey(),
      });
    },
  });

  // Resubmit a rejected role for review. Flips it back to Pending server-side
  // and pings the backoffice, so the fix-and-resubmit loop can happen entirely
  // from settings instead of only from the contract page's rejection banner.
  const reapplyMutation = useMutation({
    mutationFn: (profileId: string) =>
      api.companies.reapplyProfile.call({ profileId }),
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: api.companies.getProfile.queryKey(),
      });
      queryClient.invalidateQueries({
        queryKey: api.companies.getInfo.queryKey(),
      });
    },
  });

  const handleSave = () => {
    if (selected.size === 0) return;
    mutation.mutate(Array.from(selected));
  };

  return (
    <Card padding="lg">
      <Group gap="sm" mb="xs">
        <Building2 size={20} />
        <Title order={3}>Operating Roles</Title>
      </Group>
      <Text c="edr-muted" size="sm" mb="lg">
        {profile.companyType === "customer"
          ? "Select the service(s) your company operates as — importer, exporter and/or freight forwarder."
          : "Your company's operational role."}
      </Text>

      {options.length === 0 ? (
        <Text size="sm" c="edr-muted">
          Role management for this company type is coming soon.
        </Text>
      ) : (
        <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
          {options.map((opt) => {
            const existing = profileByType.get(opt.type);
            const view = existing ? roleStatusView(existing) : undefined;
            const rejected = existing?.status === "rejected";
            return (
              <RoleCard
                key={opt.type}
                label={opt.label}
                description={opt.description}
                icon={opt.icon}
                selected={selected.has(opt.type)}
                locked={Boolean(existing)}
                approved={view?.approved}
                lockedNote={view?.note}
                lockedNoteColor={view?.color}
                detail={
                  (rejected || existing?.status === "suspended") &&
                  existing?.reviewNote
                    ? `Reviewer note: ${existing.reviewNote}`
                    : undefined
                }
                action={
                  rejected ? (
                    <Button
                      size="xs"
                      variant="light"
                      leftSection={<RefreshCw size={14} />}
                      loading={
                        reapplyMutation.isPending &&
                        reapplyMutation.variables === existing.id
                      }
                      onClick={() => reapplyMutation.mutate(existing.id)}
                    >
                      Resubmit for approval
                    </Button>
                  ) : undefined
                }
                onClick={() => toggle(opt.type)}
              />
            );
          })}
        </SimpleGrid>
      )}

      {options.length > 0 && (
        <Group
          justify="space-between"
          mt="xl"
          pt="md"
          style={{ borderTop: "1px solid var(--mantine-color-edr-border-0)" }}
        >
          <Group gap="xs">
            {mutation.isSuccess && (
              <Group gap={6} c="green">
                <CheckCircle2 size={16} />
                <Text size="sm" fw={500}>
                  Profile updated
                </Text>
              </Group>
            )}
            {mutation.isError && (
              <Group gap={6} c="red">
                <XCircle size={16} />
                <Text size="sm" fw={500}>
                  Failed to update profile
                </Text>
              </Group>
            )}
          </Group>
          <Button
            type="button"
            leftSection={<Save size={16} />}
            loading={mutation.isPending}
            disabled={selected.size === 0}
            onClick={handleSave}
          >
            {selected.size > 1 ? "Add Roles" : "Add Role"}
          </Button>
        </Group>
      )}
    </Card>
  );
}
