"use client";

import React, { useEffect, useState, useRef, useCallback } from "react";
import { Container, Row, Col, Card, Form, FloatingLabel, Badge, Button, Stack, Spinner } from "react-bootstrap";
import { useForm, Controller } from "react-hook-form";
import { useToast } from "@/context/ToastContext";
import LoadingCMS from "@/components/LoadingCMS";
import HtmlEditor from "@/components/HtmlEditor";
import { excerptFromHtml } from "@/lib/function";
import { useRecaptcha } from "@/hooks/useRecaptcha";

type FormData = {
  sb_id: number;
  sb_sbt_id: number;
  sb_title: string;
  sb_content: string;
  sb_path: string;
  sb_photo?: FileList;
  sb_status: number;
  sm_title: string;
  sm_description: string;
};
type BlogData = FormData & {
  sb_photo?: string;
  sb_photo_width?: number;
  sb_photo_height?: number;
};
type TypeData = {
  sbt_id: number;
  sbt_title: string;
};
export default function Blogs() {
  const { showToast } = useToast();
  const { getToken } = useRecaptcha();

  const [blogs, setBlogs] = useState<BlogData[]>([]);
  const [blogType, setBlogType] = useState<TypeData[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [selectedBlog, setSelectedBlog] = useState<FormData | null>(null);
  const [search, setSearch] = useState("");
  const [selectedType, setSelectedType] = useState<number | "">("");
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const { register, handleSubmit, reset, control, formState: { errors, isSubmitting } } = useForm<FormData>({
    defaultValues: {
      sb_id: 0,
      sb_sbt_id: 0,
      sb_title: "",
      sb_content: "",
      sb_path: "",
      sb_status: 0,
      sm_title: "",
      sm_description: "",
    }
  });
  const fetchAllBlog = useCallback(async (sbtId?: number) => {
    try {
      const res = await fetch("/api/blog/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ sbtId })
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.data)) {
        setBlogs(json.data);
      }
    } catch {
      showToast("Blog List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);
  const fetchBlogType = useCallback(async () => {
    try {
      const res = await fetch("/api/blog/type");
      const json = await res.json();
      if (res.ok && Array.isArray(json.data)) {
        setBlogType(json.data);
      }
    } catch {
      showToast("Blog Type: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);
  useEffect(() => {
    fetchAllBlog();
    fetchBlogType();
  }, [fetchAllBlog, fetchBlogType]);
  useEffect(() => {
    if (selectedBlog) {
      reset({
        ...selectedBlog,
        sb_status: selectedBlog.sb_status ? 1 : 0
      });
    }
  }, [selectedBlog, reset]);
  const filteredBlogs = blogs.filter((blog) => {
    const matchesSearch =
      blog.sb_title?.toLowerCase().includes(search.toLowerCase()) ||
      blog.sb_path?.toLowerCase().includes(search.toLowerCase());

    const matchesType = selectedType === "" || blog.sb_sbt_id === selectedType;
    return matchesSearch && matchesType;
  });
  const onSubmit = async (data: FormData) => {
    try {
      const formData = new FormData();
      formData.append("sb_id", String(data.sb_id || 0));
      formData.append("sb_sbt_id", String(data.sb_sbt_id));
      formData.append("sb_title", data.sb_title);
      formData.append("sb_content", data.sb_content);
      formData.append("sb_path", data.sb_path);
      formData.append("sb_status", String(data.sb_status));
      formData.append("sm_title", data.sm_title);
      formData.append("sm_description", data.sm_description);
      if (data.sb_photo && data.sb_photo.length > 0 && data.sb_photo[0] instanceof File) {
        formData.append("sb_photo", data.sb_photo[0]);
      }
      const recaptchaToken = await getToken("blog_save_form");
      formData.append("recaptchaToken", recaptchaToken || '');

      const res = await fetch("/api/blog/save", {
        method: "POST",
        body: formData
      });
      const result = await res.json();
      if (res.ok) {
        showToast(result.message, "success");
        reset({
          sb_id: 0,
          sb_sbt_id: 0,
          sb_title: "",
          sb_content: "",
          sb_path: "",
          sb_status: 0,
          sm_title: "",
          sm_description: "",
        });
        if (fileInputRef.current) {
          fileInputRef.current.value = "";
        }
        setSelectedBlog(null);
        fetchAllBlog();
      } else {
        showToast(result.error, "danger");
      }
    } catch {
      showToast("Blog Save: Failed to save.", "danger");
    }
  };
  if (isLoading) return <LoadingCMS />;
  return (
    <Container fluid className="py-3">
      <Row>        
        <Col md={8}>
          <Row xs={1} md={2} className="g-3">
            <Col md={4} className="align-self-center">
              <h1 className="fs-3">Blogs <small className="text-body-secondary">({filteredBlogs.length})</small></h1>
            </Col>
            <Col md={4}>
              <FloatingLabel label="Search by title or path">
                <Form.Control value={search} onChange={(e) => setSearch(e.target.value)} />
              </FloatingLabel>
            </Col>
            <Col md={4}>
              <FloatingLabel label="Filter by Category">
                <Form.Select value={selectedType} onChange={(e) => setSelectedType(e.target.value === "" ? "" : Number(e.target.value))}>
                  <option value="">All Categories</option>
                  {blogType.map((type) => (
                    <option key={type.sbt_id} value={type.sbt_id}>
                      {type.sbt_title}
                    </option>
                  ))}
                </Form.Select>
              </FloatingLabel>
            </Col>
            {filteredBlogs.map((blog, index) => (
              <Col key={index}>
                <Card className={`h-100 rounded-4 overflow-hidden ${selectedBlog && selectedBlog.sb_id === blog.sb_id ? 'text-bg-success' : null}`}>
                  {blog.sb_photo && (
                    <Card.Img className="img-fluid" src={blog.sb_photo} width={blog.sb_photo_width} height={blog.sb_photo_height} alt={blog.sb_title} />
                  )}
                  <Card.Body>
                    <Card.Title className="d-flex align-items-start">
                      <span className="flex-fill me-3">{blog.sb_title}</span>
                      {blog.sb_status === 1 ? <Badge bg="primary">Active</Badge> : <Badge bg="secondary">Inactive</Badge>}
                    </Card.Title>
                    <Card.Subtitle className="mb-2 text-muted">{`/blog/${blog.sb_path}`}</Card.Subtitle>
                    <Card.Text>{excerptFromHtml(blog.sb_content, 50)}</Card.Text>
                  </Card.Body>
                  <Card.Footer>
                    <Button variant="outline-danger" className="w-100 rounded-pill" onClick={() => setSelectedBlog(blog)}>
                      Edit
                    </Button>
                  </Card.Footer>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
        <Col md={4} style={{ position: "sticky", top: "1rem", height: "100vh", overflowY: "auto" }}>
          <Card className="rounded-4">
            <Card.Body>
              <h4 className="mb-4">{selectedBlog ? "Edit Blog" : "Create New Blog"}</h4>
              <Form noValidate onSubmit={handleSubmit(onSubmit)}>
                <Row className="g-3">
                  <Col md={12}>
                    <FloatingLabel label="Category">
                      <Form.Select {...register("sb_sbt_id", { required: "Category is required", valueAsNumber: true, validate: (value) => value > 0 || "Please select a valid category" })} isInvalid={!!errors.sb_sbt_id} >
                        <option value="0">Please Select</option>
                        {blogType.map((type) => (
                          <option key={type.sbt_id} value={type.sbt_id}>
                            {type.sbt_title}
                          </option>
                        ))}
                      </Form.Select>
                      <Form.Control.Feedback type="invalid">{errors.sb_sbt_id?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Title">
                      <Form.Control type="text" {...register("sb_title", { required: "Title is required" })} isInvalid={!!errors.sb_title} />
                      <Form.Control.Feedback type="invalid">{errors.sb_title?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <Controller name="sb_content" control={control} 
                      rules={{
                        validate: (value) => {
                          const cleaned = (value || "").trim();
                          const div = document.createElement("div");
                          div.innerHTML = cleaned;
                          const text = div.textContent?.trim() || "";
                          if (!text) { return "Details is required"; }
                          return true;
                        },
                      }} 
                      render={({ field }) => (
                        <HtmlEditor value={field.value || ""} onChange={field.onChange} />
                      )}
                    />
                    {errors.sb_content && (<div className="invalid-feedback d-block">{errors.sb_content.message}</div>)}
                  </Col>
                  <Col md={12}>
                  {selectedBlog ? (
                    <FloatingLabel label="Upload Photo">
                      <Form.Control type="file" accept=".png,.jpg,.jpeg" {...register("sb_photo")} ref={(e) => { register("sb_photo").ref(e);fileInputRef.current = e; }} isInvalid={!!errors.sb_photo}/>
                      <Form.Control.Feedback type="invalid">{errors.sb_photo?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  ) : (
                    <FloatingLabel label="Upload Photo">
                      <Form.Control type="file" accept=".png,.jpg,.jpeg" {...register("sb_photo", { required: "Photo is required" })} ref={(e) => { register("sb_photo").ref(e);fileInputRef.current = e; }} isInvalid={!!errors.sb_photo}/>
                      <Form.Control.Feedback type="invalid">{errors.sb_photo?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  )}                    
                  </Col>
                  <Col md={12}>
                    <Controller name="sb_status" control={control} defaultValue={0} render={({ field }) => (
                      <Form.Check type="switch" id="sb_status" label="Blog Status" checked={field.value === 1} onChange={(e) => field.onChange(e.target.checked ? 1 : 0)} />
                      )}
                    />
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Meta Title">
                      <Form.Control {...register("sm_title", { required: "Title is required" })} isInvalid={!!errors.sm_title} />
                      <Form.Control.Feedback type="invalid">{errors.sm_title?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Meta Description">
                      <Form.Control as="textarea" rows={3} {...register("sm_description", { required: "Description is required" })} isInvalid={!!errors.sm_description} />
                      <Form.Control.Feedback type="invalid">{errors.sm_description?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <Stack direction="horizontal" gap={3}>
                      <Button type="submit" variant="danger" className="w-100 rounded-pill" disabled={isSubmitting}>
                        {isSubmitting ? (
                          <Stack gap={2} direction="horizontal">
                            <Spinner animation="grow" size="sm" variant="danger" />
                            <Spinner animation="grow" size="sm" variant="primary" />
                            <Spinner animation="grow" size="sm" variant="success" />
                            <span>{selectedBlog ? "Updating..." : "Creating..."}</span>
                          </Stack>
                        ) : selectedBlog ? "Update Blog" : "Create Blog"}
                      </Button>
                      {selectedBlog && (
                        <Button variant="outline-secondary" className="w-100 rounded-pill" onClick={() => { reset({sb_id: 0,sb_sbt_id: 0,sb_title: "",sb_content: "",sb_path: "",sb_status: 0,sm_title: "",sm_description: "",}); setSelectedBlog(null); }} >
                          Cancel Edit
                        </Button>
                      )}
                    </Stack>
                  </Col>
                </Row>
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}
