"use client";

import { useEffect, useState, useCallback } from "react";
import { useActiveClass } from "@/hooks/use-active-class";
import { useAuth } from "@/hooks/use-auth";
import { fetchAPI, postAPI, putAPI, deleteAPI, getErrorMessage } from "@/lib/api";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { ErrorState } from "@/components/error-state";
import { Pagination } from "@/components/pagination";
import { toast } from "sonner";
import type { Vote, PageResponse } from "@/lib/types";
import { hasClassPermission } from "@/lib/permissions";

export default function VotesPage() {
  const { activeClassId } = useActiveClass();
  const { user } = useAuth();

  // List state
  const [votes, setVotes] = useState<Vote[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);

  // Create dialog state
  const [createOpen, setCreateOpen] = useState(false);
  const [formTitle, setFormTitle] = useState("");
  const [formDesc, setFormDesc] = useState("");
  const [formVoteType, setFormVoteType] = useState<"single" | "multiple">("single");
  const [formAnonymous, setFormAnonymous] = useState(false);
  const [formMaxChoices, setFormMaxChoices] = useState(2);
  const [formDeadline, setFormDeadline] = useState("");
  const [formOptions, setFormOptions] = useState<string[]>(["", ""]);
  const [submitting, setSubmitting] = useState(false);

  // Detail dialog state
  const [detailOpen, setDetailOpen] = useState(false);
  const [detailVote, setDetailVote] = useState<Vote | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [selectedOptions, setSelectedOptions] = useState<number[]>([]);
  const [submittingVote, setSubmittingVote] = useState(false);

  // Delete confirm state
  const [deleteTarget, setDeleteTarget] = useState<number | null>(null);

  const loadVotes = useCallback(async () => {
    if (!activeClassId) return;
    setError(null);
    setLoading(true);
    try {
      const res = await fetchAPI<PageResponse<Vote>>("/api/votes/", {
        class_id: String(activeClassId),
        page: String(page),
        page_size: "10",
      });
      setVotes(res.items || []);
      setTotalPages(res.total_pages || 1);
    } catch (err: unknown) {
      setError(getErrorMessage(err, "加载失败"));
    } finally {
      setLoading(false);
    }
  }, [activeClassId, page]);

  useEffect(() => {
    loadVotes();
  }, [loadVotes]);

  // Reset page when class changes
  useEffect(() => {
    setPage(1);
  }, [activeClassId]);

  // ---------- Create ----------

  const resetCreateForm = () => {
    setFormTitle("");
    setFormDesc("");
    setFormVoteType("single");
    setFormAnonymous(false);
    setFormMaxChoices(2);
    setFormDeadline("");
    setFormOptions(["", ""]);
  };

  const handleCreate = async () => {
    if (!formTitle.trim()) {
      toast.error("请输入投票标题");
      return;
    }
    const validOptions = formOptions.filter((o) => o.trim());
    if (validOptions.length < 2) {
      toast.error("至少需要两个选项");
      return;
    }
    if (formVoteType === "multiple" && formMaxChoices < 2) {
      toast.error("多选投票至少允许选择2项");
      return;
    }
    if (formVoteType === "multiple" && formMaxChoices > validOptions.length) {
      toast.error("最多可选择数不能超过选项总数");
      return;
    }
    setSubmitting(true);
    try {
      await postAPI(`/api/votes/?class_id=${activeClassId}`, {
        title: formTitle.trim(),
        description: formDesc.trim() || null,
        vote_type: formVoteType,
        is_anonymous: formAnonymous,
        max_choices: formVoteType === "multiple" ? formMaxChoices : 1,
        deadline: formDeadline || null,
        options: validOptions,
      });
      toast.success("投票已创建");
      setCreateOpen(false);
      resetCreateForm();
      loadVotes();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "创建失败"));
    } finally {
      setSubmitting(false);
    }
  };

  const addOption = () => setFormOptions([...formOptions, ""]);

  const removeOption = (index: number) => {
    if (formOptions.length <= 2) return;
    setFormOptions(formOptions.filter((_, i) => i !== index));
  };

  const updateOption = (index: number, value: string) => {
    const updated = [...formOptions];
    updated[index] = value;
    setFormOptions(updated);
  };

  // ---------- Detail ----------

  const openDetail = async (voteId: number) => {
    setDetailOpen(true);
    setDetailLoading(true);
    setSelectedOptions([]);
    try {
      const data = await fetchAPI<Vote>(`/api/votes/${voteId}`);
      setDetailVote(data);
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "加载投票详情失败"));
      setDetailOpen(false);
    } finally {
      setDetailLoading(false);
    }
  };

  const handleSubmitVote = async () => {
    if (!detailVote) return;
    if (selectedOptions.length === 0) {
      toast.error("请至少选择一个选项");
      return;
    }
    if (detailVote.vote_type === "multiple" && selectedOptions.length > detailVote.max_choices) {
      toast.error(`最多只能选择${detailVote.max_choices}项`);
      return;
    }
    setSubmittingVote(true);
    try {
      await postAPI(`/api/votes/${detailVote.id}/submit`, {
        option_ids: selectedOptions,
      });
      toast.success("投票成功");
      // Refresh detail
      const data = await fetchAPI<Vote>(`/api/votes/${detailVote.id}`);
      setDetailVote(data);
      setSelectedOptions([]);
      loadVotes();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "投票失败"));
    } finally {
      setSubmittingVote(false);
    }
  };

  const handleCloseVote = async (voteId: number) => {
    try {
      await putAPI(`/api/votes/${voteId}/close`);
      toast.success("投票已关闭");
      setDetailOpen(false);
      loadVotes();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "关闭失败"));
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await deleteAPI(`/api/votes/${id}`);
      toast.success("已删除");
      setDeleteTarget(null);
      setDetailOpen(false);
      loadVotes();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "删除失败"));
    }
  };

  const canManage = (vote: Vote) =>
    user &&
    (
      hasClassPermission(user, "vote_manage", vote.class_id) ||
      user.id === vote.creator_id
    );

  // ---------- Render helpers ----------

  const renderStatusBadge = (status: Vote["status"]) => {
    if (status === "open") {
      return <Badge className="bg-green-500 text-white text-xs">进行中</Badge>;
    }
    return <Badge variant="secondary" className="text-xs">已结束</Badge>;
  };

  const formatDeadline = (deadline: string | null) => {
    if (!deadline) return "无截止时间";
    return new Date(deadline).toLocaleString("zh-CN", {
      year: "numeric",
      month: "2-digit",
      day: "2-digit",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  const getPercentage = (count: number, total: number) => {
    if (total === 0) return 0;
    return Math.round((count / total) * 100);
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">投票</h1>
          <p className="text-gray-500 mt-1">班级投票与调查</p>
        </div>
        <Dialog open={createOpen} onOpenChange={(open) => {
          setCreateOpen(open);
          if (!open) resetCreateForm();
        }}>
          <DialogTrigger>
            <Button>创建投票</Button>
          </DialogTrigger>
          <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-lg">
            <DialogHeader>
              <DialogTitle>创建投票</DialogTitle>
            </DialogHeader>
            <div className="space-y-4 pt-2">
              {/* Title */}
              <div>
                <Label className="mb-1.5 block text-sm font-medium">标题 *</Label>
                <Input
                  placeholder="投票标题"
                  value={formTitle}
                  onChange={(e) => setFormTitle(e.target.value)}
                />
              </div>

              {/* Description */}
              <div>
                <Label className="mb-1.5 block text-sm font-medium">描述</Label>
                <Textarea
                  placeholder="投票描述（可选）"
                  value={formDesc}
                  onChange={(e) => setFormDesc(e.target.value)}
                  rows={3}
                />
              </div>

              {/* Vote type */}
              <div>
                <Label className="mb-1.5 block text-sm font-medium">投票类型</Label>
                <div className="flex gap-2">
                  <Button
                    type="button"
                    variant={formVoteType === "single" ? "default" : "outline"}
                    size="sm"
                    onClick={() => setFormVoteType("single")}
                  >
                    单选
                  </Button>
                  <Button
                    type="button"
                    variant={formVoteType === "multiple" ? "default" : "outline"}
                    size="sm"
                    onClick={() => setFormVoteType("multiple")}
                  >
                    多选
                  </Button>
                </div>
              </div>

              {/* Max choices (multiple only) */}
              {formVoteType === "multiple" && (
                <div>
                  <Label className="mb-1.5 block text-sm font-medium">最多可选择</Label>
                  <Input
                    type="number"
                    min={2}
                    max={formOptions.filter((o) => o.trim()).length || 2}
                    value={formMaxChoices}
                    onChange={(e) => setFormMaxChoices(parseInt(e.target.value) || 2)}
                    className="w-24"
                  />
                </div>
              )}

              {/* Anonymous */}
              <div className="flex items-center gap-3">
                <Switch
                  id="anonymous"
                  checked={formAnonymous}
                  onCheckedChange={setFormAnonymous}
                />
                <Label htmlFor="anonymous" className="cursor-pointer">匿名投票</Label>
              </div>

              {/* Deadline */}
              <div>
                <Label className="mb-1.5 block text-sm font-medium">截止时间</Label>
                <Input
                  type="datetime-local"
                  value={formDeadline}
                  onChange={(e) => setFormDeadline(e.target.value)}
                />
              </div>

              {/* Options */}
              <div>
                <Label className="mb-1.5 block text-sm font-medium">选项 *</Label>
                <div className="space-y-2">
                  {formOptions.map((opt, i) => (
                    <div key={i} className="flex gap-2">
                      <Input
                        placeholder={`选项 ${i + 1}`}
                        value={opt}
                        onChange={(e) => updateOption(i, e.target.value)}
                      />
                      {formOptions.length > 2 && (
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          className="text-red-500 shrink-0"
                          onClick={() => removeOption(i)}
                        >
                          删除
                        </Button>
                      )}
                    </div>
                  ))}
                </div>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="mt-2"
                  onClick={addOption}
                >
                  + 添加选项
                </Button>
              </div>

              {/* Submit */}
              <Button onClick={handleCreate} disabled={submitting} className="w-full">
                {submitting ? "创建中..." : "创建投票"}
              </Button>
            </div>
          </DialogContent>
        </Dialog>
      </div>

      {/* Loading */}
      {loading ? (
        <div className="space-y-4">
          {[1, 2, 3].map((i) => (
            <Card key={i} className="animate-pulse">
              <CardContent className="p-6">
                <div className="h-24 bg-gray-200 rounded" />
              </CardContent>
            </Card>
          ))}
        </div>
      ) : error ? (
        <ErrorState message={error} onRetry={loadVotes} />
      ) : votes.length === 0 ? (
        <div className="text-center py-12 text-gray-400">暂无投票</div>
      ) : (
        <div className="space-y-4">
          {votes.map((vote) => (
            <Card
              key={vote.id}
              className="cursor-pointer hover:shadow-md transition-shadow"
              onClick={() => openDetail(vote.id)}
            >
              <CardContent className="p-6">
                <div className="flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 flex-wrap">
                      {renderStatusBadge(vote.status)}
                      {vote.is_anonymous && (
                        <Badge variant="outline" className="text-xs">匿名</Badge>
                      )}
                      <Badge variant="outline" className="text-xs">
                        {vote.vote_type === "single" ? "单选" : "多选"}
                      </Badge>
                      <h3 className="text-lg font-semibold truncate">{vote.title}</h3>
                    </div>
                    {vote.description && (
                      <p className="mt-2 text-gray-600 text-sm line-clamp-2">{vote.description}</p>
                    )}
                    <div className="mt-3 flex items-center gap-4 text-sm text-gray-400 flex-wrap">
                      <span>{vote.creator_name}</span>
                      <span>{formatDeadline(vote.deadline)}</span>
                      <span>{vote.total_voters} 人参与</span>
                    </div>
                  </div>
                  <div className="shrink-0">
                    {vote.has_voted ? (
                      <Badge className="bg-gray-100 text-gray-500 text-xs">已投票</Badge>
                    ) : vote.status === "open" ? (
                      <Badge className="bg-blue-500 text-white text-xs">投票</Badge>
                    ) : null}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      <Pagination page={page} totalPages={totalPages} onPageChange={setPage} />

      {/* Detail dialog */}
      <Dialog open={detailOpen} onOpenChange={setDetailOpen}>
        <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>投票详情</DialogTitle>
          </DialogHeader>
          {detailLoading ? (
            <div className="py-8 text-center text-gray-400">加载中...</div>
          ) : detailVote ? (
            <div className="space-y-5 pt-2">
              {/* Header info */}
              <div>
                <div className="flex items-center gap-2 flex-wrap mb-2">
                  {renderStatusBadge(detailVote.status)}
                  {detailVote.is_anonymous && (
                    <Badge variant="outline" className="text-xs">匿名</Badge>
                  )}
                  <Badge variant="outline" className="text-xs">
                    {detailVote.vote_type === "single" ? "单选" : `多选（最多${detailVote.max_choices}项）`}
                  </Badge>
                </div>
                <h3 className="text-lg font-semibold">{detailVote.title}</h3>
                {detailVote.description && (
                  <p className="mt-1 text-gray-600 text-sm">{detailVote.description}</p>
                )}
                <div className="mt-2 flex items-center gap-4 text-sm text-gray-400 flex-wrap">
                  <span>发起人: {detailVote.creator_name}</span>
                  <span>截止: {formatDeadline(detailVote.deadline)}</span>
                  <span>{detailVote.total_voters} 人参与</span>
                </div>
              </div>

              {/* Options: vote or results */}
              {detailVote.status === "open" && !detailVote.has_voted ? (
                /* Voting form */
                <div className="space-y-3">
                  <p className="text-sm font-medium">
                    {detailVote.vote_type === "single" ? "请选择一个选项：" : `请选择选项（最多${detailVote.max_choices}项）：`}
                  </p>
                  {detailVote.options.map((option) => (
                    <label
                      key={option.id}
                      className={`flex items-center gap-3 p-3 rounded-lg border cursor-pointer transition-colors ${
                        selectedOptions.includes(option.id)
                          ? "border-blue-500 bg-blue-50"
                          : "border-gray-200 hover:border-gray-300"
                      }`}
                    >
                      <input
                        type={detailVote.vote_type === "single" ? "radio" : "checkbox"}
                        name="vote-option"
                        className="shrink-0"
                        checked={selectedOptions.includes(option.id)}
                        onChange={() => {
                          if (detailVote.vote_type === "single") {
                            setSelectedOptions([option.id]);
                          } else {
                            setSelectedOptions((prev) =>
                              prev.includes(option.id)
                                ? prev.filter((id) => id !== option.id)
                                : prev.length < detailVote.max_choices
                                  ? [...prev, option.id]
                                  : (toast.error(`最多只能选择${detailVote.max_choices}项`), prev)
                            );
                          }
                        }}
                      />
                      <span className="text-sm">{option.content}</span>
                    </label>
                  ))}
                  <Button
                    onClick={handleSubmitVote}
                    disabled={submittingVote || selectedOptions.length === 0}
                    className="w-full"
                  >
                    {submittingVote ? "提交中..." : "提交投票"}
                  </Button>
                </div>
              ) : (
                /* Results */
                <div className="space-y-3">
                  {detailVote.options.map((option) => {
                    const pct = getPercentage(option.vote_count, detailVote.total_voters);
                    const isMyChoice = detailVote.my_option_ids?.includes(option.id);
                    return (
                      <div key={option.id}>
                        <div className="flex items-center justify-between mb-1">
                          <span className={`text-sm ${isMyChoice ? "font-semibold text-blue-600" : ""}`}>
                            {option.content}
                            {isMyChoice && <span className="ml-1 text-xs text-blue-500">(我的选择)</span>}
                          </span>
                          <span className="text-sm text-gray-500">
                            {option.vote_count} 票 ({pct}%)
                          </span>
                        </div>
                        <div className="w-full bg-gray-100 rounded-full h-2.5">
                          <div
                            className={`h-2.5 rounded-full transition-all ${
                              isMyChoice ? "bg-blue-500" : "bg-gray-400"
                            }`}
                            style={{ width: `${pct}%` }}
                          />
                        </div>
                        {/* Voter names */}
                        {!detailVote.is_anonymous &&
                          option.voter_names &&
                          option.voter_names.length > 0 && (
                            <p className="text-xs text-gray-400 mt-1">
                              {option.voter_names.join("、")}
                            </p>
                          )}
                      </div>
                    );
                  })}
                </div>
              )}

              {/* Actions for creator/admin */}
              {canManage(detailVote) && (
                <div className="flex gap-2 pt-2 border-t">
                  {detailVote.status === "open" && (
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => handleCloseVote(detailVote.id)}
                    >
                      关闭投票
                    </Button>
                  )}
                  <Button
                    variant="ghost"
                    size="sm"
                    className="text-red-500"
                    onClick={() => setDeleteTarget(detailVote.id)}
                  >
                    删除
                  </Button>
                </div>
              )}
            </div>
          ) : null}
        </DialogContent>
      </Dialog>

      {/* Delete confirm */}
      <Dialog open={deleteTarget !== null} onOpenChange={(open) => { if (!open) setDeleteTarget(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>删除投票</DialogTitle>
          </DialogHeader>
          <p className="text-gray-500 text-sm">确定删除此投票？此操作不可恢复。</p>
          <div className="flex justify-end gap-2 pt-2">
            <Button variant="outline" size="sm" onClick={() => setDeleteTarget(null)}>
              取消
            </Button>
            <Button
              variant="destructive"
              size="sm"
              onClick={() => deleteTarget && handleDelete(deleteTarget)}
            >
              删除
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
