"use client";

import { CalendarDays, ChevronDown, ChevronRight } from "lucide-react";
import { Fragment, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { cn } from "@/lib/utils";

type Person = {
  id: string;
  name: string;
  contract: string;
  projects: string[];
};

const weeks = ["S40", "S41", "S42", "S43", "S44", "S45"];

export function PlanningPeopleBoard({ people }: { people: Person[] }) {
  const [expandedPersonId, setExpandedPersonId] = useState<string | null>(people[0]?.id ?? null);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between gap-3">
          <div className="flex items-center gap-2">
            <CalendarDays className="h-4 w-4 text-primary" />
            <h2 className="text-base font-semibold">Charge collaborateurs</h2>
          </div>
          <Badge tone="blue">Zoom semaine</Badge>
        </div>
      </CardHeader>
      <CardContent className="overflow-x-auto p-0">
        <table className="w-full min-w-[980px] border-collapse text-sm">
          <thead className="bg-[#272445] text-left text-xs uppercase text-white">
            <tr>
              <th className="w-72 px-4 py-3 font-semibold">Personne</th>
              {weeks.map((week) => (
                <th key={week} className="px-4 py-3 text-center font-semibold">
                  {week}
                </th>
              ))}
              <th className="px-4 py-3 text-right font-semibold">Total</th>
            </tr>
          </thead>
          <tbody>
            {people.map((person, personIndex) => {
              const isExpanded = expandedPersonId === person.id;
              const totals = getPersonWeekTotals(person, personIndex);

              return (
                <Fragment key={person.id}>
                  <tr className="border-t border-border bg-white">
                    <td className="px-4 py-3">
                      <button
                        type="button"
                        aria-expanded={isExpanded}
                        className="flex w-full items-center gap-2 rounded-sm text-left outline-none focus-visible:ring-2 focus-visible:ring-[#E10E49]"
                        onClick={() => setExpandedPersonId(isExpanded ? null : person.id)}
                      >
                        {isExpanded ? <ChevronDown className="h-4 w-4 text-[#E10E49]" /> : <ChevronRight className="h-4 w-4 text-[#272445]" />}
                        <span className="min-w-0">
                          <span className="block truncate font-semibold text-[#272445]">{person.name}</span>
                          <span className="block truncate text-xs text-muted-foreground">{person.contract}</span>
                        </span>
                      </button>
                    </td>
                    {totals.map((value, weekIndex) => (
                      <td key={`${person.id}-${weeks[weekIndex]}`} className="px-4 py-3 text-center">
                        <LoadBadge value={value} />
                      </td>
                    ))}
                    <td className="px-4 py-3 text-right font-bold text-[#272445]">{formatDays(sum(totals))}</td>
                  </tr>
                  {isExpanded ? <PersonProjectRows person={person} personIndex={personIndex} /> : null}
                </Fragment>
              );
            })}
          </tbody>
        </table>
      </CardContent>
    </Card>
  );
}

function PersonProjectRows({ person, personIndex }: { person: Person; personIndex: number }) {
  const projects = person.projects.length > 0 ? person.projects : ["Aucun projet attribué"];

  return (
    <tr className="border-t border-border bg-[#fbf9fc]">
      <td colSpan={weeks.length + 2} className="px-4 py-3">
        <div className="ml-6 overflow-hidden rounded-md border border-[#ddd6e8] bg-white">
          <div className="grid grid-cols-[minmax(220px,1.5fr)_repeat(6,minmax(82px,1fr))_92px] border-b border-border bg-[#f6f2f8] text-xs font-bold uppercase text-[#272445]">
            <div className="px-3 py-2">Projets attribués</div>
            {weeks.map((week) => (
              <div key={week} className="px-3 py-2" />
            ))}
            <div className="px-3 py-2 text-right">Total</div>
          </div>
          {projects.map((project, projectIndex) => {
            const values = getProjectWeekLoads(personIndex, projectIndex);

            return (
              <div
                key={`${person.id}-${project}`}
                className={cn(
                  "grid grid-cols-[minmax(220px,1.5fr)_repeat(6,minmax(82px,1fr))_92px] items-center text-sm",
                  projectIndex % 2 === 0 ? "bg-white" : "bg-[#f8fafb]"
                )}
              >
                <div className="truncate px-3 py-2 font-semibold text-[#272445]">{project}</div>
                {values.map((value, weekIndex) => (
                  <div key={`${project}-${weeks[weekIndex]}`} className="px-3 py-2 text-center">
                    {value > 0 ? <LoadBadge value={value} compact /> : <span className="text-muted-foreground">-</span>}
                  </div>
                ))}
                <div className="px-3 py-2 text-right font-bold text-[#272445]">{formatDays(sum(values))}</div>
              </div>
            );
          })}
        </div>
      </td>
    </tr>
  );
}

function LoadBadge({ value, compact = false }: { value: number; compact?: boolean }) {
  return (
    <span
      className={cn(
        "inline-flex items-center rounded-sm font-bold",
        compact ? "px-2 py-1 text-xs" : "px-2.5 py-1.5 text-sm",
        value >= 4 ? "bg-[#ffe8ca] text-[#8a4c00]" : value >= 2.5 ? "bg-[#dbe7ff] text-[#272445]" : "bg-[#e9f5e2] text-[#315c24]"
      )}
    >
      {formatDays(value)}
    </span>
  );
}

function getPersonWeekTotals(person: Person, personIndex: number) {
  return weeks.map((_, weekIndex) =>
    person.projects.reduce((total, _project, projectIndex) => total + getProjectWeekLoad(personIndex, projectIndex, weekIndex), 0)
  );
}

function getProjectWeekLoads(personIndex: number, projectIndex: number) {
  return weeks.map((_, weekIndex) => getProjectWeekLoad(personIndex, projectIndex, weekIndex));
}

function getProjectWeekLoad(personIndex: number, projectIndex: number, weekIndex: number) {
  const pattern = (personIndex + projectIndex * 2 + weekIndex) % 6;
  if (pattern === 0) {
    return 0;
  }
  return [0.5, 1, 1.5, 2, 2.5, 3][pattern];
}

function sum(values: number[]) {
  return values.reduce((total, value) => total + value, 0);
}

function formatDays(value: number) {
  return `${value.toLocaleString("fr-FR", { maximumFractionDigits: 1 })} j`;
}
