./knowledge-base/frontend/src/components/BrowseLists.tsx

import {
  Box,
  Typography,
  Grid,
  Card,
  CardActionArea,
  Chip,
  Button,
} from "@mui/material";
import { ArrowBack as ArrowBackIcon } from "@mui/icons-material";
import type { EraMaster, ProgramMaster, DocumentSummary } from "../types";
import {
  DocumentGenreSelector,
  DOCUMENT_GENRE_OPTIONS,
} from "./DocumentGenreSelector";

const UNSET_LABEL = "未設定";

function getCountByKey(map: Map<string, number>, key: string): number {
  return map.get(key) || map.get(key.replace(/戰/g, "戦")) || 0;
}

export function BrowseEraList({
  eraList,
  eraCounts,
  unsetFilterValue,
  onSelectEra,
}: {
  eraList: EraMaster[];
  eraCounts: Map<string, number>;
  unsetFilterValue: string;
  onSelectEra: (era: string) => void;
}) {
  const eraItems = [
    ...eraList.map((era) => ({
      id: era.id,
      label: era.label,
      filterValue: era.label,
      count: getCountByKey(eraCounts, era.label),
    })),
    {
      id: "unset-era",
      label: UNSET_LABEL,
      filterValue: unsetFilterValue,
      count: getCountByKey(eraCounts, unsetFilterValue),
    },
  ];

  return (
    <Box>
      <Typography variant="h6" sx={{ mb: 2 }}>
        時代を選んでください
      </Typography>
      <Grid container spacing={2}>
        {eraItems.map((era) => (
          <Grid item xs={12} sm={6} md={4} key={era.id}>
            <Card
              sx={{ cursor: "pointer" }}
              onClick={() => onSelectEra(era.filterValue)}
            >
              <CardActionArea sx={{ p: 2 }}>
                <Box
                  sx={{
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                    gap: 1,
                  }}
                >
                  <Typography variant="body1" fontWeight="bold">
                    {era.label}
                  </Typography>
                  <Chip
                    label={`${era.count}冊`}
                    size="small"
                    color="primary"
                    variant="outlined"
                  />
                </Box>
              </CardActionArea>
            </Card>
          </Grid>
        ))}
      </Grid>
    </Box>
  );
}

export function BrowseProgramList({
  programList,
  programCounts,
  unsetFilterValue,
  onSelectProgram,
}: {
  programList: ProgramMaster[];
  programCounts: Map<string, number>;
  unsetFilterValue: string;
  onSelectProgram: (program: string) => void;
}) {
  const programItems = [
    ...programList.map((program) => ({
      id: program.id,
      name: program.name,
      filterValue: program.name,
      count: getCountByKey(programCounts, program.name),
    })),
    ...Array.from(programCounts.entries())
      .filter(
        ([name]) =>
          name !== unsetFilterValue &&
          !programList.some((program) => program.name === name),
      )
      .map(([name]) => ({
        id: `program-extra-${name}`,
        name,
        filterValue: name,
        count: getCountByKey(programCounts, name),
      })),
    {
      id: "unset-program",
      name: UNSET_LABEL,
      filterValue: unsetFilterValue,
      count: getCountByKey(programCounts, unsetFilterValue),
    },
  ];

  return (
    <Box>
      <Typography variant="h6" sx={{ mb: 2 }}>
        番組名を選んでください
      </Typography>
      {programItems.length === 0 ? (
        <Typography color="text.secondary">番組が登録されていません</Typography>
      ) : (
        <Grid container spacing={2}>
          {programItems.map((program) => (
            <Grid item xs={12} sm={6} md={4} key={program.id}>
              <Card
                sx={{ cursor: "pointer" }}
                onClick={() => onSelectProgram(program.filterValue)}
              >
                <CardActionArea sx={{ p: 2 }}>
                  <Box
                    sx={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "center",
                      gap: 1,
                    }}
                  >
                    <Typography variant="body1" fontWeight="bold">
                      {program.name}
                    </Typography>
                    <Chip
                      label={`${program.count}冊`}
                      size="small"
                      color="primary"
                      variant="outlined"
                    />
                  </Box>
                </CardActionArea>
              </Card>
            </Grid>
          ))}
        </Grid>
      )}
    </Box>
  );
}

export function BrowseBookTitleList({
  documentList,
  browseBookGenre,
  onSelectGenre,
  onSelectBook,
  skipGenreStep = false,
}: {
  documentList: DocumentSummary[];
  browseBookGenre: string | null;
  onSelectGenre: (genre: string | null) => void;
  onSelectBook: (title: string) => void;
  skipGenreStep?: boolean;
}) {
  // ジャンルで絞り込んだ書籍リスト(skipGenreStep=true のときは全件表示)
  const filteredList =
    skipGenreStep || !browseBookGenre
      ? documentList
      : documentList.filter((doc) => doc.document_genre === browseBookGenre);

  // skipGenreStep=true: ジャンル選択ステップをスキップして全書籍を直接表示
  if (!skipGenreStep && !browseBookGenre) {
    return (
      <Box>
        <Typography variant="h6" sx={{ mb: 2 }}>
          ジャンルを選んでください
        </Typography>
        <DocumentGenreSelector
          value=""
          onChange={(genre) => onSelectGenre(genre)}
        />
      </Box>
    );
  }

  // Step2 / skipGenreStep=true: 書籍一覧画面
  const genreOption = browseBookGenre
    ? DOCUMENT_GENRE_OPTIONS.find((g) => g.value === browseBookGenre)
    : null;
  const heading = skipGenreStep
    ? "書籍タイトルの一覧"
    : `${browseBookGenre}の一覧`;
  return (
    <Box>
      <Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 2 }}>
        {!skipGenreStep && (
          <Button
            size="small"
            startIcon={<ArrowBackIcon />}
            onClick={() => onSelectGenre(null)}
            variant="outlined"
          >
            ジャンル選択に戻る
          </Button>
        )}
        {genreOption?.image && (
          <Box
            component="img"
            src={genreOption.image}
            alt={browseBookGenre ?? ""}
            sx={{
              width: 32,
              height: 32,
              objectFit: "cover",
              borderRadius: 0.5,
            }}
          />
        )}
        <Typography variant="h6">{heading}</Typography>
      </Box>
      {filteredList.length === 0 ? (
        <Typography color="text.secondary">
          該当する書籍が登録されていません
        </Typography>
      ) : (
        <Grid container spacing={2}>
          {filteredList.map((doc) => (
            <Grid item xs={12} sm={6} md={4} key={doc.document_id}>
              <Card
                sx={{ cursor: "pointer" }}
                onClick={() => onSelectBook(doc.title || "(タイトル未設定)")}
              >
                <CardActionArea sx={{ p: 2 }}>
                  <Typography variant="body1" fontWeight="bold">
                    {doc.title || "(タイトル未設定)"}
                  </Typography>
                  {doc.document_genre && (
                    <Chip
                      label={doc.document_genre}
                      size="small"
                      variant="outlined"
                      sx={{ mt: 0.5 }}
                    />
                  )}
                </CardActionArea>
              </Card>
            </Grid>
          ))}
        </Grid>
      )}
    </Box>
  );
}