-- =============================================================================
-- IT Service Request Module
-- =============================================================================

-- 1. Main table
CREATE TABLE IF NOT EXISTS it_service_requests (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  request_number text UNIQUE,

  -- Services (checkboxes from the form)
  services text[] NOT NULL DEFAULT '{}',
  services_other text,

  -- Event/Activity Details (Quill Delta JSON)
  event_name text NOT NULL,
  event_details text, -- Quill delta JSON
  
  -- Scheduling
  event_date timestamptz,
  event_end_date timestamptz,
  dry_run_date timestamptz,
  dry_run_end_date timestamptz,

  -- Contact
  contact_person text,
  contact_number text,

  -- Remarks (Quill Delta JSON)
  remarks text,

  -- Office (Department in the form)
  office_id uuid REFERENCES offices(id) ON DELETE SET NULL,

  -- Signatories
  requested_by text, -- Name of requester (default: standard user who created)
  requested_by_user_id uuid REFERENCES auth.users(id) ON DELETE SET NULL,
  approved_by text, -- Name of approver (admin only)
  approved_by_user_id uuid REFERENCES auth.users(id) ON DELETE SET NULL,
  approved_at timestamptz,

  -- Status lifecycle: draft → pending_approval → scheduled → in_progress_dry_run → in_progress → completed → cancelled
  status text NOT NULL DEFAULT 'draft' CHECK (
    status IN ('draft', 'pending_approval', 'scheduled', 'in_progress_dry_run', 'in_progress', 'completed', 'cancelled')
  ),

  -- Geofence override: allow IT staff to check in/out outside CRMC premise
  outside_premise_allowed boolean NOT NULL DEFAULT false,

  -- Cancellation
  cancellation_reason text,
  cancelled_at timestamptz,

  -- Metadata
  creator_id uuid REFERENCES auth.users(id) ON DELETE SET NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updated_at timestamptz NOT NULL DEFAULT now(),
  completed_at timestamptz,

  -- Date/Time Received/Checked from the form
  date_time_received timestamptz,
  date_time_checked timestamptz
);

-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_it_service_requests_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER it_service_requests_updated_at_trigger
  BEFORE UPDATE ON it_service_requests
  FOR EACH ROW
  EXECUTE FUNCTION update_it_service_requests_updated_at();

-- 2. IT Service Request Assignments (IT Staff assigned to the request)
CREATE TABLE IF NOT EXISTS it_service_request_assignments (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  request_id uuid NOT NULL REFERENCES it_service_requests(id) ON DELETE CASCADE,
  user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  created_at timestamptz NOT NULL DEFAULT now(),
  UNIQUE(request_id, user_id)
);

-- 3. Activity Logs for audit trail
CREATE TABLE IF NOT EXISTS it_service_request_activity_logs (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  request_id uuid NOT NULL REFERENCES it_service_requests(id) ON DELETE CASCADE,
  actor_id uuid REFERENCES auth.users(id) ON DELETE SET NULL,
  action_type text NOT NULL,
  meta jsonb,
  created_at timestamptz NOT NULL DEFAULT now()
);

-- 4. Action Taken (separate table with evidence attachments)
CREATE TABLE IF NOT EXISTS it_service_request_actions (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  request_id uuid NOT NULL REFERENCES it_service_requests(id) ON DELETE CASCADE,
  user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  action_taken text, -- Quill Delta JSON
  created_at timestamptz NOT NULL DEFAULT now(),
  updated_at timestamptz NOT NULL DEFAULT now()
);

-- Auto-update updated_at for actions
CREATE TRIGGER it_service_request_actions_updated_at_trigger
  BEFORE UPDATE ON it_service_request_actions
  FOR EACH ROW
  EXECUTE FUNCTION update_it_service_requests_updated_at();

-- 5. Evidence Attachments (images only, for action taken)
CREATE TABLE IF NOT EXISTS it_service_request_evidence (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  request_id uuid NOT NULL REFERENCES it_service_requests(id) ON DELETE CASCADE,
  action_id uuid REFERENCES it_service_request_actions(id) ON DELETE CASCADE,
  user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  file_path text NOT NULL,
  file_name text NOT NULL,
  taken_at timestamptz, -- Extracted from image EXIF metadata
  created_at timestamptz NOT NULL DEFAULT now()
);

-- 6. Request Number Generation RPC
CREATE OR REPLACE FUNCTION insert_it_service_request_with_number(
  p_event_name text,
  p_services text[],
  p_creator_id uuid,
  p_office_id uuid DEFAULT NULL,
  p_requested_by text DEFAULT NULL,
  p_requested_by_user_id uuid DEFAULT NULL,
  p_status text DEFAULT 'draft'
)
RETURNS TABLE(id uuid, request_number text) AS $$
DECLARE
  v_seq int;
  v_id uuid;
  v_number text;
BEGIN
  -- Get next sequence number for the current year
  SELECT COALESCE(MAX(
    CAST(NULLIF(regexp_replace(r.request_number, '^ISR-\d{4}-', ''), '') AS int)
  ), 0) + 1
  INTO v_seq
  FROM it_service_requests r
  WHERE r.request_number LIKE 'ISR-' || EXTRACT(YEAR FROM now())::text || '-%';

  v_number := 'ISR-' || EXTRACT(YEAR FROM now())::text || '-' || LPAD(v_seq::text, 4, '0');
  v_id := gen_random_uuid();

  INSERT INTO it_service_requests (id, request_number, event_name, services, creator_id, office_id, requested_by, requested_by_user_id, status)
  VALUES (v_id, v_number, p_event_name, p_services, p_creator_id, p_office_id, p_requested_by, p_requested_by_user_id, p_status);

  RETURN QUERY SELECT v_id, v_number;
END;
$$ LANGUAGE plpgsql;

-- 7. Indexes
CREATE INDEX idx_it_service_requests_status ON it_service_requests(status);
CREATE INDEX idx_it_service_requests_office_id ON it_service_requests(office_id);
CREATE INDEX idx_it_service_requests_creator_id ON it_service_requests(creator_id);
CREATE INDEX idx_it_service_requests_event_date ON it_service_requests(event_date);
CREATE INDEX idx_it_service_request_assignments_request_id ON it_service_request_assignments(request_id);
CREATE INDEX idx_it_service_request_assignments_user_id ON it_service_request_assignments(user_id);
CREATE INDEX idx_it_service_request_activity_logs_request_id ON it_service_request_activity_logs(request_id);
CREATE INDEX idx_it_service_request_actions_request_id ON it_service_request_actions(request_id);
CREATE INDEX idx_it_service_request_evidence_request_id ON it_service_request_evidence(request_id);

-- 8. Enable RLS
ALTER TABLE it_service_requests ENABLE ROW LEVEL SECURITY;
ALTER TABLE it_service_request_assignments ENABLE ROW LEVEL SECURITY;
ALTER TABLE it_service_request_activity_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE it_service_request_actions ENABLE ROW LEVEL SECURITY;
ALTER TABLE it_service_request_evidence ENABLE ROW LEVEL SECURITY;

-- 9. RLS Policies

-- IT Service Requests: authenticated can read all, insert own, update depending on role
CREATE POLICY "Authenticated users can read it_service_requests"
  ON it_service_requests FOR SELECT TO authenticated USING (true);

CREATE POLICY "Authenticated users can insert it_service_requests"
  ON it_service_requests FOR INSERT TO authenticated
  WITH CHECK (auth.uid() = creator_id);

CREATE POLICY "Authenticated users can update it_service_requests"
  ON it_service_requests FOR UPDATE TO authenticated
  USING (true);

-- Assignments
CREATE POLICY "Authenticated users can read it_service_request_assignments"
  ON it_service_request_assignments FOR SELECT TO authenticated USING (true);

CREATE POLICY "Authenticated users can insert it_service_request_assignments"
  ON it_service_request_assignments FOR INSERT TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete it_service_request_assignments"
  ON it_service_request_assignments FOR DELETE TO authenticated
  USING (true);

-- Activity Logs
CREATE POLICY "Authenticated users can read it_service_request_activity_logs"
  ON it_service_request_activity_logs FOR SELECT TO authenticated USING (true);

CREATE POLICY "Authenticated users can insert it_service_request_activity_logs"
  ON it_service_request_activity_logs FOR INSERT TO authenticated
  WITH CHECK (true);

-- Actions
CREATE POLICY "Authenticated users can read it_service_request_actions"
  ON it_service_request_actions FOR SELECT TO authenticated USING (true);

CREATE POLICY "Authenticated users can insert it_service_request_actions"
  ON it_service_request_actions FOR INSERT TO authenticated
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Authenticated users can update it_service_request_actions"
  ON it_service_request_actions FOR UPDATE TO authenticated
  USING (auth.uid() = user_id);

-- Evidence
CREATE POLICY "Authenticated users can read it_service_request_evidence"
  ON it_service_request_evidence FOR SELECT TO authenticated USING (true);

CREATE POLICY "Authenticated users can insert it_service_request_evidence"
  ON it_service_request_evidence FOR INSERT TO authenticated
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Authenticated users can delete it_service_request_evidence"
  ON it_service_request_evidence FOR DELETE TO authenticated
  USING (auth.uid() = user_id);

-- 10. Add it_service_request_id to notifications table
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS it_service_request_id uuid REFERENCES it_service_requests(id) ON DELETE CASCADE;

-- 11. Storage bucket for IT service request files
INSERT INTO storage.buckets (id, name, public, file_size_limit)
VALUES ('it_service_attachments', 'it_service_attachments', true, 26214400)
ON CONFLICT (id) DO NOTHING;

-- Storage policies
CREATE POLICY "Authenticated users can upload it_service_attachments"
  ON storage.objects FOR INSERT TO authenticated
  WITH CHECK (bucket_id = 'it_service_attachments');

CREATE POLICY "Authenticated users can read it_service_attachments"
  ON storage.objects FOR SELECT TO authenticated
  USING (bucket_id = 'it_service_attachments');

CREATE POLICY "Authenticated users can delete it_service_attachments"
  ON storage.objects FOR DELETE TO authenticated
  USING (bucket_id = 'it_service_attachments');

-- 12. Realtime publication
ALTER PUBLICATION supabase_realtime ADD TABLE it_service_requests;
ALTER PUBLICATION supabase_realtime ADD TABLE it_service_request_assignments;
ALTER PUBLICATION supabase_realtime ADD TABLE it_service_request_activity_logs;
ALTER PUBLICATION supabase_realtime ADD TABLE it_service_request_actions;
