"use client";

import React, { useEffect, useState, useCallback } from "react";
import { Container, Row, Col, Card, Form, FloatingLabel, Badge, Button, Stack, Spinner, ListGroup } from "react-bootstrap";
import { useForm, Controller } from "react-hook-form";
import { useToast } from "@/context/ToastContext";
import { unixToDateTime,excerptFromHtml } from "@/lib/function";
import LoadingCMS from "@/components/LoadingCMS";
import HtmlEditor from "@/components/HtmlEditor";
import { useRecaptcha } from "@/hooks/useRecaptcha";

type SubscriberData = {
  ss_id: number;
  ss_name: string;
  ss_email: string;
  ss_status: number;
  ss_date: number;
  mail_queued: number;
  mail_pending: number;
  mail_sent: number;
  mail_failed: number;
};

type MailData = {
  smq_id: number;
  smq_subject: string;
  smq_content: string;
  smq_status: number;
  smq_date: number;
  smq_sent_date: number;
  mail_queued: number;
  mail_pending: number;
  mail_sent: number;
  mail_failed: number;
};

type MailFormData = {
  subject: string;
  content: string;
  recipients: number[];
};

export default function Subscribers() {
  const { showToast } = useToast();
  const { getToken } = useRecaptcha();

  const [subscribers, setSubscribers] = useState<SubscriberData[]>([]);
  const [mails, setMails] = useState<MailData[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [searchSubscriber, setSubscriberSearch] = useState("");
  const [searchMail, setMailSearch] = useState("");
  const mailStatus = [
    <Badge key="pending" bg="primary">Pending</Badge>,
    <Badge key="sending" bg="warning">Sending</Badge>,
    <Badge key="completed" bg="success">Completed</Badge>,
    <Badge key="failed" bg="danger">Failed</Badge>,
  ];

  const { register, handleSubmit, watch, setValue,control, formState: { errors, isSubmitting } } = useForm<MailFormData>({    
    defaultValues: {
      subject: "",
      content: "",
      recipients: []
    }
  });

  const fetchSubscribers = useCallback(async () => {
    try {
      const res = await fetch("/api/subscribe/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.subscribersData)) {
        setSubscribers(json.subscribersData);
        const activeIds = json.subscribersData.filter((s: SubscriberData) => s.ss_status === 1).map((s: SubscriberData) => s.ss_id);
        setValue("recipients", activeIds);
      }
    } catch {
      showToast("Subscriber List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast,setValue]);

  const fetchMails = useCallback(async () => {
    try {
      const res = await fetch("/api/subscribe/mail/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.mailsData)) {
        setMails(json.mailsData);
      }
    } catch {
      showToast("Subscriber List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);

  useEffect(() => {
    fetchSubscribers();
    fetchMails();
  }, [fetchSubscribers,fetchMails]);

  const filteredSubscribers = subscribers.filter((subscriber) => {
    const matchesSearch =
      subscriber.ss_name?.toLowerCase().includes(searchSubscriber.toLowerCase()) ||
      subscriber.ss_email?.toLowerCase().includes(searchSubscriber.toLowerCase());
    return matchesSearch;
  });

  const filteredMails = mails.filter((mail) => {
    const matchesSearch =
      mail.smq_subject?.toLowerCase().includes(searchMail.toLowerCase());
    return matchesSearch;
  });

  const onSubmit = async (data: MailFormData) => {
    try {
      const recaptchaToken = await getToken("mail_save_form");
      const res = await fetch("/api/subscribe/mail/save", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({...data, recaptchaToken}),
      });
      const result = await res.json();
      if (res.ok) {
        showToast(result.message, "success");
      }
    } catch {
      showToast("Mail Seeding Failed..", "danger");
    }
  };

  if (isLoading) return <LoadingCMS />;

  return (
    <Container fluid className="py-3">
      <Row>        
        <Col md={4}>
          <Row xs={1} md={1} className="g-3">
            <Col>
              <h1 className="fs-3">Subscribers <small className="text-body-secondary">({filteredSubscribers.length})</small></h1>
            </Col>
            <Col>
              <FloatingLabel label="Search by name or email">
                <Form.Control value={searchSubscriber} onChange={(e) => setSubscriberSearch(e.target.value)} />
              </FloatingLabel>
            </Col>
            {filteredSubscribers.map((subscriber, index) => (
              <Col key={index}>
                <Card className="h-100 rounded-4 overflow-hidden">
                  <Card.Body>
                    <Card.Title className="d-flex align-items-start">
                      <span className="flex-fill me-3">{subscriber.ss_name}</span>
                      {subscriber.ss_status === 1 ? <Badge bg="primary">Active</Badge> : <Badge bg="secondary">Inactive</Badge>}
                    </Card.Title>
                  </Card.Body>
                  <ListGroup variant="flush">
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Email <span className="ms-3">{subscriber.ss_email}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Subscribe Date <span className="ms-3">{unixToDateTime(subscriber.ss_date,'date')}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      <Badge pill bg="secondary">Mail Queued ({subscriber.mail_queued})</Badge>
                      <Badge pill bg="info">Pending ({subscriber.mail_pending})</Badge>
                      <Badge pill bg="success">Sent ({subscriber.mail_sent})</Badge>
                      <Badge pill bg="danger">Failed ({subscriber.mail_failed})</Badge>
                    </ListGroup.Item>
                  </ListGroup>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
        <Col md={4} className="position-sticky vh-100 overflow-y-auto" style={{ top: "1rem" }}>
          <Card className="rounded-4 bg-light">
            <Card.Body>
              <h2 className="fs-3 mb-4">Create New Mail</h2>
              <Form noValidate onSubmit={handleSubmit(onSubmit)}>
                <Row className="g-3">
                  <Col md={12}>
                    <FloatingLabel label="Mail Subject">
                      <Form.Control type="text"
                        {...register("subject", {
                          required: "Subject is required",
                          minLength: {value: 3,message: "Subject must be at least 3 characters"},
                          maxLength: {value: 150,message: "Subject cannot exceed 150 characters"},
                          validate: (value) => {
                            const cleaned = value.trim();
                            if (!cleaned) {return "Subject is required";}
                            if (!/[A-Za-z0-9]/.test(cleaned)) {return "Subject must contain letters or numbers";}
                            return true;
                          },
                        })} isInvalid={!!errors.subject} />
                      <Form.Control.Feedback type="invalid">
                        {errors.subject?.message}
                      </Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <Controller name="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 "Content is required"; }
                          return true;
                        },
                      }} 
                      render={({ field }) => (
                        <HtmlEditor value={field.value || ""} onChange={field.onChange} />
                      )}
                    />
                    {errors.content && (<div className="invalid-feedback d-block">{errors.content.message}</div>)}                
                  </Col>
                  <Col md={12}>
                    <h6>Active Subscribers ({watch("recipients").length})</h6>
                    <ListGroup style={{ height: "200px", overflowY: "auto" }}>
                      {subscribers
                        .filter((s) => s.ss_status === 1)
                        .map((s) => (
                          <ListGroup.Item key={s.ss_id} className="p-1">
                            <Form.Check
                              type="checkbox"
                              label={`${s.ss_name} (${s.ss_email})`}
                              checked={watch("recipients").includes(s.ss_id)}
                              onChange={(e) => {
                                const current = watch("recipients");
                                if (e.target.checked) {
                                  setValue("recipients", [...current, s.ss_id]);
                                } else {
                                  setValue("recipients", current.filter((id) => id !== s.ss_id));
                                }
                              }}
                            />
                          </ListGroup.Item>
                        ))}
                    </ListGroup>
                  </Col>
                  <Col md={12}>
                    <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>Seeding...</span>
                        </Stack>
                      ) : "Submit"}
                    </Button>
                  </Col>
                </Row>
              </Form>
            </Card.Body>
          </Card>
        </Col>
        <Col md={4}>
          <Row xs={1} md={1} className="g-3">
            <Col>
              <h3 className="fs-3">Queued Mails <small className="text-body-secondary">({filteredMails.length})</small></h3>
            </Col>
            <Col>
              <FloatingLabel label="Search by subject">
                <Form.Control value={searchMail} onChange={(e) => setMailSearch(e.target.value)} />
              </FloatingLabel>
            </Col>
            {filteredMails.map((mail, index) => (
              <Col key={index}>
                <Card className="h-100 rounded-4 overflow-hidden">
                  <Card.Body>
                    <Card.Title>{mail.smq_subject}</Card.Title>
                    <Card.Text>{excerptFromHtml(mail.smq_content,30)}</Card.Text>
                  </Card.Body>
                  <ListGroup variant="flush">
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Status {mailStatus[mail.smq_status]}
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Created <span className="ms-3">{unixToDateTime(mail.smq_date)}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Processed <span className="ms-3">{unixToDateTime(mail.smq_sent_date)}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      <Badge pill bg="secondary">Subscribers ({mail.mail_queued})</Badge>
                      <Badge pill bg="info">Pending ({mail.mail_pending})</Badge>
                      <Badge pill bg="success">Sent ({mail.mail_sent})</Badge>
                      <Badge pill bg="danger">Failed ({mail.mail_failed})</Badge>
                    </ListGroup.Item>
                  </ListGroup>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
      </Row>
    </Container>
  );
}
